目录
前言
5. 分离分层
5.1 回顾-设备驱动实现
5.2 分离分层
5.3 设备
5.4 驱动
5.5 系统,模块
5.6 Makefile
参考:
本章节记录实现LED驱动的大概步骤,且编程框架实现分离分层。
分离分层:
上层:系统 相关。如模块注册于注销。
下层:硬件操作。如提供 file_operations 。分离:
设备。提供板卡信息,如使用哪一个引脚。
驱动。引脚的具体操作。
以下以 LED 为例。
步骤:
模块:
入口函数
出口函数
协议
驱动
驱动代码:实现 file_operations
申请设备号
初始化内核设备文件结构体+绑定驱动代码 file_operations
添加内核设备文件结构体到内核+绑定设备号
创建设备类
创建设备节点+绑定设备号
具体实现参考《linux-驱动-3-字符设备驱动》或往下看。
把一个字符设备驱动工程分层分离。(看章前分析)
得出以下目录树:
目录树分析:
dev_drv:字符设备模块目录
xxx_module.c:上层。系统。用于注册、注销模块,及操作驱动与内核的联系部分。
include:系统、设备、驱动共用的自定义头文件。
xxx_resource.h:资源文件。包含了设备资源传给驱动文件的结构体。
device:设备目录。硬件设备内容,提供给驱动文件使用,即是提供资源。
xxx_dev_a.c:板卡a。以规定的格式提供硬件资源。
xxx_dev_a.h:板卡a。头文件。
driver:驱动目录。实现驱动 file_operations 的目录。
xxx_drv.c:驱动。实现驱动内容。
xxx_drv.c:驱动。头文件。
主要内容:
提供设备资源;
提供获取设备资源接口。
现在设备资源格式文件中第一好格式:
设备资源:(led_resource.h)
获取设备资源接口:
实现驱动内容:
file_operations;
使用设备数组模式,实现统一管理,且达到时间复杂度为 O(1) 的性能。
file_operations:
<code>int led_dev_open(struct inode *inode, struct file *filp)</code>:打开设备节点。
<code>int led_dev_release(struct inode *inode, struct file *filp)</code>:关闭设备节点。
<code>ssize_t led_dev_write(struct file *filp, const char __user * buf, size_t count, loff_t *ppos)</code>:写函数。
<code>ssize_t led_dev_read(struct file *filp, char __user * buf, size_t count, loff_t *ppos)</code>:读函数。
设备数组:
<code>static led_dev_t led_dev_elem[LED_DEV_CNT];</code>:led 设备列表。使用 id 作为下标去定位哪一个设备。
设备结构体:
万事俱备,只欠东风。
下层硬件的资源和驱动函数都准备好了,现在只需要实现模块即可。
主要三个点:
<code>static int __init led_chrdev_init(void)</code>:入口函数。(<code>module_init(led_chrdev_init)</code>)
<code>static void __exit led_chrdev_exit(void)</code>:出口函数。(<code>module_exit(led_chrdev_exit)</code>)
<code>MODULE_LICENSE("GPL")</code>:协议。
以上两个函数的内容可以参考字符设备驱动实现步骤来实现。
除了以上三个函数外,还有把驱动内容填入驱动文件中 file_operations 实体。
给出 led_module.c 文件参考:
参考 《一个通用驱动Makefile-V2-支持编译多目录》
以下只给出源码:
《IMX6ULLRM(6ULL用户手册).pdf》
内核文档html
李柱明博客:https://www.cnblogs.com/lizhuming/
本文链接:https://www.cnblogs.com/lizhuming
推荐去看源码:
驱动模块例程