日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

驱动设计的思想:面向对象/分层/分离

發(fā)布時(shí)間:2025/4/5 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 驱动设计的思想:面向对象/分层/分离 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1 面向?qū)ο?/li>
    • 2 分層
    • 3 分離

1 面向?qū)ο?/h2>

字符設(shè)備驅(qū)動(dòng)程序抽象出一個(gè) file_operations 結(jié)構(gòu)體;

我們寫的程序針對硬件部分抽象出led_operations 結(jié)構(gòu)體。


2 分層

上下分層,比如我們前面寫的 LED 驅(qū)動(dòng)程序就分為 2 層:
① 上層實(shí)現(xiàn)硬件無關(guān)的操作,比如注冊字符設(shè)備驅(qū)動(dòng):leddrv.c。
② 下層實(shí)現(xiàn)硬件相關(guān)的操作,比如 board_A.c 實(shí)現(xiàn)單板 A 的 LED 操作。


3 分離

還能不能改進(jìn)?分離。
在 board_A.c 中,實(shí)現(xiàn)了一個(gè)led_operations,為 LED 引腳實(shí)現(xiàn)了初始化函數(shù)、控制函數(shù):

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

如果硬件上更換一個(gè)引腳來控制 LED 怎么辦?你要去修改上面結(jié)構(gòu)體中的 init、ctl 函數(shù)。
實(shí)際情況是,每一款芯片它的 GPIO 操作都是類似的。比如:GPIO1_3、GPIO5_4 這 2 個(gè)引腳接到 LED:

① GPIO1_3 屬于第 1 組,即 GPIO1。
有方向寄存器 DIR、數(shù)據(jù)寄存器 DR 等,基礎(chǔ)地址是 addr_base_addr_gpio1。
設(shè)置為 output 引腳:修改 GPIO1 的 DIR 寄存器的 bit3。
設(shè)置輸出電平:修改 GPIO1 的 DR 寄存器的 bit3。

② GPIO5_4 屬于第 5 組,即 GPIO5。
有方向寄存器 DIR、數(shù)據(jù)寄存器 DR 等,基礎(chǔ)地址是 addr_base_addr_gpio5。
設(shè)置為 output 引腳:修改 GPIO5 的 DIR 寄存器的 bit4。
設(shè)置輸出電平:修改 GPIO5 的 DR 寄存器的 bit4。

既然引腳操作那么有規(guī)律,并且這是跟主芯片相關(guān)的,那可以針對該芯片寫出比較通用的硬件操作代碼。

比如 board_A.c 使用芯片 chipY,那就可以寫出:chipY_gpio.c,它實(shí)現(xiàn)芯片 Y 的 GPIO 操作,適用于
芯片 Y 的所有 GPIO 引腳。
使用時(shí),我們只需要在 board_A_led.c 中指定使用哪一個(gè)引腳即可。

程序結(jié)構(gòu)如下:

以面向?qū)ο蟮乃枷?#xff0c;在 board_A_led.c 中實(shí)現(xiàn) led_resouce 結(jié)構(gòu)體,它定義“資源”──要用哪一個(gè)引腳。

在 chipY_gpio.c 中仍是實(shí)現(xiàn) led_operations 結(jié)構(gòu)體,它要寫得更完善,支持所有 GPIO。

代碼實(shí)現(xiàn):
程序仍分為上下結(jié)構(gòu):上層 leddrv.c 向內(nèi)核注冊 file_operations 結(jié)構(gòu)體;下層 chip_demo_gpio.c 提
供 led_operations 結(jié)構(gòu)體來操作硬件。

下層的代碼分為 2 個(gè):chip_demo_gpio.c 實(shí)現(xiàn)通用的 GPIO 操作,board_A_led.c 指定使用哪個(gè) GPIO,
即“資源”。

led_resource.h 中定義了 led_resource 結(jié)構(gòu)體,用來描述 GPIO:

#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

board_A_led.c 指定使用哪個(gè) GPIO,它實(shí)現(xiàn)一個(gè) led_resource 結(jié)構(gòu)體,并提供訪問函數(shù):

#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 實(shí)現(xiàn)的 led_resource 結(jié)構(gòu)體,然后再進(jìn)行其他操作:

#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-哪個(gè)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-哪個(gè)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; } 《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的驱动设计的思想:面向对象/分层/分离的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。