大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家介紹的是利用i.MXRT1xxx系列ROM集成的DCD功能可輕松配置指定外設(shè)。
關(guān)于 i.MXRT1xxx 系列芯片 BootROM 中集成的 DCD 功能這個(gè)話(huà)題,痞子衡早就想寫(xiě)了,但是一直沒(méi)有動(dòng)筆,畢竟這個(gè)話(huà)題比較生澀,單獨(dú)講會(huì)比較枯燥。最近痞子衡在支持一個(gè) i.MXRT1170 客戶(hù),需要在客戶(hù)板卡上跑其應(yīng)用代碼的壓力測(cè)試,但是客戶(hù)因?yàn)楸C艿木壒蕛H提供了應(yīng)用可執(zhí)行文件,而我們又需要在客戶(hù)應(yīng)用里額外加一些配置代碼做測(cè)試,測(cè)試過(guò)程中會(huì)涉及多次斷電上電,如果掛外部調(diào)試器去做額外配置又太繁瑣,這時(shí)候 DCD 功能就派上用場(chǎng)了。
Note:文中貼圖、代碼主要以 i.MXRT1170 為例,其余 i.MXRT1xxx 系列原理類(lèi)似。
一、DCD是什么及其應(yīng)用場(chǎng)景
DCD 是 Device Configuration Data 縮寫(xiě),這是 i.MXRT1xxx 系列芯片 BootROM 里帶的一個(gè)附加功能,主要用于 App 啟動(dòng)前系統(tǒng)外設(shè)的用戶(hù)定制化配置。我們知道 i.MXRT1xxx 系列芯片上電永遠(yuǎn)都是 BootROM 代碼先執(zhí)行,然后由 BootROM 再去加載 App 執(zhí)行。如果希望在 App 執(zhí)行前系統(tǒng)就已經(jīng)被配置到指定狀態(tài)(即不需要在 App 里去做這方面系統(tǒng)設(shè)置),那就需要借助 DCD 功能,你只需要按格式將 DCD 數(shù)據(jù)放到 Boot Device 指定偏移處即可,BootROM 會(huì)自動(dòng)去解析執(zhí)行。
翻看芯片參考手冊(cè) Device Configuration Data (DCD) 章節(jié),你會(huì)發(fā)現(xiàn) DCD 數(shù)據(jù)設(shè)計(jì)特別簡(jiǎn)單,它總共支持三類(lèi)命令:Write data(Tag 是 0xCC)、Check data(Tag 是 0xCF)、NOP(Tag 是 0xC0),這三類(lèi)命令就是為了讀寫(xiě)芯片外設(shè)寄存器而設(shè)計(jì)的,我們需要做的就是組合這三類(lèi)命令完成指定外設(shè)模塊寄存器的設(shè)置序列。任意打開(kāi)一個(gè) RT1170 SDK 示例工程,都會(huì)包含 dcd.c/h 文件(僅當(dāng)工程選項(xiàng)預(yù)編譯宏里有 XIP_BOOT_HEADER_DCD_ENABLE=1 才會(huì)被使能)。
隨便摘其中兩句分析下,第一句表明是 Write data 命令的 *address = val_msk 動(dòng)作合集,第二句是執(zhí)行 *((uint32_t *)0x40CC0200) = 0x00000703,也就是 CCM->CLOCK_ROOT[kCLOCK_Root_Semc].CONTROL = 0x703。
/*?#1.1-129,?command?header?bytes?for?merged?'Write?-?value'?command?*/
0xCC,?0x04,?0x0C,?0x04,
/*?#1.1,?command:?write_value,?address:?CCM_CLOCK_ROOT4_CONTROL,?value:?0x703,?size:?4?*/
0x40,?0xCC,?0x02,?0x00,?0x00,?0x00,?0x07,?0x03,
接著這個(gè)示例 dcd.c 內(nèi)容繼續(xù)聊,這其實(shí)是配置芯片 SEMC 外設(shè)去初始化外部 SDRAM 的全部序列。有了這個(gè) DCD 設(shè)置,那么 App 里就可以不用管外部 SDRAM 初始化工作了,直接讀寫(xiě)訪(fǎng)問(wèn) SDRAM 完成相應(yīng)應(yīng)用業(yè)務(wù)功能即可,這也是 DCD 的典型應(yīng)用場(chǎng)景。如果應(yīng)用代碼直接是全部在 SDRAM 執(zhí)行,在不設(shè)計(jì)用戶(hù)二級(jí) Bootloader 做加載的情況下,DCD 是必選的解決方案。
二、以實(shí)際客戶(hù)案例代入DCD使用
現(xiàn)在回到客戶(hù)的實(shí)際案例,客戶(hù) RT1170 板卡上用了一顆來(lái)自 MXIC 的 Octal Flash,代碼是執(zhí)行在 Flash 上,現(xiàn)在我們需要測(cè)試不同 FlexSPI1->DLLACR[SLVDLYTARGET] 設(shè)置下的工作情況,而我們手頭僅有客戶(hù)可執(zhí)行文件。
將客戶(hù)可執(zhí)行文件下載進(jìn)板卡,并設(shè)置啟動(dòng)模式為從 Flash 啟動(dòng)(2'b10),然后掛上 JLINK 調(diào)試器讀取 FlexSPI1->DLLACR 寄存器值(該寄存器地址是 0x400cc0c0),得到 0x00400079,其中 SLVDLYTARGET 是默認(rèn)的理想值 4'b1111,這個(gè)值是 BootROM 自動(dòng)配置的,我們無(wú)法通過(guò) FDCB 啟動(dòng)頭來(lái)更改設(shè)置。
為了做壓力測(cè)試,我們需要更改不同的 FlexSPI1->DLLACR[SLVDLYTARGET] 值,比如將其設(shè)為 4'b1000,這時(shí)候可以借助 DCD 來(lái)實(shí)現(xiàn),我們直接使用 MCUBootUtility 工具(需要使用 v4.1.1 版本及以上)來(lái)使能 DCD。
下載地址:https://github.com/JayHeng/NXP-MCUBootUtility/archive/refs/tags/v4.1.1.zip
將客戶(hù)板卡啟動(dòng)模式改為 Serial Download (2'b01),插上 UART/USB 下載線(xiàn),打開(kāi) MCUBootUtility 工具,在 DCD 設(shè)置界面里啟用 "Use DCD description" 選項(xiàng),并在動(dòng)作框里直接輸入下面語(yǔ)句(這里直接是類(lèi) C 語(yǔ)法,會(huì)被工具自動(dòng)轉(zhuǎn)成 DCD 數(shù)據(jù)),然后連接、下載。
*(uint32_t*)0x400cc0c0?=?0x00400041;
將板卡設(shè)為從 Flash 啟動(dòng)模式后重新上電,掛上 JLINK 再去讀取,此時(shí) FlexSPI1->DLLACR 已經(jīng)是期望的 0x00400041,說(shuō)明 DCD 功能生效了。這里還有一個(gè)注意事項(xiàng),即 BootROM 利用 FDCB 啟動(dòng)頭配置 FlexSPI 外設(shè)在前,解析執(zhí)行 DCD 數(shù)據(jù)在后,所以我們才能借助 DCD 實(shí)現(xiàn)這樣的更改測(cè)試。
三、DCD能配置全部外設(shè)嗎?
看起來(lái) DCD 特別強(qiáng)大,那么它能幫助操作 ARM 4GB 系統(tǒng)空間里的全部地址嗎?答案是否定的,出于安全考慮,BootROM 里做了地址限制,我們僅能用 DCD 操作如下指定的一些外設(shè)(不同 i.MXRT 系列有所不同):
至此,利用i.MXRT1xxx系列ROM集成的DCD功能可輕松配置指定外設(shè)痞子衡便介紹完畢了,掌聲在哪里~~~