最近痞子衡寫了篇文章 《i.MXRT從Serial NAND啟動時間測量》,這篇文章詳細測試了不同長度的 Non-XIP 程序在不同 NAND 訪問速度下由 BootROM 加載啟動所需要的時間,比如 240KB 的程序在 60MHz NAND 的訪問速度下啟動時間接近 30ms,這個啟動時間對于有些響應時間敏感的應用(比如汽車電子)來說還是比較長的。
對于Non-XIP 程序,經過冷啟動后,其程序體本身已經被加載進芯片內部 SRAM 了,除非發生 POR,否則 SRAM 中的程序會一直保持著。假設程序在惡劣的電磁環境中運行,代碼里雖然包含異常復位的處理,但是每次程序復位啟動時間還是和冷啟動時間一樣長(每次都需要 BootROM 搬移加載),有點難以接受。那么對于這種熱啟動的情況,程序啟動時間能夠縮短嗎?答案是可以的,今天痞子衡就介紹下 i.MXRT 上的 INIT_VTOR 特性:
-
備注1:本文主角是i.MXRT1050,但內容也基本適用其它i.MXRT10xx系列。
-
備注2:同樣的測試在i.MXRT1160/1170下無效,因為CM7_INIT_VTOR所在的IOMUXC_LPSR_GPR->GPR26在軟復位下不能保持。
INIT_VTOR功能簡介
在介紹INIT_VTOR 功能之前,大家首先要對 ARM Cortex-M 內核的中斷向量表偏移寄存器 SCB->VTOR 功能有所了解,具體可以看痞子衡的舊文 《Cortex-M中斷向量表原理及其重定向方法》。
簡單來說,芯片上電啟動后內核都是從 SCB->VTOR 指向的地址處獲取程序中斷向量表里的第二個向量即所謂的復位函數Reset_Handler。有了復位函數,就找到了程序入口。
startup_MIMXRT1052.s
__vector_table
DCD sfe(CSTACK)
DCD Reset_Handler
DCD NMI_Handler
DCD HardFault_Handler
DCD MemManage_Handler
DCD BusFault_Handler
DCD UsageFault_Handler
...
對于i.MXRT1050,我們知道芯片上電復位都是執行 BootROM 代碼,BootROM 中斷向量表固定放在了 0x0020_0000 地址處。那么這個 0x0020_0000 地址是怎么被賦給 SCB->VTOR 寄存器的呢?這就引出了本文主角 IOMUXC_GPR->GPR16[32:7] - CM7_INIT_VTOR 位,這 25bits 的 CM7_INIT_VTOR 值每次復位都會被芯片系統自動加載進 SCB->VTOR[32:7] 中,其默認值即對應 BootROM 中斷向量表地址。
正如痞子衡舊文 《妙用i.MXRT1xxx里SystemReset不復位的GPR寄存器》 提及的那樣,IOMUXC_GPR 寄存器僅在 POR 復位或者整體重新上電時才會被置位,這就意味著我們在應用程序中只需要設置一次 CM7_INIT_VTOR 值,其后不管發生多少次類似NVIC_SystemReset() 的復位,CM7_INIT_VTOR 值都不會改變。
使用INIT_VTOR縮短程序熱重啟有了上一節的理論基礎,我們來做個實驗。痞子衡找了一塊MIMXRT1050-EVK12(Rev.A)板卡,將其啟動設備換成串行 NAND 啟動(電阻切換到使能 U33,并將 U33 替換成華邦 W25N01GV)。
然后按照串行 NAND 啟動時間測試方法那樣修改SDK_2_13_0_EVKB-IMXRT1050oardsevkbimxrt1050demo_appsled_blinkyiar 例程(debug build,即代碼在 ITCM 運行,注意修改鏈接文件中的 m_interrupts_start = 0x00002000),并在SystemInit() 函數里調用如下測試函數,根據是否設置 IOMUXC_GPR->GPR16 寄存器編譯出兩個不同鏡像文件(直接編輯 bin 文件將其均填充至 120KB)。
void set_led_gpio(void)
{
CLOCK_EnableClock(kCLOCK_Iomuxc);
gpio_pin_config_t USER_LED_config = {
.direction = kGPIO_DigitalOutput,
.outputLogic = 0U,
.interruptMode = kGPIO_NoIntmode
};
GPIO_PinInit(GPIO1, 9U, &USER_LED_config);
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0x10B0U);
SystemCoreClockUpdate();
GPIO_PinWrite(GPIO1, 9U, 0U);
SDK_DelayAtLeastUs(5000, SystemCoreClock);
// 根據是否設置 CM7_INIT_VTOR 分別編譯兩個不同鏡像文件
// 設置 CM7_INIT_VTOR 指向地址 0x00002000,即用戶應用程序中斷向量表
IOMUXC_GPR->GPR16 = (IOMUXC_GPR->GPR16 & (~IOMUXC_GPR_GPR16_CM7_INIT_VTOR_MASK)) | IOMUXC_GPR_GPR16_CM7_INIT_VTOR(0x2000 >> 7);
NVIC_SystemReset();
while (1);
}
然后借助 MCUBootUtility 工具將這兩個不同鏡像文件下載進串行 NAND flash,并測試相應啟動時間。這里 Flash 運行速度就選擇 60MHz:
下面是不設置 IOMUXC_GPR->GPR16 的程序啟動時間測試結果,無論是一開始的POR 冷啟動還是后面 NVIC_SystemReset() 引起的熱啟動,啟動時間都需要約 18.66ms:
下面是設置了 IOMUXC_GPR->GPR16 指向 0x2000 之后的程序啟動時間測試結果,只有一開始的 POR 冷啟動時間是 18.66ms,后面 NVIC_SystemReset() 引起的熱啟動時間僅需要約 5.26ms。
上述實驗結果證明,設置 IOMUXC_GPR->GPR16 指向應用程序中斷向量表之后確實能縮短程序熱啟動時間。有朋友可能會疑問,設置了從 ITCM 直接熱啟動后為何還是有 5.26ms 的啟動時間?這其實主要是從進入應用程序 Reset_Handler 到執行到測試 GPIO 拉低時的代碼所消耗的時間,并且需要注意的是由 BootROM 加載執行的程序默認是在 ROM 配置后的 396MHz 主頻下執行的(主頻夠快,測試代碼消耗時間可以忽略不計),而直接復位從ITCM 里執行的程序是在默認主頻 12MHz 下執行的(主頻較慢,測試代碼消耗時間不得不計)。
最后再提一下,除了直接在應用程序里設置 IOMUXC_GPR->GPR16 之外,也可以借助 BootROM 的 DCD 功能來設置,同樣可以借助 MCUBootUtility 直接完成(詳細步驟可參考《利用i.MXRT1xxx系列ROM集成的DCD功能可輕松配置指定外設》),痞子衡實測是有效的。
翻看i.MXRT1050 參考手冊 System Boot 章節,IOMUXC_GPR寄存器地址空間也確實在有效的 DCD 設置范圍。
END
更多恩智浦AI-IoT市場和產品信息,邀您同時關注“NXP客棧”微信公眾號

