为什么要进行驱动开发?

有的平台没有所谓“wiringPi”库,为了驱动引脚需要编写自己的“wiringPi”库

如何找到驱动?

1:文件名

2:设备号: Linux的设备管理是和文件系统紧密结合的,各种设备都以文件的形式存放在/dev目录下,称为设备文件。使用open系列打开。为了管理这些设备,系统为设备编了号

①主设备号:区分不同种类的设备

②次设备号:区分同一类型的多个设备

查看设备号:ls -l 红圈是 主 黄圈是 次

驱动调用或添加步骤参考:

 用户进行open时linux进行系统调用的过程:

 自己总结:用户调用open,open调用sys_call(系统调用),sys_call调用sys_open去打开驱动

open -> sys_call -> sys_open -> 驱动

参考别人的驱动:

#include //file_operations声明

#include //module_init module_exit声明

#include //__init __exit 宏定义声明

#include //class devise声明

#include //copy_from_user 的头文件

#include //设备号 dev_t 类型声明

#include //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"; //模块名

//led_open函数

static int pin4_open(struct inode *inode,struct file *file)

{

printk("pin4_open\n"); //内核的打印函数和printf类似

return 0;

}

//led_write函数

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,

};

int __init pin4_drv_init(void) //真实驱动入口

{

int ret;

devno = MKDEV(major, minor); //创建设备号

ret = register_chrdev(major, module_name, &pin4_fops); //注册驱动 告诉内核,把这个驱动加入到内核驱动的链表中

pin4_class=class_create(THIS_MODULE, "myfirstdemo"); //用代码在dev自动生成设备

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); //入口,内核加载该驱动(insmod)的时候,这个宏被使用

module_exit(pin4_drv_exit);

MODULE_LICENSE("GPL v2");

编译阶段:

1.进入linux-rpi-4.14.y/drivers/char,编辑好文件pin_4.c

2.修改一下Makefile:vi Makefile

 3.回到linux-rpi-4.14.y 编译代码:

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make modules

4.生成的驱动pin_4发给树莓派:

 

scp /home/lzy/SYSTEM/linux-rpi-4.14.y/drivers/char/pin_4.ko pi@192.168.0.21:/home/pi

5.驱动传到树莓派后,需要加载驱动

加载驱动:sudo insmod hello_drv.ko

驱动卸载:sudo rmmod hello_drv 不需要写ko

查看驱动模块:lsmod

在/dev底下就能看到:

 6.写一个测试程序,编译并运行测试程序

#include

#include

#include

#include

#include

int main()

{

int fd;

fd=open("/dev/my_pin4",O_RDWR);

if(fd==-1){

printf("open failed\n");

}else{

printf("open success\n");

}

write(fd,"1",1);

return 0;

}

运行测试程序,一定要加超级用户权限sudo

 在用户态是看不到内核态的东西的使用:dmesg查看:

 总结:

调用流程:我们上层空间的①open去查找dev下的驱动(文件名),文件名背后包含了驱动的主设备号和次设备号,此时用户open触发一个②系统调用(sys_call),系统调用经过③vfs(虚拟文件系统),vfs根据文件名背后的设备号去调用④sys_open去判断,找到内核中驱动链表的驱动位置,再去调用驱动里面自己的⑤dev_open函数

验证步骤: ①装载驱动 ②查看驱动装载后是否生成设备 ③运行测试程序调试驱动 ④内核的printk打印在内核层,通过dmesg查看内核打印信息  

原文链接:

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。