天天看点

【linux】驱动-5-驱动框架分层分离&实战

目录

前言

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

推荐去看源码:

驱动模块例程