参考:【IMX6ULL驱动开发学习】11.驱动设计之面向对象_分层思想(学习设备树过渡部分)-CSDN博客
韦东山课程:LED模板驱动程序的改造_总线设备驱动模型
我使用的开发板:野火imx6ull pro
欢迎大家一起讨论学习
实现了总线设备驱动模型实现LED驱动并能够控制三个LED灯的亮灭
参照博客和韦老师的代码梳理了思路,图片可去我的gitee仓库中下载,在linux_driver_study/led_drv_template_bus_dev_drv中,链接:我的gitee
驱动分层思想
1、首先是驱动程序(leddrv.c)中的file_operations结构体,该结构体关联了应用层的文件IO函数和驱动层的函数
2、硬件操作分离程序(chip_demo_gpio.c)中的platform_driver结构体,加载完.ko(驱动文件)后,内核会自动去匹配platform_driver和platform_device,如果匹配成功,则platform_driver的probe函数会自动执行,在probe函数中获取platform_device中的硬件资源,完成设备节点的创建【device_create】
PS:创建设备节点需要驱动框架层的设备类对象,所以这里需要在设备框架层中为硬件操作层提供对应函数
3、硬件资源定义程序中的 platform_device 结构体,该结构体中定义了与硬件操作层中platform_driver 对应的 name 成员和硬件引脚资源 resource 等,
4、硬件资源层中硬件资源的定义,硬件资源有个特定的结构体 resource ,可以参照Linux内核中其他文件对其的定义来写。
PS:注意要设置 dev 成员下的 release 属性,如果不加的话卸载驱动时会报警告
执行顺序:
- insmod leddrv.ko,执行相应的入口函数,完成file_operations的注册、类注册
- insmod chip_demo_chip.ko,执行相应的入口函数,完成platform_driver的注册、向上层提供led_operations的结构体变量,其中包含了led的与硬件有关的初始化函数和控制函数
- insmod board_A_led.ko,执行相应的入口函数,完成platform_device的注册,同时内核完成了platform_device和platform_driver的匹配,自动执行platform_driver的probe函数,在probe函数中获取platform_device中的硬件资源,完成设备节点的创建【device_create】
执行完以上三步之后,/dev下会出现led设备
- ./led_drv_test /dev/myled0 on,通过应用层的open和write函数,分别调用硬件操作分离程序中的imx6ull_demo_led_init函数和imx6ull_demo_led_ctl函数来控制灯的亮灭
控制小灯亮灭的应用层函数【通过led_operations的结构体变量调用两个底层init函数和ctl函数】: