beep蜂鸣器驱动实验-蜂鸣器驱动框架代码实现

一.  简介

上一篇文章说明了如何在设备树文件中添加蜂鸣器的设备节点。文章地址如下:

beep蜂鸣器驱动实验-开发板上测试设备树文件-CSDN博客

这里学习编写蜂鸣器的驱动框架代码,驱动框架代码其实与 Led灯驱动框架是一样的。

二.  蜂鸣器驱动框架代码实现

1.   创建 vscode工程

打开 ubuntu系统,进入 如下目录下:

/home/wangtian/zhengdian_Linux/Linux_Drivers

在 上面目录下创建 工程目录 7_beep:

wangtian@wangtian-virtual-machine:~/zhengdian_Linux/Linux_Drivers$ mkdir 7_beep

(1)  拷贝 .vscode

将前面实验 6_gpioled 工程中 .vscode目录及其下文件拷贝到该工程下:

wangtian@wangtian-virtual-machine:~/zhengdian_Linux/Linux_Drivers/7_beep$ sudo cp ../6_gpioled/.vscode/ ./ -rf
[sudo] wangtian 的密码: 
wangtian@wangtian-virtual-machine:~/zhengdian_Linux/Linux_Drivers/7_beep$ 

注意: 拷贝.vscode 目录及其下文件的原因在于,.vscode目录下的文件中设置了 驱动程序可能会调用到的 Linux内核源码的路径(NXP官方)。

(2)  拷贝 Makefile文件

将前面实验 6_gpioled 工程中 Makefile拷贝到该工程下,操作如下:

wangtian@wangtian-virtual-machine:~/zhengdian_Linux/Linux_Drivers/7_beep$ cp ../6_gpioled/Makefile ./

更改 Makefile文件的目标文件名,更改为如下:

obj-m := beep.o

创建 beep.c文件:

wangtian@wangtian-virtual-machine:~/zhengdian_Linux/Linux_Drivers/7_beep$ touch beep.c

2.  蜂鸣器驱动代码框架

将 6_gpioled 工程中 gpioled.c文件中头文件拷贝到 beep.c文件中:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>

下来编写 蜂鸣器的驱动框架代码。beep.c文件代码如下:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>

#define  BEEP_NAME   "beep"
#define  BEEP_CNT     1

//beep设备结构体
struct beep_gpio{
    dev_t  devid;
    int major;
    int minor;
    struct cdev cdev;
    struct class* class;
    struct device* device;

};

struct beep_gpio beep_dev;

static const struct file_operations beep_fops = {
    .owner = THIS_MODULE,
	// .open = gpioled_open,
    // .write = gpioled_write,
    // .release = gpioled_close,
};

/*驱动模块入口函数 */
static int __init beep_init(void)
{
    int ret = 0;
    beep_dev.major = 0;
    /*1. 申请设备号 */
    if (beep_dev.major) {
		beep_dev.devid = MKDEV(beep_dev.major, 0);
		ret = register_chrdev_region(beep_dev.devid , BEEP_CNT, BEEP_NAME);
	} else {
		ret = alloc_chrdev_region(&beep_dev.devid, 0, BEEP_CNT, BEEP_NAME);
		beep_dev.major = MAJOR(beep_dev.devid);
        beep_dev.minor = MINOR(beep_dev.devid);
	}
    printk("dev.major: %d  dev.minor: %d\n",beep_dev.major, beep_dev.minor);
    if(ret < 0)
    {
        printk("devid apply failed!\n");
        goto apply_devid_failed;
    }

    /*2. 设备初始化 */
    beep_dev.cdev.owner = THIS_MODULE;
    cdev_init(&beep_dev.cdev, &beep_fops);
	ret = cdev_add(&beep_dev.cdev, beep_dev.devid, BEEP_CNT);
	if (ret < 0) {
		goto dev_init_failed;
	}
    /*3. 自动创建设备节点*/
    beep_dev.class = class_create(THIS_MODULE, BEEP_NAME);
 	if (IS_ERR(beep_dev.class)) {
        ret = -EINVAL;
		goto class_create_failed;
	}   
    beep_dev.device = device_create(beep_dev.class, NULL, beep_dev.devid, NULL, BEEP_NAME);
	if (IS_ERR(beep_dev.device)) {
        ret = -EINVAL;
		goto device_create_failed;
	}		     
    return 0;

device_create_failed:
    class_destroy(beep_dev.class);
class_create_failed:
    cdev_del(&beep_dev.cdev);
dev_init_failed:
    unregister_chrdev_region(beep_dev.devid, BEEP_CNT);
apply_devid_failed:
    return ret;
}

