AcWing
  • 首页
  • 活动
  • 题库
  • 竞赛
  • 校园
  • 应用
  • 文章
    • 题解
    • 分享
    • 问答
  • 吐槽
  • 登录/注册

Linux 驱动开发基础---驱动设计思想---分离

作者: 作者的头像   也许 ,  2022-05-14 16:23:29 ,  所有人可见 ,  阅读 16


0


驱动程序分离的思想

想想前面的LED驱动程序还有什么缺点?

    我们已经解决了驱动程序与硬件绑定太死的问题,提升了驱动程序的通用性。

    但是想想硬件操作是不是可以改进?

        同一块开发板LED有不同的引脚,如果换一个引脚,broad.c中硬件操作的函数全部要修改。如果有100个引脚,

        要写100份braod.c?

    事实上,每一款芯片它的GPIO操作都是类似的

        GPIO1_3:

            有方向寄存器DIR、数据寄存器DR等,基础地址是addr_base_addr_gpio1。

            设置为output引脚:修改GPIO1的DIR寄存器的bit3。

            设置输出电平:修改GPIO1的DR寄存器的bit3。

        GPIO5_4 

            有方向寄存器DIR、数据寄存器DR等,基础地址是addr_base_addr_gpio5。

            设置为output引脚:修改GPIO5的DIR寄存器的bit4。

            设置输出电平:修改GPIO5的DR寄存器的bit4。

    既然引脚操作那么有规律,并且这是跟主芯片相关的,那可以针对该芯片写出比较通用的硬件操作代码。

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

    使用时,我们只需要在board_A_led.c中指定使用哪一个引脚即可。

程序结构

分离.png

LED驱动程序改进

led_drv.c led_drv_test.c 不变

broad.c 进一步细分

    board_A_led.c ====》指定硬件资源如,LED引脚

    chipY_gpio.c =====》芯片Y的GPIO通用操作,它首先获取硬件资源,然后根据资源,执行相应操作

led_resource.h

#ifndef _LED_RESOURCE_H
#define _LED_RESOURCE_H

/* 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);

#endif

broad_A_led.c

#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;
}


chipY_gpio.c

#include <linux/module.h>

#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include "led_opr.h"
#include "led_resource.h"

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 评论

你确定删除吗?
1024
x

© 2018-2022 AcWing 版权所有  |  京ICP备17053197号-1
用户协议  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息