一. 简介
上一篇文章说明了如何在设备树文件中添加蜂鸣器的设备节点。文章地址如下:
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$
可以看出,驱动代码可以正常编译。下一篇对该驱动程序进行测试。在开发板上加载该驱动模块。