快速發(fā)展的技術(shù)需要軟件支持(固件驅(qū)動(dòng)程序和示例代碼)來簡化過程中的設(shè)計(jì)。本文介紹如何使用no-OS(無操作系統(tǒng))驅(qū)動(dòng)程序和平臺(tái)驅(qū)動(dòng)程序,通過ADI公司的精密模數(shù)轉(zhuǎn)換器和數(shù)模轉(zhuǎn)換器構(gòu)建應(yīng)用固件,這些轉(zhuǎn)換器在速度、功耗、尺寸和分辨率方面具有高水平的性能。
ADI提供基于no-OS驅(qū)動(dòng)程序的嵌入式固件示例,以支持精密轉(zhuǎn)換器。No-OS驅(qū)動(dòng)程序負(fù)責(zé)設(shè)備配置、從轉(zhuǎn)換器捕獲數(shù)據(jù)、執(zhí)行校準(zhǔn)等,而基于no-OS驅(qū)動(dòng)程序的固件示例有助于將數(shù)據(jù)傳輸?shù)街鳈C(jī)PC進(jìn)行顯示、存儲(chǔ)和進(jìn)一步處理。
無操作系統(tǒng)和平臺(tái)驅(qū)動(dòng)程序簡介
顧名思義,no-OS 驅(qū)動(dòng)程序旨在與通用(或無特定)操作系統(tǒng)一起使用。該名稱還意味著這些驅(qū)動(dòng)程序可以在沒有任何操作系統(tǒng)支持的情況下在裸機(jī)系統(tǒng)上使用。No-OS驅(qū)動(dòng)程序旨在為給定精密轉(zhuǎn)換器的數(shù)字接口訪問提供高級(jí)API。使用這些 API 的 No-OS 驅(qū)動(dòng)程序與設(shè)備接口,以訪問、配置、讀取和寫入數(shù)據(jù),而無需了解寄存器地址(內(nèi)存映射)及其內(nèi)容。
No-OS驅(qū)動(dòng)程序利用平臺(tái)驅(qū)動(dòng)程序?qū)?,允許在多個(gè)硬件/軟件平臺(tái)上重復(fù)使用相同的no-OS驅(qū)動(dòng)程序,從而使您的固件具有高度可移植性。使用平臺(tái)驅(qū)動(dòng)程序?qū)邮篃o操作系統(tǒng)驅(qū)動(dòng)程序無法了解平臺(tái)特定接口(如 SPI、I 等)的低級(jí)細(xì)節(jié)2C、GPIO 等,這使得無操作系統(tǒng)驅(qū)動(dòng)程序可以在多個(gè)平臺(tái)上重用,而無需更改它們。
圖1.精密轉(zhuǎn)換器固件堆棧。
使用無操作系統(tǒng)驅(qū)動(dòng)程序
圖 2 顯示了無操作系統(tǒng)驅(qū)動(dòng)程序的典型代碼結(jié)構(gòu)。
圖2.無操作系統(tǒng)驅(qū)動(dòng)程序代碼結(jié)構(gòu)。
圖3.設(shè)備配置枚舉、結(jié)構(gòu)和 API。
精密轉(zhuǎn)換器的無操作系統(tǒng)驅(qū)動(dòng)程序代碼通常合并在兩個(gè)用C編程語言編寫的源文件中:adxxxx.c和adxxxx.h,其中xxxx代表器件名稱(例如,AD7606、AD7124等)。器件頭文件 (adxxxx.h) 包含器件特定結(jié)構(gòu)、枚舉、寄存器地址和位掩碼的公共編程接口,通過將該文件包含在所需的源文件中,可供公眾訪問。器件源文件 (adxxxx.c) 包含用于初始化和移除器件、讀/寫器件寄存器、從器件讀取數(shù)據(jù)、獲取/設(shè)置器件特定參數(shù)等的接口實(shí)現(xiàn)。
典型的無操作系統(tǒng)驅(qū)動(dòng)程序圍繞一組通用功能構(gòu)建:
聲明器件特定的寄存器地址、位掩碼宏、器件配置枚舉以及用于讀/寫器件特定參數(shù)(例如,過采樣、增益、基準(zhǔn)等)的結(jié)構(gòu)。
通過no-OS驅(qū)動(dòng)程序的設(shè)備初始化/取消初始化物理設(shè)備初始化/刪除函數(shù)以及設(shè)備特定的初始化和驅(qū)動(dòng)程序結(jié)構(gòu)和描述符。
使用設(shè)備寄存器讀/寫功能訪問設(shè)備存儲(chǔ)器映射或寄存器詳細(xì)信息;例如,adxxxx_read_register() 或 adxxxx_write_register()。
無操作系統(tǒng)驅(qū)動(dòng)程序代碼使用
使用設(shè)備特定的地址、位掩碼以及參數(shù)配置枚舉和結(jié)構(gòu):
如前所述,adxxxx.h 頭文件包含所有特定于器件的枚舉和結(jié)構(gòu)的聲明,這些枚舉和結(jié)構(gòu)將傳遞給特定于器件的函數(shù)或 API 以配置或訪問器件參數(shù)。如圖 3 所示。
圖3所示的adxxxx_config結(jié)構(gòu)允許用戶選擇多路復(fù)用器通道并為其設(shè)置過采樣速率。此結(jié)構(gòu)的兩個(gè)成員(afe_mux_channel和過采樣)都是存在于同一頭文件中的枚舉,該文件包含用戶可以選擇的兩個(gè)字段的所有可能值的數(shù)字常量。
adxxxx.c 文件中定義的 adxxxx_set_adc_config() 函數(shù)通過配置結(jié)構(gòu)獲取用戶傳遞的配置/參數(shù),并進(jìn)一步調(diào)用 adxxxx_spi_reg_write() 函數(shù),通過數(shù)字接口將數(shù)據(jù)寫入ADXXXX_REG_CONFIG器件寄存器(在前一種情況下為 SPI)。
使用no-OS驅(qū)動(dòng)程序設(shè)備結(jié)構(gòu)和初始化功能初始化設(shè)備:
圖4.設(shè)備初始化和驅(qū)動(dòng)程序結(jié)構(gòu)的聲明。
除了設(shè)備配置枚舉和結(jié)構(gòu)外,no-OS 驅(qū)動(dòng)程序還提供兩個(gè)附加結(jié)構(gòu):
設(shè)備初始化結(jié)構(gòu)。
設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)。
設(shè)備 init 結(jié)構(gòu)允許用戶在用戶應(yīng)用程序代碼中定義特定于設(shè)備的參數(shù)和配置。init 結(jié)構(gòu)包含其他特定于設(shè)備的參數(shù)結(jié)構(gòu)和枚舉的成員。圖 5 顯示了如何定義設(shè)備 init 結(jié)構(gòu)。
圖5.用戶應(yīng)用程序中的設(shè)備初始化結(jié)構(gòu)定義。
設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)通過設(shè)備 init 函數(shù) adxxxx_init() 加載設(shè)備初始化參數(shù)。設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)在運(yùn)行時(shí)(動(dòng)態(tài))內(nèi)存中從堆空間分配。在設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)和設(shè)備 init 結(jié)構(gòu)中聲明的參數(shù)幾乎彼此相同。設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)是設(shè)備 init 結(jié)構(gòu)的運(yùn)行時(shí)版本。
典型的設(shè)備初始化函數(shù)和初始化流程如下所述:
步驟 1:在應(yīng)用程序中創(chuàng)建設(shè)備 init 結(jié)構(gòu)的定義(或?qū)嵗ɡ缃Y(jié)構(gòu) adxxxx_init_params),以初始化用戶特定的設(shè)備參數(shù)和與平臺(tái)相關(guān)的驅(qū)動(dòng)程序參數(shù)。參數(shù)是在編譯時(shí)定義的。
注意:init 結(jié)構(gòu)中定義的參數(shù)因設(shè)備而異。
步驟 2:在應(yīng)用程序代碼中創(chuàng)建設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)的指針實(shí)例(變量)。
用戶應(yīng)用程序需要?jiǎng)?chuàng)建設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)的單個(gè)指針實(shí)例。此實(shí)例將傳遞給所有無操作系統(tǒng)驅(qū)動(dòng)程序 API/函數(shù),以訪問設(shè)備特定的參數(shù)。應(yīng)用程序代碼中定義的此指針實(shí)例指向堆中動(dòng)態(tài)分配的內(nèi)存,該內(nèi)存通過設(shè)備 init 函數(shù)(如 adxxxx_init())完成,該函數(shù)在 no-OS 驅(qū)動(dòng)程序中定義。
第 3 步:通過調(diào)用設(shè)備 init 函數(shù)初始化設(shè)備和其他特定于平臺(tái)的外設(shè)。
no-OS 驅(qū)動(dòng)程序中定義的 adxxxx_init() 函數(shù)使用通過adxxx_init_param結(jié)構(gòu)傳遞的用戶特定參數(shù)初始化設(shè)備。設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)的指針實(shí)例和設(shè)備 init 結(jié)構(gòu)的實(shí)例作為兩個(gè)參數(shù)傳遞給此 init 函數(shù)。用戶應(yīng)用程序代碼可以多次調(diào)用 adxxxx_init() 函數(shù),前提是 init 調(diào)用通過調(diào)用設(shè)備刪除函數(shù)來平衡。
通過器件寄存器讀/寫功能訪問存儲(chǔ)器映射(寄存器內(nèi)容)如圖6所示
圖6.訪問寄存器內(nèi)容。
用戶可以通過無操作系統(tǒng)驅(qū)動(dòng)程序設(shè)備特定的adxxx_read/write()函數(shù)訪問設(shè)備寄存器內(nèi)容(如產(chǎn)品ID、暫存器值、OSR等)。
大多數(shù)情況下,用戶不直接使用注冊訪問功能。設(shè)備特定函數(shù)通過這些寄存器訪問函數(shù)(如 adxxxx_ spi_reg_read/write())調(diào)用。建議盡可能使用設(shè)備配置和狀態(tài) API 訪問設(shè)備內(nèi)存映射,而不是使用直接寄存器訪問函數(shù),因?yàn)檫@可確保設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)與設(shè)備中的配置保持同步。
平臺(tái)驅(qū)動(dòng)程序
平臺(tái)驅(qū)動(dòng)程序是包裝特定于平臺(tái)的 API 的硬件抽象層 (HAL) 之一。它們由無操作系統(tǒng)設(shè)備驅(qū)動(dòng)程序或用戶應(yīng)用程序代碼調(diào)用,以提供獨(dú)立于底層硬件和軟件平臺(tái)的功能。平臺(tái)驅(qū)動(dòng)程序包裝了特定于平臺(tái)的低級(jí)硬件功能,如 SPI/I2C 初始化和讀/寫、GPIO 初始化和讀/寫、UART 初始化和接收/發(fā)送、用戶特定的延遲、中斷等。
SPI 平臺(tái)驅(qū)動(dòng)程序模塊的典型文件結(jié)構(gòu)如圖 7 所示。
圖7.SPI 平臺(tái)驅(qū)動(dòng)程序代碼結(jié)構(gòu)。
使用平臺(tái)驅(qū)動(dòng)程序
平臺(tái)驅(qū)動(dòng)程序代碼通常合并在用 C/C++ 編程語言編寫的三個(gè)源文件中。
1) spi.h:這是一個(gè)與平臺(tái)無關(guān)的文件,其中包含 SPI 功能所需的設(shè)備結(jié)構(gòu)和枚舉。此標(biāo)頭中定義的 C 編程接口沒有平臺(tái)依賴項(xiàng)。
在 init 和設(shè)備結(jié)構(gòu)中聲明的所有參數(shù)對(duì)于任何平臺(tái)上的 SPI 接口都是通用的。
設(shè)備 init 結(jié)構(gòu)中使用的 void *extra 參數(shù)允許用戶傳遞其他(額外)參數(shù),這些參數(shù)可能特定于所使用的平臺(tái)。
在 SPI 驅(qū)動(dòng)程序結(jié)構(gòu)和 SPI 初始化結(jié)構(gòu)中聲明的參數(shù)幾乎彼此相同。SPI 驅(qū)動(dòng)程序結(jié)構(gòu)是 SPI 初始化結(jié)構(gòu)的運(yùn)行時(shí)版本。
2) spi.cpp/.c:該文件包含在spi.h文件中聲明的函數(shù)的實(shí)現(xiàn),這些函數(shù)用于初始化SPI外設(shè)并從中為特定平臺(tái)讀取/寫入數(shù)據(jù)。術(shù)語“平臺(tái)”在廣義上是指硬件微控制器(目標(biāo)設(shè)備)和軟件(例如,RTOS或Mbed-OS)的組合。此文件依賴于平臺(tái),在移植到其他平臺(tái)上時(shí)需要修改。
圖 9 詳細(xì)介紹了 Mbed 平臺(tái)的 SPI 接口,并顯示了如何使用這些接口和器件初始化/驅(qū)動(dòng)程序結(jié)構(gòu)初始化 SPI 和讀/寫數(shù)據(jù)。
圖8.SPI 初始化和驅(qū)動(dòng)程序結(jié)構(gòu)。
圖9.SPI API 或函數(shù)。注意:spi_init() 和 spi_write_and_read() 添加的代碼是縮寫代碼,為清楚起見,省略了詳細(xì)信息。
圖 10.SPI 額外的初始化和驅(qū)動(dòng)程序結(jié)構(gòu)。
3) spi_extra.h:此文件包含特定于給定平臺(tái)的其他設(shè)備結(jié)構(gòu)或枚舉。這允許用戶應(yīng)用程序代碼提供通用 spi.h 文件中未涵蓋的配置。例如,SPI引腳可能因平臺(tái)而異,因此可以作為這些平臺(tái)特定額外結(jié)構(gòu)的一部分添加。
移植平臺(tái)驅(qū)動(dòng)程序
通常通過創(chuàng)建特定于平臺(tái)的 .cpp/.c 和 _extra.h 文件,可以將平臺(tái)驅(qū)動(dòng)程序從一個(gè)平臺(tái)(微控制器)移植到另一個(gè)平臺(tái)(微控制器)。平臺(tái)驅(qū)動(dòng)程序位于微控制器單元供應(yīng)商提供的特定于設(shè)備的硬件抽象層 (HAL) 之上一層。因此,將平臺(tái)驅(qū)動(dòng)程序從一個(gè)平臺(tái)移植到另一個(gè)平臺(tái)需要對(duì)與調(diào)用其供應(yīng)商提供的 HAL 中存在的函數(shù)或 API 相關(guān)的平臺(tái)驅(qū)動(dòng)程序代碼進(jìn)行一些最小的更改。
圖12中的圖表區(qū)分了基于Mbed的SPI平臺(tái)驅(qū)動(dòng)程序和ADuCM410 SPI平臺(tái)驅(qū)動(dòng)程序。
ADI公司的no-OS存儲(chǔ)庫和平臺(tái)驅(qū)動(dòng)程序的GitHub源代碼鏈接可在ADI公司的Wiki和GitHub頁面上找到。
為無操作系統(tǒng)驅(qū)動(dòng)程序做出貢獻(xiàn)
ADI no-OS 驅(qū)動(dòng)程序是開源的,托管在 GitHub 上。這些驅(qū)動(dòng)器不僅支持精密轉(zhuǎn)換器,還支持許多其他ADI公司產(chǎn)品,如加速度計(jì)、收發(fā)器、光電器件等。熟悉源代碼的任何人都可以通過提交更改并創(chuàng)建拉取請求來查看這些更改,從而為這些驅(qū)動(dòng)程序做出貢獻(xiàn)。
有許多示例項(xiàng)目可以在 Linux 和/或 Windows 環(huán)境中運(yùn)行。許多示例項(xiàng)目都是使用硬件描述性語言 (HDL) 開發(fā)的,可在 Xilinx、Intel 等開發(fā)的 FPGA 上運(yùn)行,并且針對(duì)不同供應(yīng)商開發(fā)的處理器。??
對(duì)于沒有操作系統(tǒng)的系統(tǒng),可以在ADI公司的no-OS GitHub存儲(chǔ)庫中訪問C語言中的No-OS軟件驅(qū)動(dòng)程序。
ADI公司維基提供了為使用Mbed和ADuCMxxx平臺(tái)的精密轉(zhuǎn)換器開發(fā)的示例。
圖 11.特定于 mbed 平臺(tái)的 SPI 初始化實(shí)現(xiàn)。
圖 12.平臺(tái)驅(qū)動(dòng)程序差異。
-
轉(zhuǎn)換器
+關(guān)注
關(guān)注
27文章
8703瀏覽量
147172 -
寄存器
+關(guān)注
關(guān)注
31文章
5343瀏覽量
120361 -
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
6823瀏覽量
123331
發(fā)布評(píng)論請先 登錄
相關(guān)推薦
評(píng)論