1、面向对象
⚫ 字符设备驱动程序抽象出一个 file_operations 结构体;
⚫ 我们写的程序针对硬件部分抽象出 led_operations 结构体。
2、分层
上层实现硬件无关的操作,比如注册字符设备驱动:leddrv.c
下层实现硬件相关的操作,比如 board_A.c 实现单板 A 的 LED 操作
3、分离
在 board_A.c 中,实现了一个 led_operations,为 LED 引脚实现了初始化函数、控制函数:
static struct led_operations board_demo_led_opr = {
.num = 1,
.init = board_demo_led_init,
.ctl = board_demo_led_ctl,
};
使用时,我们只需要在 board_A_led.c 中指定使用哪一个引脚即可。程序结构如下:
4、代码
程序仍分为上下结构:上层 leddrv.c 向内核注册 file_operations 结构体;下层 chip_demo_gpio.c 提供 led_operations 结构体来操作硬件。
下层的代码分为 2 个:chip_demo_gpio.c 实现通用的 GPIO 操作,board_A_led.c 指定使用哪个 GPIO,即“资源”。
led_resource.h 中定义了 led_resource 结构体,用来描述 GPIO:
/* GPIO3_0 */
/* bit[31:16] = group */
/* bit[15:0] = which pin */
#define GROUP(x) (x>>16)
#define PIN(x) (x&0xFFFF)
#define GROUP_PIN(g,p) ((g<<16) | (p))
struct led_resource
{
int pin;
};
struct led_resource *get_led_resouce(void);
board_A_led.c 指定使用哪个 GPIO,它实现一个 led_resource 结构体,并提供访问函数:
#include "led_resource.h"
static struct led_resource board_A_led = {
.pin = GROUP_PIN(3,1),
};
struct led_resource *get_led_resouce(void)
{
return &board_A_led;
}
chip_demo_gpio.c 中,首先获得 board_A_led.c 实现的 led_resource结构体,然后再进行其他操作,请看下面第 7 行:
static struct led_resource *led_rsc;
static int board_demo_led_init (int which) /* 初始化 LED, which-哪个 LED */
{
//printk("%s %s line %d, led %d\n", __FILE__, __FUNCTION__, __LINE__, which);
if (!led_rsc)
{
led_rsc = get_led_resouce();
}
....
}