NXP客棧
恩智浦致力于打造安全的連接和基礎設施解決方案,為智慧生活保駕護航。
長按二維碼,關注我們
恩智浦MCU加油站
這是由恩智浦官方運營的公眾號,著重為您推薦恩智浦MCU的產品信息、開發技巧、教程文檔、培訓課程等內容。

長按二維碼,關注我們
原文標題:借助i.MXRT10xx系列INIT_VTOR功能縮短程序熱重啟時間
文章出處:【微信公眾號:恩智浦MCU加油站】歡迎添加關注!文章轉載請注明出處。
-
mcu
+關注
關注
146文章
17824瀏覽量
360113 -
恩智浦
+關注
關注
14文章
5945瀏覽量
112876
原文標題:借助i.MXRT10xx系列INIT_VTOR功能縮短程序熱重啟時間
文章出處:【微信號:NXP_SMART_HARDWARE,微信公眾號:恩智浦MCU加油站】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
RT10XX RC24M開啟自動校準功能

MSP430x5xx和MSP430x6xx系列系列用戶指南

Simcenter Flotherm XT電子熱分析軟件

從MSP430F2xx、G2xx系列遷移到MSP430FR58xx/FR59xx/68xx/69xx

從MSP430F4xx系列遷移到MSP430FR58xx/FR59xx/FR68xx/FR69xx系列

iPhone 16 Pro機型發貨時間縮短
【GD32 MCU 移植教程】8、從 STM32F4xx 系列移植到 GD32F4xx 系

評論