天天看點

RT-Thread 核心學習筆記 - 裝置模型rt_device的了解

RT-Thread 核心學習筆記 - 核心對象rt_object

RT-Thread 核心學習筆記 - 核心對象管理

RT-Thread 核心學習筆記 - 核心對象操作API

RT-Thread 核心學習筆記 - 核心對象初始化連結清單組織方式

RT-Thread 核心學習筆記 - 核心對象連結清單結構深入了解

RT-Thread 核心學習筆記 - 裝置模型rt_device的了解

RT-Thread 核心學習筆記 - 了解defunct僵屍線程

前言

  • 最近在看核心源碼,暫時避開費腦力的任務排程、記憶體管理等較複雜的實作方法,發現rt_device裝置架構實作很簡單。
  • rt_device,裝置管理的架構(模型),提供标準的裝置操作接口API,一些外設,可以抽象成裝置,進行統一的管理操作,如LCD、Touch、Sensor等。

rt_device的結構

  • rt_device,是核心對象派生出來的,是以,有些操作,就是在操作核心對象。上幾篇筆記研究核心對象的管理,現在發現,看device.c檔案,很容易能看懂。
RT-Thread 核心學習筆記 - 裝置模型rt_device的了解
RT-Thread 核心學習筆記 - 裝置模型rt_device的了解

rt_device的使用

  • RT-Thread 的PIN、CAN、Serial、I2C、SPI、PM等,都抽象成一種裝置模型。這些裝置模型,派生于rt_device即可。

pin裝置模型:結構如下:

/* pin device and operations for RT-Thread */
struct rt_device_pin
{
    struct rt_device parent; /* 派生于rt_device */
    const struct rt_pin_ops *ops; /* 裝置特有的操作接口,還可以根據需要增加其他成員 */
};
           
  • 是以使用者可以派生自己想要的裝置架構,增加特定裝置的操作接口:ops,特定屬性:結構體成員。
  • 需要把具體的裝置,注冊到核心容器上,這裡調用rt_device的注冊接口。

如:

/* 使用時,需要把裝置名稱、操作接口等,傳入 */
int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data)
{
    _hw_pin.parent.type         = RT_Device_Class_Miscellaneous; /* 裝置類型,為了區分裝置種類 */
    _hw_pin.parent.rx_indicate  = RT_NULL; /* 接收回調,序列槽、CAN一般會有 */
    _hw_pin.parent.tx_complete  = RT_NULL; /* 發送回調,序列槽、CAN一般會有 */

#ifdef RT_USING_DEVICE_OPS
    _hw_pin.parent.ops          = &pin_ops;
#else
    _hw_pin.parent.init         = RT_NULL; /* 以下标準的rt_device裝置操作接口,根據需要實作 */
    _hw_pin.parent.open         = RT_NULL;
    _hw_pin.parent.close        = RT_NULL;
    _hw_pin.parent.read         = _pin_read;
    _hw_pin.parent.write        = _pin_write;
    _hw_pin.parent.control      = _pin_control;
#endif

    _hw_pin.ops                 = ops;  /* 操作接口,裝置的特有操作接口 */
    _hw_pin.parent.user_data    = user_data; /* 不是必要的使用者資料 */

    /* register a character device */
    rt_device_register(&_hw_pin.parent, name, RT_DEVICE_FLAG_RDWR);  /* 裝置注冊接口:注冊為具體裝置 */

    return 0;
}
           
  • 具體裝置對接裝置架構
/* 具體裝置的OPS 實作 */
const static struct rt_pin_ops _stm32_pin_ops =
{
    stm32_pin_mode,
    stm32_pin_write,
    stm32_pin_read,
    stm32_pin_attach_irq,
    stm32_pin_dettach_irq,
    stm32_pin_irq_enable,
};

/* 實際裝置的注冊方法 */
rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL);
           
  • 裝置注冊後,可以通過:list_device檢視

其他

  • rt_device_read rt_device_write等操作前,需要:rt_device_open
  • rt_device_open rt_device_close 操作最好成對出現,原因是rt_device内部有引用計數,如你open兩次,close一次,計數為1,沒有真正的close。
  • 一般通過rt_device_find,通過裝置名稱,查找裝置,擷取裝置的操作句柄,也就是裝置結構體指針,進而可以進一步進行操作裝置的操作接口ops或通過裝置的标準操作接口操作裝置。
  • RT-Thread 的裝置類型很多,可以派生各種裝置模型(架構),進而可以注冊挂載很多裝置上去,可以友善的實作讀寫控制等操作,如控制硬體、傳感器等。

總結

  • 裝置派生于核心對象:rt_object,熟悉核心對象,有利于熟悉rt_device的操作
  • 繼續研究RT-Thread核心,不斷學習,收獲很多。

繼續閱讀