您好!
我正在尝试实现引导加载程序应用程序。
为了开始了解如何执行引导加载、设计了一个用例。 成功完成此简单用例后、可以增强基本功能并针对外部存储器或仿真 EEPROM 进行缩放。 有各种可能性。
用例:
- 将 F021闪存 API 加载到 RAM 中、以获得闪存组0 (主闪存)的擦除/重新编程访问权限。
- 擦除闪存组0中的扇区、以验证 F021是否加载到 RAM 中。
- 使用 F021使用同一闪存组中另一个扇区的数据对扇区进行重新编程。
我正在使用 TI 提供的引导加载程序示例。
我迄今采取的步骤:
- 链接器文件中的"sys_link.cmd"
内存 { /*扇区0 */ 矢量 (x) :O=0x00000000 l=0x00001000 BOOT_LOAD (RX):o=0x00001000 l=0x00001000 //引导加载程序位于此处*/ FLASH_API (RX):o=0x00002000 l=0x00002000 // F021 API 驻留在此处*/ /*扇区1..14 */ FLASH0 (Rx):O=0x00004000 l=0x0011BFFF /*扇区15 */ Flash_copy (RX):o=0x00120000 l=0x0001FFFF f=0x5A5A5A 堆栈 (RW):o=0x08000000 l=0x00010500 RAM (RW):o=0x08010500 l=0x0001fb00 //用户代码开始(2)*/ *用户代码结束*/ }
部分
{
.intvecs:{}>向量
.text :{}>FLASH0
.const :{}>FLASH0
.cinit :{}>FLASH0
.pinit :{}>FLASH0
.bss :{}> RAM
.data :{}> RAM
sysmem :{}>RAM
/*用户代码开始(4)*/
BOOT_LDR:{sys_core_AFw.obj (.text)}> boot_load
eabi_start:{sys_startup_AFw.obj (.text)}> boot_load
FLASH_API:
{
fapi_usr_func.obj (.text)
bl_flash.obj (.text)
l F021_API_CortexR4_be_V3D16.lib (.text)
}
LOAD = FLASH_API、
运行= RAM、
LOAD_START (API_LOAD)、
RUN_START (API_RUN)、
load_size (api_size)
/*用户代码结束*/
}
- 在启动序列中(sys_startup.c 和 sys_core.asm)
-
- 在_coreInitRegisters_函数结束时、CPU 被切换回监控器模式。
-
… ;切换到未定义指令模式(M=11011) CPS #27 MOV LR、r0 R1女士、CPSR MSR spsr_cxsf、R1 ;切换到系统模式(共享用户模式寄存器)(M = 11111) CPS #31 MOV LR、r0 R1女士、CPSR MSR spsr_cxsf、R1 ;切换回 Supervisor 模式(M=10011)-引导加载程序 CPS #19 MOV LR、r0 R1女士、CPSR MSR spsr_cxsf、R1 ;ARM 模式- cortex R4手动 ARM DDI 0363G p.56
-
-
- 之后、我使用 MPU 访问控制寄存器授予完全读取/写入数据权限、如 Cortex-R4F 技术参考手册第126页(ARM DDI 0363G、ID041111;第126/436页)中所述
-
;MPU cortex R4 ARM DDI 0363G 第184页 MRC P15、 0x00、 R2、 c1、c0、#0x02 ORR R2、 R2、 0xF00000 MCR P15、 0x00、 R2、 c1、c0、#0x02 MOV R2、 0x40000000 fmxr fpexc、R2 ;读/写完全访问 ARM DDI 0363G 第126页 MRC P15、 0x00、 R2、 C6、C1、#0x04 MOV R2、 0x03 MCR P15、 0x00、 R2、 C6、C1、#0x04 MOV R2、 0x40000000 fmxr fpexc、R2
-
- 闪存在管线模式中被初始化以实现160MHz 的读取/写入(SPNU515C;第288页)。
- 闪存在管线模式中被初始化以实现160MHz 的读取/写入(SPNU515C;第288页)。
/**-设置闪存读取模式、地址等待状态和数据等待状态*/ flashWREG->FRDCNTL = 0x000000000000 |(UINT32)((UINT32) 3U << 8U) |(uint32)((uint32) 1U <<4U) | 1U;
- "引导加载程序"
-
- 要在 RAM 中复制闪存 API、我选择了 C 函数而不是汇编语言。 我们公司的 CI 管道可以分析 C 代码、但不能分析汇编代码。 我在另一个 E2E 主题上找到的代码、我没有记下它!
- 我使用 SPNU118W 之后的链接器符号、第8.6.1节 在 C/C++应用中使用链接器符号
- 我在每次函数调用后刷新流水线、即使这不是必需的。
-
extern uint8_t api_load; extern uint8_t api_run; extern uint8_t api_size; // f021 API 以 u32字表示的大小*/ #define API_U32_word_count (uint32_t)((uint32_t)(&api_size)/ sizeof (uint32_word_)* 要 定义闪存地址/#int32_t)*要定义的地址 0x00120000 #define ADDR_FLASH_API 0x00002000 /*闪存-组0、EEPROM -组7 */ #define Bank_0 0U #define Bank_7 7U #define Bank_0_Sector_15 0x8000U void fn_copy_api_to_ram (uint8_t * p_load、uint8_t * p_start、uint32_t u32_size) { 操作 { *p_start =*p_load; P_START++; P_LOAD++; } while (--u32_size); return; } void fn_updateer_util (void) { /*首先将闪存 API 复制到 RAM **以便写入闪存组0 */ fn_copy_api_to_ram ((uint8_t*)&api_load、(uint8_t*)&api_run、(uint32_t)&api_size); uint32_t u32_fapi_res =(uint32_t) 0U; u32_fapi_res = Fapi_initializeFlashBanks (SYS_CLK_FREQ); u32_fapi_res = Fapi_setActiveFlashBank (Bank_0); u32_fapi_res = Fapi_enableMainBankSecors (Bank_0_Secto_15); while (fapi_check_FSM_ready_busy!= fapi_Status_FsmReady); while (fapi_get_FSM_status!= fapi_Status_Success); u32_fapi_res = Fapi_issue19 CommandWithAddress (Fapi_EraseSector、(uint32_t*) ADDR_FLASH_COPY); fapi_flushPipeline(); while (fapi_check_FSM_ready_busy =fapi_Status_FsmBusy); while (fapi_get_FSM_status!= fapi_Status_Success); u32_fapi_res = fapi_get_FSM_status; u32_fapi_res = Fapi_initializeFlashBanks (SYS_CLK_FREQ); u32_fapi_res = Fapi_setActiveFlashBank (Bank_0); u32_fapi_res = Fapi_enableMainBankSecors (Bank_0_Secto_15); while (fapi_check_FSM_ready_busy!= fapi_Status_FsmReady); while (fapi_get_FSM_status!= fapi_Status_Success); uint8_t u8_dum_buff [4]={0xBA、0xD0、0xBA、0xD0}; u32_fapi_res = fapi_issueProgrammingCommand (((uint32_t *) ADDR_FLASH_COPY、 u8_dum_buff [0]、 4、 0U、 0U、 Fapi_AutoEccGeneration); while (fapi_check_FSM_ready_busy =fapi_Status_FsmBusy); u32_fapi_res = fapi_get_FSM_status; 返回; }
我面临的问题:
使用调试器时,如果我单步执行 Fapi_issuedCommandWithAddress()函数,它将正常工作,并且我可以在内存浏览器中看到已擦除的闪存。 如果我在函数之后设置一个断点、并在程序开始时按 Resume Execution、则会导致预取尝试。
2.当我单步执行 fapi_issueProgrammingCommand()的汇编代码时,它可以正常工作,并且重新编程新擦除的闪存! 当我尝试单步执行函数时、它会导致预取。
我不知道如何继续下去,这证明是一个阻挡者。 提前感谢您!
此致、
米哈伊尔

