1. LED驱动程序框架
注意:如果做实验安装驱动时提示
version magic
不匹配,请看本文档最后的“常见问题”。
1.1 回顾字符设备驱动程序框架
1.确定主设备号
2.定义自己的file_operations
结构体
3.实现对应的drv_open
/drv_read
/drv_write
等函数,填入file_operations
结构体
4.把file_operations
结构体告诉内核:register_chrdev
5.谁来注册驱动程序啊?得有一个入口函数,安装驱动程序时,就会调用这个入口函数。
6.有入口函数就应该有出口函数,出口函数调用unregister_chrdev
7.其他完善:提供设备信息,自动创建设备结点:class_create
,device_create
1.2 对于LED驱动,我们想要什么样的接口?
1.3 LED驱动要怎么写,才能支持多个板子?分层。
- 把驱动拆分为通用的框架(
leddrv.c
)、具体的硬件操作(board_X.c
):
- 以面向对象的思想,改进代码: 抽象出一个结构体:
每个单板相关的
board_X.c
实现自己的led_operations
结构体,供上层的leddrv.c
调用:
1.4 写代码
使用GIT下载所有源码后,本节源码位于如下目录:
01_all_series_quickstart
05_嵌入式Linux驱动开发基础知识source02_led_drv01_led_drv_template
1.4.1 驱动程序
驱动程序分为上下两层:
leddrv.c
、board_demo.c
。
leddrv.c
负责注册file_operations
结构体,它的open
/write
成员会调用board_demo.c
中提供的硬件led_opr
中的对应函数。
1.4.1.1 把LED的操作抽象出一个led_operations结构体
首先看看
led_opr.h
,它定义了一个led_operations
结构体,把LED的操作抽象为这个结构体:
01 #ifndef _LED_OPR_H
02 #define _LED_OPR_H
03
04 struct led_operations {
05 int (*init) (int which); /* 初始化LED, which-哪个LED */
06 int (*ctl) (int which, char status); /* 控制LED, which-哪个LED, status:1-亮,0-灭 */
07 };
08
09 struct led_operations *get_board_led_opr(void);
10
11
12 #endif
13
看到上面定义的头文件,可以立马把对应的
board_demo.c
的框架给写出来,内部的具体功能根据情况再自己定义,头文件部分依旧是两个原则,一个是根据linux
内核代码中别人类似的驱动程序去编写头文件,还有一种