您的位置:首页 > 运维架构 > Linux

Linux学习(3)应用程序与驱动程序是如何连接的?

2017-03-21 23:10 260 查看
首先看一张韦东山老师给出的系统图:



在驱动开发过程中,首先是编写驱动代码。对于字符设备驱动的框架,可以归纳如下:

1,写出具体驱动函数,如 led_open(),led_read(),led_write()等



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

{
//printk("first_drv_open\n");
/* 配置GPF4,5,6为输出 */
*gpfcon &= ~((0x3<<(4*2)) | (0x3<<(5*2)) | (0x3<<(6*2)));
*gpfcon |= ((0x1<<(4*2)) | (0x1<<(5*2)) | (0x1<<(6*2)));
return 0;

}

2、定义一个file_operation()函数,它指向具体的驱动函数,为下一步注册到内核提供参数。

 如:static struct file_operationsfirst_drv_fops = {

               .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

              .open     =   first_drv_open,     
        .write   =first_drv_write,
  

};

3、编写入口函数,在入口函数中利用 register_chrdev()将驱动注册到内核。

 static int first_drv_init(void)

{
major = register_chrdev(0, "first_drv", &first_drv_fops); // 注册, 告诉内核

firstdrv_class = class_create(THIS_MODULE, "firstdrv");

firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */

gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
gpfdat = gpfcon + 1;

return 0;

}

4
4000
、编写 module_init(first_drv_init); 在加载内核是调用该函数。相应的有出口函数和卸载模块的函数。

static void first_drv_exit(void)

{
unregister_chrdev(major, "first_drv"); // 卸载

class_device_unregister(firstdrv_class_dev);
class_destroy(firstdrv_class);
iounmap(gpfcon);

}

module_exit(first_drv_exit);

5、其他信息 主要是

MODULE_LICENSE("GPL");

驱动程序完成,现在分析应用程序是如何调用的

在 APP中 有open("/dev/XXX")其中dev为设备属性 字符设备为C,XXX为设备号,我们在编写驱动程序时,在编写register()函数时,有个参数为设备号major = register_chrdev(0,
"first_drv", &first_drv_fops); ,该设备号就是为了APP认识它为做准备的。驱动在注册到内核之后,在内核中会生成一个数组,数组里面为各个设备号以及其对应的驱动操作的调用函数。通过这个 数组,就将APP层与驱动层联系起来了。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: