新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > mr-library中的GPIO是怎么封裝的?完整拆解+實戰思路

        mr-library中的GPIO是怎么封裝的?完整拆解+實戰思路

        作者:嵌入式芯視野 時間:2025-07-08 來源:今日頭條 收藏

        MR 框架

        (1)宏定義部分:模式操作封裝

        #define PIN_MODE_SET(_pin, _number, _mode) 
           do {
               MR_BIT_CLR((_pin)->pins[(_number) / 8], (0xf << (((_number) % 8) * 4)));
               MR_BIT_SET((_pin)->pins[(_number) / 8], ((_mode) << (((_number) % 8) * 4)));
           } while (0)#define PIN_MODE_GET(_pin, _number)
           ((int)(((_pin)->pins[(_number) / 8] >> (((_number) % 8) * 4)) & 0xf))

        解讀:

        • 使用 pins[] 來壓縮存儲每個 GPIO 引腳的模式值,每個引腳占用 4bit。

        • 相當于 8 個引腳共用一個 32 位整型單元。

        • SET/GET 宏本質上是位操作技巧,屬于輕量級狀態映射機制,避免使用結構體數組。

        (2)內部封裝接口:pin_set_mode() & pin_get_mode()

        int pin_set_mode(struct mr_pin *pin, int number, struct mr_pin_config config)
        • 校驗引腳編號合法性;

        • 調用底層平臺實現的 configure() 函數進行實際模式配置;

        • 再通過 PIN_MODE_SET 記錄設置狀態。

        該函數不僅設置了底層硬件,還更新了上層狀態緩存,是對 狀態同步封裝 的經典做法。

        int pin_get_mode(struct mr_pin *pin, int number, struct mr_pin_config *config)
        • 只讀取本地緩存的模式狀態;

        • 并未從底層硬件重新讀取,高效但不完全精準,需確保狀態同步一致。

        • (3)設備接口實現部分

          int mr_pin_close(struct mr_dev *dev)
          • 當關閉設備時,自動將所有使用過的引腳設置為 NONE;

          • 避免引腳懸空或占用;

          • 條件編譯宏 MR_USING_PIN_AUTO_DISABLE 控制是否啟用自動 disable 功能;

          • 使用 PIN_MODE_GET 查狀態再決定是否關閉該引腳。

          這是一個安全性加強設計,有助于系統資源釋放。

          ssize_t mr_pin_write(struct mr_dev *dev, const void *buf, size_t count)
        • 與 read 對稱:寫入指定引腳的電平值;

        • 仍基于 dev->position 表示當前操作的引腳編號;

        • 每個字節寫入一個值。

        • int mr_pin_ioctl(struct mr_dev *dev, int cmd, void *args)
        • 是控制命令接口,支持動態配置與查詢模式:

          • MR_IOC_PIN_SET_MODE:設置某個引腳模式;

          • MR_IOC_PIN_GET_MODE:讀取某個引腳當前模式;

        • 本質是平臺中對 GPIO 控制功能的“高級指令接口”;

        • 具備通用擴展能力,未來可以支持如設置上拉、開漏、中斷等新指令。

        • ssize_t mr_pin_isr(struct mr_dev *dev, int event, void *args)
        • 響應中斷事件(如外部中斷 EXTI);

        • 當前僅實現了 MR_ISR_PIN_EXTI_INT,返回中斷引腳號;

        • 可作為平臺中斷通知機制與上層事件處理系統之間的橋梁。

        • (4)注冊接口:mr_pin_register

          int mr_pin_register(struct mr_pin *pin, const char *path, struct mr_drv *drv)
          • 該函數將 pin 注冊到系統設備樹中;

          • 使用的是 mr_dev_register(通用設備注冊函數);

          • 傳入統一的設備操作結構體 ops;

          • 注冊成功后還會調用 _mr_fast_pin_init(),進行引腳快速訪問初始化。

          這是真正把引腳納入設備系統管理的入口函數。

          (5)整體架構總結圖示(邏輯調用流程)

          +---------------------------+|         應用層            |
          |   (調用 pin 讀寫函數)     |
          +------------+-------------+
                      |
                      v
          +---------------------------+|    mr_dev 操作接口        |
          | mr_pin_read/write/ioctl   |
          +------------+-------------+
                      |
                      v
          +---------------------------+|    struct mr_pin_ops      |
          | -> read / write / config  |
          | (平臺相關的底層操作)      |
          +------------+-------------+
                      |
                      v
          +---------------------------+|   硬件寄存器操作(HAL)   |
          +---------------------------+
        • 總結亮點設計

        • 特性

          實現方式說明

          模式管理高效

          pins[] 使用位操作壓縮記錄所有引腳模式,快速讀寫

          安全性設計

          配置合法性檢查、自動 disable、assert 保護

          與設備框架深度整合

          實現設備標準接口 read/write/ioctl/close

          抽象 + 多態

          所有操作通過 mr_pin_ops 實現平臺無關

          支持多引腳統一管理

          通過 dev->position 定位目標引腳,實現統一操作

          可擴展 IOCTL 命令

          SET_MODE/GET_MODE 只是開始,可擴展為完整控制指令集

          開源代碼:
          https://gitee.com/MacRsh/mr-library/tree/master


        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 昭通市| 曲松县| 锡林郭勒盟| 东明县| 田林县| 鹰潭市| 昭平县| 卓资县| 随州市| 和平区| 泰安市| 马龙县| 尚志市| 郑州市| 蚌埠市| 南充市| 桂东县| 鄄城县| 翁牛特旗| 博兴县| 宿松县| 栾川县| 茌平县| 五寨县| 巴楚县| 巩义市| 四平市| 丘北县| 鸡东县| 仲巴县| 温州市| 花莲县| 新宁县| 广河县| 荆州市| 遂溪县| 富民县| 望都县| 奉化市| 孝感市| 华容县|