驱动设计思想


面向对线

驱动设计的思想跟面向对象的思想类似,就是实现分层分离。

  • 字符设备驱动程序抽象出一个 file_operations 结构体;
  • 我们的程序针对硬件部分抽象出 led_operations 结构体。

分层

上下分层,比如我们写的 LED 驱动程序分为两层:

  1. 上层实现硬件无关的操作,比如注册字符设备驱动:leddrv.c
  2. 下层实现硬件相关的操作,比如 board_A.c 实现单板 A 的 LED 操作,board_B.c 实现单板 B 的 LED 操作。
    在这里插入图片描述

分离

在分层的基础上还可以进一步改进?

在 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,
};

如果硬件要更换一个引脚来控制 LED,就要对上面结构体中的 init、ctl 函数进行更改,比较麻烦。

对于同一个主芯片,操作 led 的步骤是一样的,因此我们可以针对该芯片写出比较通用的硬件操作代码。

比如 board_A.c 使用芯片 chipY,那就可以写出 chipY_gpio.c,它实现芯片 Y 的 GPIO 操作,适用于芯片 Y 的所有 GPIO 引脚。

使用时,我们只需要在 board_A_led. c 中指定使用哪个引脚即可。
在这里插入图片描述

程序仍然分为上下结构:上层还是向内核注册 [[4. 驱动入门#^caba23|file_operations]] ;

下层的代码分为两个:chip_demo_gpio. c 实现通用的 GPIO 操作,board_A_led. c 指定使用哪个 GPIO, 即“资源”。

led_resource. h 定义了 led_resource 结构体,用来描述 GPIO:

/* 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_r esouce(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_resource(void)
{
	return &board_A_led;
}

然后在 chip_demo_gpio. c 中,首先获得 board_A_led. c 实现的 led_resource 结构体,然后再进行其他操作:

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();
	}
	
	printk("init gpio: group %d, pin %d\n", GROUP(led_rsc->pin), PIN(led_rsc->pin));
	switch(GROUP(led_rsc->pin))
	{
		case 0:
		{
			printk("init pin of group 0 ...\n");
			break;
		}
		case 1:
		{
			printk("init pin of group 1 ...\n");
			break;
		}
		case 2:
		{
			printk("init pin of group 2 ...\n");
			break;
		}
		case 3:
		{
			printk("init pin of group 3 ...\n");
			break;
		}
	}
	
	return 0;
}

static int board_demo_led_ctl (int which, char status) /* 控制LED, which-哪个                                                     LED, status:1-亮,0-灭 */
{
	//printk("%s %s line %d, led %d, %s\n", __FILE__, __FUNCTION__, __LINE__, which, status ? "on" : "off");
	printk("set led %s: group %d, pin %d\n", status ? "on" : "off", GROUP(led_rsc->pin), PIN(led_rsc->pin));

	switch(GROUP(led_rsc->pin))
	{
		case 0:
		{
			printk("set pin of group 0 ...\n");
			break;
		}
		case 1:
		{
			printk("set pin of group 1 ...\n");
			break;
		}
		case 2:
		{
			printk("set pin of group 2 ...\n");
			break;
		}
		case 3:
		{
			printk("set pin of group 3 ...\n");
			break;
		}
	}

	return 0;
}

static struct led_operations board_demo_led_opr = {
	.init = board_demo_led_init,
	.ctl  = board_demo_led_ctl,
};

struct led_operations *get_board_led_opr(void)
{
	return &board_demo_led_opr;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值