在嵌入式開發中,我們經常需要在系統啟動的早期階段(U-Boot)識別硬件版本或配置。本文將詳細介紹如何在U-Boot中為RK3588平臺添加SARADC(Successive Approximation Register Analog-to-Digital Converter)檢測功能,通過讀取ADC電壓值來區分不同的硬件版本,并將結果存入環境變量,為后續的啟動流程提供依據。

核心思路與應用場景
為什么需要在U-Boot中做ADC檢測?
U-Boot作為引導加載程序,運行在操作系統內核之前,擁有極高的硬件訪問權限。在這個階段進行ADC檢測,可以實現:
?硬件版本自動識別:通過讀取主板上由電阻分壓網絡決定的ADC引腳電壓,U-Boot可以判斷出當前硬件的具體型號或版本。
?動態配置加載:根據識別出的硬件版本,U-Boot可以加載不同的設備樹(Device Tree)、啟動參數或執行特定的初始化腳本,實現“一鏡像適配多硬件”的目標。
?故障診斷:檢測關鍵電源電壓或傳感器狀態,在啟動早期發現硬件異常。
第一步:配置SARADC設備樹(DTS)
要在U-Boot中使用SARADC,首先需要確保其設備樹節點已正確配置并啟用。
文件路徑:u-boot/arch/arm/dts/rk3588-u-boot.dtsi
/* 在 rk3588-u-boot.dtsi 文件中找到并確認 saradc 節點 */&saradc {/** u-boot, dm-pre-reloc; 是一個關鍵屬性,* 它告訴 U-Boot 的驅動模型(Driver Model)* 在 relocation(重定位)之前就初始化這個設備。* 因為我們要在 board_init_f 階段(重定位前)讀取ADC,* 所以必須添加此屬性。*/u-boot, dm-pre-reloc;status ="okay";};
代碼解讀:
?&saradc:引用主設備樹中定義的saradc節點。
?u-boot, dm-pre-reloc;:核心配置。確保SARADC驅動在U-Boot早期階段(內存重定位前)就被初始化,這樣我們才能在board_init_f或board_init_r中調用其功能。
?status = "okay";:啟用這個設備節點。
第二步:編寫ADC檢測邏輯
接下來,我們在板級初始化文件中添加實際的檢測代碼。
文件路徑:u-boot/arch/arm/mach-rockchip/board.c
/* 在 board.c 文件的合適位置(如 board_init_r 函數之前)添加此函數 */voidsbc_id_detection(void){/* 1. 定義變量 */intclosest_level =7;// 默認的最高等級unsignedintadc_value;// 存儲原始ADC讀數 (0-4095 for 12-bit)unsignedintvoltage_mv;// 轉換后的電壓值 (mV)/* 2. 定義電壓區間與硬件版本的對應關系 *//* 這是一個典型的電阻分壓網絡設計,不同的電阻組合產生不同的電壓。你需要根據自己的硬件原理圖來修改這兩個數組中的值。 */constintmin_mv[] = {1640,1430,1220,1000,790, 560, 350, 0};constintmax_mv[] = {1840,1630,1420,1200,990, 770, 550,250};/* 3. 讀取ADC通道3的值 *//* "saradc" 是設備樹中的節點名,3 是要讀取的通道號 */if(adc_channel_single_shot("saradc",3, &adc_value) ==0) {/* 4. 將ADC原始值轉換為電壓值 (mV) *//*計算公式:Vout = Vin * (ADC_Value / 2^n)- Vin (參考電壓) = 1800 mV (根據瑞芯微文檔)- n (ADC位數) = 12 bits, 所以 2^12 = 4096*/voltage_mv = (adc_value *1800) /4095;/* 5. 根據電壓值查找匹配的硬件等級 */for(inti =0; i 8; i++) {if(voltage_mv >= min_mv[i] && voltage_mv <= max_mv[i]) {closest_level = i;break;// 找到后立即跳出循環}}/* 6. 將檢測結果存入U-Boot環境變量 *//* 環境變量 SBCID 可以在后續的啟動腳本中被讀取和使用 */env_set_ulong("SBCID", closest_level);/* 調試信息,可以在串口終端看到 */printf("SARADC: Voltage detected: %d mV, SBCID set to %dn", voltage_mv, closest_level);}else{/* 7. 處理ADC讀取失敗的情況 */env_set("SBCID","unknown");printf("SARADC: Failed to read from channel 3. SBCID set to 'unknown'n");}}/** 將檢測函數注冊到U-Boot的初始化序列中。* board_init_r 是一個合適的位置,它在設備初始化完成后、* 環境變量初始化后、啟動倒計時開始前執行。*/// 注意:具體的注冊方式可能因U-Boot版本而異,// 請查閱你所用U-Boot版本的板級文件,找到合適的位置調用 sbc_id_detection();// 例如,在 board_r.c 的某個初始化函數中添加:// sbc_id_detection();
代碼解讀:
1.adc_channel_single_shot(): U-Boot提供的便捷API,用于單次讀取指定ADC設備和通道的值。
2.電壓換算:根據瑞芯微手冊,SARADC的參考電壓Vref為1.8V(1800mV)。代碼將12位的ADC讀數(范圍0-4095)線性換算為實際電壓。
3.等級匹配:通過for循環將計算出的電壓值與預設的min_mv和max_mv數組進行比較,找到對應的硬件等級closest_level。
4.環境變量:env_set_ulong()將檢測到的等級存入名為SBCID的環境變量。這個變量非常關鍵,后續的啟動腳本(如boot.cmd)就可以通過判斷SBCID的值來執行不同的操作。
第三步:如何使用檢測結果(參考)
檢測結果SBCID已存入環境變量,現在你可以在U-Boot的啟動腳本中靈活運用它。
文件路徑:u-boot/board/rockchip/your_board/your_board.env(或類似的腳本文件)
# 在 U-Boot 啟動腳本中,可以這樣使用 SBCIDiftest${SBCID}-eq 0;thenecho"Detected Board Version A. Loading corresponding Device Tree..."setenv fdtfile rockchip/rk3588-board-version-a.dtbeliftest${SBCID}-eq 1;thenecho"Detected Board Version B. Loading corresponding Device Tree..."setenv fdtfile rockchip/rk3588-board-version-b.dtbelseecho"Detected unknown board or using default configuration."setenv fdtfile rockchip/rk3588-board-default.dtbfi# 后續的 bootcmd 會使用 $fdtfile 變量來加載正確的設備樹# run bootcmd
第四步:uboot 命令行中查看
bdinfo
關鍵要點與風險預案
1.時序問題:確保ADC檢測函數在所有必要驅動初始化之后調用。board_init_r是一個安全的選擇。
2.硬件依賴:此方案完全依賴于硬件設計。分壓電阻的精度、焊接質量、以及ADC引腳的電氣連接都會影響檢測結果。
3.區間設計:在設計min_mv和max_mv數組時,要考慮到電阻容差和ADC采樣誤差,為每個區間留出足夠的余量,避免電壓值落在區間邊界導致誤判。
4.調試:在開發階段,可以將printf語句打開,通過串口終端觀察ADC的原始值、換算后的電壓值以及最終的SBCID,這對于調試硬件和校準區間非常有幫助。
下一步
?代碼集成:將上述代碼片段集成到您的U-Boot源碼樹中,并根據您的具體硬件原理圖,精確調整min_mv和max_mv數組的值。
?腳本優化:完善您的U-Boot啟動腳本,利用SBCID環境變量實現更復雜的啟動邏輯,例如加載不同的內核參數或根文件系統。
希望這篇文章能幫助您順利完成U-Boot中的ADC檢測功能開發。
-
嵌入式
+關注
關注
5198文章
20449瀏覽量
334012 -
adc
+關注
關注
100文章
7511瀏覽量
555948 -
u-boot
+關注
關注
0文章
135瀏覽量
39773 -
RK3588
+關注
關注
8文章
556瀏覽量
7323
發布評論請先 登錄
Rockchip rk3588 U-Boot詳解(一)
Rockchip rk3588 U-Boot詳解 (二)
U-boot的基本介紹
基于RK3588的NPU案例分享!6T是真的強!
基于迅為RK3568/RK3588開發板的AI圖像識別方案
如何在rk3588j上使用uboot命令行測試pwm驅動呢?
迅為RK3568/RK3588開發板人工智能AI攝像頭識別功能方案
u-boot簡介
RK3588與3588s的區別
rk3588是armv8嗎?rk3588硬件資料
深入理解?RK3506 U-Boot?重定位:從代碼到原理
深入解析RK3588 U-Boot板級文件:evb_rk3588.c核心邏輯拆解
在U-Boot中為RK3588添加SARADC檢測:從零到一的硬件識別方案
評論