1.Linux一切皆文件(鼠标、键盘、led、屏幕、网卡等这些设备都是以文件的形式存在/dev下面)
2.如何查找驱动(1.通过文件名,2.通过设备号(主设备号和次设备号))
3.驱动链表:管理所有设备的驱动(添加和调用),编写完驱动程序加载到内核,调用驱动程序用户空间去open,驱动插入链表的顺序由设备号检索。
4.驱动代码编写步骤 (1)设备驱动文件
#include <linux/fs.h> //file_operations声明
#include <linux/module.h> //module_init module_exit声明
#include <linux/init.h> //__init __exit 宏定义声明
#include <linux/device.h> //class devise声明
#include <linux/uaccess.h> //copy_from_user 的头文件
#include <linux/types.h> //设备号 dev_t 类型声明
#include <asm/io.h> //ioremap iounmap的头文件
static struct class *pin4_class;
static struct device *pin4_class_dev;
static dev_t devno; //设备号
static int major = 231; //主设备号
static int minor = 0; //次设备号
static char* module_name = "pin4"; //模块名
static int pin4_open(struct inode *inode, struct file *file)
{
printk("pin4_open\n"); //内核的打印函数,和printf相似
return 0;
}
static int pin4_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
printk("pin4_read\n");
return 0;
}
static ssize_t pin4_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
printk("pin4_write\n");
return 0;
}
static struct file_operations pin4_fops = {
.owner = THIS_MODULE,
.open = pin4_open,
.write = pin4_write,
.read = pin4_read,
};
int __init pin4_drv_init(void) //实际驱动入口
{
int ret;
//创建设备号
devno = MKDEV(major, minor);
//注册驱动,告诉内核,把这个驱动加入到内核驱动的链表中
ret = register_chrdev(major, module_name, &pin4_fops);
//让代码在/dev自动生成设备(手动生成设备进入/dev目录下mknod 设备名 设备类型 主设备号 次设备号)
pin4_class = class_create(THIS_MODULE, "myfirstdemo");
//创建设备文件
pin4_class_dev = device_create(pin4_class, NULL, devno, NULL, module_name);
return 0;
}
void __exit pin4_drv_exit(void)
{
device_destroy(pin4_class, devno);//销毁设备
class_destroy(pin4_class);//销毁类
unregister_chrdev(major, module_name); //卸载驱动
//卸载驱动与创建的顺序相反
}
module_init(pin4_drv_init); //入口,内核加载该驱动的时候,这个宏会被调用
module_exit(pin4_drv_exit);
MODULE_LICENSE("GPL v2"); //声明GPL规范
(2)测试代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
int fd;
fd = open("/dev/pin4",O_RDWR);
if(fd<0){
printf("open failed\n");
perror("reson:");
}
else{
printf("open success\n");
}
fd = write(fd,'1',1);
}
5.编译驱动代码并放到树莓派上运行 (1)将写好的驱动代码拷贝到linux源码树目录的/drivers/char目录 (2)修改Makefilevi Makefile 添加一行obj-m += pin4driver2.o(注意驱动代码放在哪里改那里的Makefile)
(3)进行模块编译 (3.1)回到linux源码树目录ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make modules (3.2)编译成功生成pin4driver2.ko (3.3)将生成的pin4driver2.ko拷贝到树梅派上 (3.4)将测试代码用交叉编译工具编译后生成的可执行文件拷贝到树梅派。 (3.5)回到树梅派上加载驱动sudo insmod pin4driver2.ko ,然后在/dev下面生成pin4这个设备驱动ls /dev/pin4 -l 。 (3.6)执行拷贝过来测试代码,然后通过dmesg 查看底层打印 (3.7)如果打印失败可能是权限或者代码有错(先从上层代码检验)lsmod命令查看驱动(列出内核驱动模块),删除该驱动模块sudo rmmod 模块名(pin4driver2) ,如果是没有权限导致的执行sudo chnod 666 /dev/pin4 ,然后在执行dmesg 查看内核打印信息。
|