一、E3210 參數
E3210 是基於 Dual-Core ARM Cortex-R5F 的嵌入式應用微控制器,有 32KB 的 I-Cache、32KB 的 D-Cache 和 128 KB TCM,內置了 1M 的 SRAM,可以支持 8 路 CAN/CANFD、12 LIN/UART、百兆以太網、1 路 USB2.0、1 路 I2S 、4 路 I2C、4 路 SPI 等各種串行通信接口。本套 Demo 是基於 E3210 開發板就行搭建,下圖為開發板外設介紹。
二、Boot Manager 介紹
Boot Manager 主要功能有:① 啟動流程管理和狀態機維護;②對“啟動APP”進行驗簽(根據Boot Reason);③ 負責對“啟動APP”的回滾(根據其Version)和選擇;④ 負責跳轉至FBL/A/APP。本文檔主要介紹 BM 將 APP 從 Flash 搬運到 RAM,並進行跳轉。流程圖如下:
三、代碼說明
1、BM 中主要包括跳轉和搬運,跳轉主要由 Boot_Reason 控制。
Boot_Reason |
|
|
BOOT_FBL |
0x00 |
BM -> FBL |
BOOT_APP |
0x01 |
BM -> APP |
PROG_FBL |
0x02 |
在 FBL 中升級 Bootloaser |
PROG_APP |
0x03 |
在 FBL 中升級 APP |
(1)Mcu_Read_Rstgen_GPR0 函數
功能:讀 GENERAL_REGn 寄存器的值,GENERAL_REGn 屬於通用寄存器,Reset 後寄存器的值不會被清空
傳入參數 a:寄存器偏移地址
返回值:寄存器 a Bit 的值
/**
* @brief 讀寄存器值
*
* 讀 GENERAL_REGn 寄存器值判斷 Boot Reason
*
* @param[in] a 寄存器 Bit
* @return 寄存器 a Bit 的值
*/
uint8 Mcu_Read_Rstgen_GPR0(uint8 a)
{
uint32 b = APB_RSTGEN_SF_BASE;
return readb(b + GENERAL_REG_OFF(a));
}
(2)Mcu_Write_Rstgen_GPR0 函數
功能:寫 GENERAL_REGn 寄存器的值,GENERAL_REGn 屬於通用寄存器,Reset 後寄存器的值不會被清空
傳入參數 v :寫入寄存器的值
傳入參數 a: 寄存器偏移地址
/**
* @brief 寫寄存器值
*
* 寫 GENERAL_REGn 寄存器值判斷 Boot Reason
*
* @param[in] v 寫入寄存器的值
* @param[in] a 寄存器 Bit
*/
void Mcu_Write_Rstgen_GPR0(uint8 v , uint8 a)
{
uint32 b = APB_RSTGEN_SF_BASE;
ram_writeb(b + GENERAL_REG_OFF(a),v);
}
(3)Mcu_SetApp 函數
功能:將 APP 從 Flash 搬運到 RAM
傳入參數:Flash_Add APP 在 Flash 中的起始地址
傳入參數:RAM_Add APP 在 RAM 中的起始地址
傳入參數: Size APP 的 大小
/**
* @brief數據搬運
*
* 將 APP 從 Flash 搬運到 RAM
*
* @param[in] Flash_Add APP 在 Flash 中的起始地址
* @param[in] RAM_Add APP 在 RAM 中的起始地址
* @param[in] Size APP 的 大小
*/
void Mcu_SetApp(uint32 Flash_Add,uint32 RAM_Add,uint32 Size)
{
uint8 data_buff_read[buff_NUM];
uint32 Flash_read_start = Flash_Add;
uint32 Flash_read_add = Flash_read_start;
uint32 RAM_write_start = RAM_Add;
uint32 RAM_write_add = RAM_write_start;
uint32 Flash_Num = Size / buff_NUM;
//每次搬運的 4K,搬運 Flash_Num 次
for(int j = 0 ; j <= Flash_Num; j++)
{
//Clean buff
memset(data_buff_read, 0, sizeof(data_buff_read));
//讀 4K 大小的 Flash 數據
Fls_Read(Flash_read_add, data_buff_read, buff_NUM);
while(MEMIF_JOB_PENDING == Fls_GetJobResult()) {
Fls_MainFunction();
}
//將從 Flash 里讀取的 4K 寫入 RAM 中
for(int i = 0 ; i < 0x1000 ; i++)
{
ram_writeb(RAM_write_add,data_buff_read[i]);
RAM_write_add += 1;
}
//地址偏移
Flash_read_add = (buff_NUM * j) + Flash_read_start;
RAM_write_add = (buff_NUM * j) + RAM_write_start;
}
}
(4)Mcu_StateMachine 函數
功能:根據 Boot_Reason 值選擇狀態,BOOT_FBL 跳轉到 FBL;BOOT_APP 搬運並跳轉 APP;PROG_FBL OTA 升級 BOOT;PROG_APP OTA 升級 APP
傳入參數: Boot_Reason 狀態
/**
* @brief 跳轉判斷
*
* 根據 Boot_Reason 值選擇狀態,BOOT_FBL 跳轉到 FBL;BOOT_APP 搬運並跳轉 APP;PROG_FBL OTA 升級 BOOT;PROG_APP OTA 升級 APP
*
* @param[in] Boot_Reason 狀態
*/
void Mcu_StateMachine(uint8 Boot_Reason)
{
if(BOOT_FBL == Boot_Reason)
{
// BM -> FBL
soc_kick_core(KICK_CR5_SF,0x42C000);
}
else if(BOOT_APP == Boot_Reason)
{
//從 Flash 搬運 APP 到 RAM
Mcu_SetApp(APP_FLASH_ADD,APP_RAM_ADD,APP_SIZE);
//BM -> APP
soc_kick_core(KICK_CR5_SF,0x465000);
}
}
2、FBL 中暫時只支持把 Boot_Reason 賦值為 BOOT_APP 後跳轉回 BM。
四、操作流程
1、使用 SDTOOLBOX 燒入程序(本次燒入工程只用來驗證 BM 搬運 APP 後,並執行跳轉入 APP 的操作)
① 使用 CMD 命令 .\tools\mcal_genpac.exe -p E3_ref_176_E3210 -v IAR -f norflash 生成 PAC
② 單擊 convert_MCAL.bat 腳本生成 merged.bin.rsa2048.signed 文件
(3)下載驗證
① 打開 SDFactoryTool 選擇 pac
② 打開 Setting 將 OSPI_BOOT0 選擇 merged.bin.rsa2048.signed
③ E3210 開發板 Mode 選擇 1000(USB 下載模式),單擊 Start downloading 下載程序
④ 開發板 Mode 選擇 0000(代碼從Flash 啟動),重新上電串口列印 BM -> APP,串口 log 如下圖
五、參考文檔
參考:《SemiDrive_E3_MCAL_FUSA_User_Guide_Rev00.03》
參考:《E3210_MCU_Datasheet_Rev01.00》
參考:《E3210_MCU_TRM_Rev01.00》
參考:《AppNote_E3_Boot_and_OTA_Rev01.06》
評論