基于定時器、RTC、WDT本質上均是計數器的共性,本次將這三種通用外設統一為TIM。以TIM為例,來展示如何開發通用驅動外設代碼。對于AMetal所提供的標準層驅動文件,均存放于ametal\interface路徑下。
如下圖所示,開發通用外設驅動主要包含以下步驟:了解通用外設標準接口層、外設硬件層開發、外設驅動層開發、外設用戶配置文件開發、外設例程文件開發。
了解通用外設標準層
1、通用外設標準接口相關類型定義
以WDT為例,如下所示為WDT的標準接口文件中對每個結構體和handle的詳細介紹。
以此類推,對于定時器和RTC,其標準接口文件中均定義了驅動函數結構體、標準服務結構體和外設標準服務操作句柄。
struct am_xxx_drv_funcs結構體
該驅動函數結構體表明了驅動層應該提供對應的函數;
typedef struct am_xxx_serv結構體
該標準服務結構體定義了標準的通用外設服務,從而包含了需要驅動層為標準接口層提供的全部內容。驅動層就只需定義這樣一個結構體變量,然后賦好相應的值,再以某種方式提供給標準接口層即可。
am_xxx_handle_t的定義
這是一個標準的操作句柄,本質上就是標準服務結構體指針類型,驅動層的初始化函數需要返回該類型的handle給用戶。當用戶在使用標準接口層函數時,就可以將獲取到的handle傳遞給標準層。那么,標準接口層就可以通過該handle訪問到驅動層提供的函數了。
2、標準接口函數
以WDT為例,如下所示為WDT標準接口函數,通過內聯函數來實現。這些函數就只是簡單地調用驅動層提供的函數,本身并沒有做什么事情。每個函數都有對應詳細的注釋,傳入參數和返回值。從中可以看到,在調用驅動層提供的函數時,就是將外設標準服務操作句柄(本質上為標準服務結構體)中的p_drv成員作為第一個參數傳遞。
外設HW層開發
HW 層對應到具體的外設,其提供的API基本上是直接操作寄存器的內聯函數,效率最高,內聯函數直接定義在.h 文件中。根據芯片手冊,來添加外設的寄存器列表;并編寫寄存器相關操作的內聯函數。以某款芯片的WDT為例,如下所示為WDT的寄存器列表,從而來明確各個寄存器的功能。
根據寄存器列表,了解了各個寄存器需要配置的各項功能和其他寄存器位該如何配合等。如下所示為WDT寄存器結構體定義。
接下來需要編寫每個寄存器的功能操作函數即可完成外設硬件層的開發。以WDT的控制寄存器cr為例,來編寫該寄存器的硬件層函數接口,如下所示:
對于定時器、RTC的硬件層驅動開發亦是通過芯片手冊來編寫寄存器操作函數來完成驅動。
外設驅動層開發
1、定義設備信息結構體和設備結構體
在AMetal中,每個設備都應該有與之對應的設備結構體和設備信息結構體。設備結構體主要用于內存分配,與設備相關的變量都應該定義在設備結構體中。設備信息結構體主要包含該設備的一些相關信息。
2、驅動函數實現
驅動函數主要包括兩部分:提供給標準層的驅動函數和初始化、解初始化函數。
以WDT為例,如下所示為WDT外設的驅動層應該給標準接口層提供的函數,按照芯片手冊中對應操作說明來完成看門狗的驅動層函數。
如下所示為WDT初始化函數和解初始化函數;初始化函數主要是為了初始化設備中的標準服務和硬件相關設置;解初始化函數是為了釋放內存資源和硬件資源。
對于定時器和RTC的驅動層開發,其大致流程亦是如此。
外設用戶配置文件開發
開發完驅動層我們知道,用戶使用一個外設的過程是,先調用驅動初始化函數,該函數返回一個handle,后續的所有操作,用戶直接使用該handle作為參數調用標準接口層函數即可。
以某款芯片的 WDT為例,如下所示為WDT的用戶配置文件,主要包含設備信息結構體、設備實例結構體及其平臺初始化函數與解初始化函數。定義好變量和函數后,在頭文件中添加函數聲明。用戶在使用時,只需調用外設實例初始化函數,并保存其返回的handle,后續直接使用該handle作為標準接口的第一個參數來調用標準接口函數即可。
對于定時器和RTC的用戶配置文件,配置其對應的設備信息,添加平臺初始化函數與解初始化函數即可。
外設例程文件開發
外設的例程文件主要分為HW層示例和STD示例。
對于STD示例,調用標準層函數和實例初始化函數返回的handle作為參數傳入,來實現外設功能。
對于HW示例,可參考驅動層函數來添加硬件層示例功能函數,最終實現外設功能。
至此,我們完成了一個通用外設驅動的開發。
來源:立功科技
-
Tim
+關注
關注
0文章
83瀏覽量
18173 -
ametal
+關注
關注
2文章
24瀏覽量
11506
發布評論請先 登錄
相關推薦
EEPROM存儲器外設及驅動代碼應用設計

RT-Thread驅動開發指南進階篇-動手驅動先楫未適配的外設LCD

評論