/*驱动模块出口函数 */
static void __exit beep_exit(void)
{
    /*删除设备*/
    cdev_del(&beep_dev.cdev);
    /*注销设备号*/
    unregister_chrdev_region(beep_dev.devid, BEEP_CNT);
    /*销毁设备*/
    device_destroy(beep_dev.class, beep_dev.devid);
    /*销毁类*/
    class_destroy(beep_dev.class);
}

/*驱动模块入口与出口函数*/
module_init(beep_init);
module_exit(beep_exit); 
MODULE_LICENSE("GPL"); //driver's License
MODULE_AUTHOR("WeiWuXian"); //author

三.   编译驱动

编译蜂鸣器驱动框架代码。ubuntu终端进入 7_beep工程目录下,输入" make" 命令编译驱动代码:

wangtian@wangtian-virtual-machine:~/zhengdian_Linux/Linux_Drivers/7_beep$ make
make -C /home/wangtian/zhengdian_Linux/linux/kernel/linux-imx-rel_imx_4.1.15_2.1.0_ga M=/home/wangtian/zhengdian_Linux/Linux_Drivers/7_beep modules
make[1]: 进入目录“/home/wangtian/zhengdian_Linux/linux/kernel/linux-imx-rel_imx_4.1.15_2.1.0_ga”
  CC [M]  /home/wangtian/zhengdian_Linux/Linux_Drivers/7_beep/beep.o
  Building modules, stage 2.
  MODPOST 1 modules
  LD [M]  /home/wangtian/zhengdian_Linux/Linux_Drivers/7_beep/beep.ko
make[1]: 离开目录“/home/wangtian/zhengdian_Linux/linux/kernel/linux-imx-rel_imx_4.1.15_2.1.0_ga”
wangtian@wangtian-virtual-machine:~/zhengdian_Linux/Linux_Drivers/7_beep$ 

可以看出,驱动代码可以正常编译。下一篇对该驱动程序进行测试。在开发板上加载该驱动模块。

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include "stm32f10x.h" #include "GPIOLIKE51.h" #define uint unsigned int #define uchar unsigned char #define CLOCK 72/8 //时钟=72M //函数声明 void GPIO_Configuration(void); /**************************************************************************** * 名 称:delay_us(u32 nus) * 功 能:微秒延时函数 * 入口参数:u32 us * 出口参数:无 * 说 明: * 调用方法:无 ****************************************************************************/ //void delay_us(u32 us) //{ // u32 temp; // SysTick->LOAD = 9*us; // SysTick->VAL=0X00;//清空计数器 // SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 // do // { // temp=SysTick->CTRL;//读取当前倒计数值 // }while((temp&0x01;)&&(!(temp&(1<CTRL=0x00; //关闭计数器 // SysTick->VAL =0X00; //清空计数器 //} /**************************************************************************** * 名 称:delay_ms(u16 ms) * 功 能:毫秒延时函数 * 入口参数:u16 nms * 出口参数:无 * 说 明: * 调用方法:无 ****************************************************************************/ void delay_ms(u16 ms) { u32 temp; SysTick->LOAD = 9000*ms; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do { temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01;)&&(!(temp&(1<CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } //============================================================================= //文件名称:main //功能概要:主函数 //参数说明:无 //函数返回:int //============================================================================= int main(void) { GPIO_Configuration(); while (1) { // GPIO_SetBits(GPIOB,GPIO_Pin_9); // delay_ms(500);// 100=0.1S GPIO_ResetBits(GPIOB,GPIO_Pin_9); delay_ms(500); } } //============================================================================= //文件名称:GPIO_Configuration //功能概要:GPIO初始化 //参数说明:无 //函数返回:无 //============================================================================= void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE&#4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值