我已经为预取中止操作困扰了几天了。 根据文档、 预取中止与指令提取而非数据访问相关联。 当发生预取中止时、处理器将预取指令标记为无效、但在执行该指令之前不会接收到异常。
我们已安装 TMS570引导加载程序应用。 当我们安装 BareMetal 用户应用程序时、加载过程非常有效、但当我们安装 SafeRTOS 用户应用程序时、所有这些都会松散。 当 SAFERTOS 用户应用程序未使用引导程序时(例如、我们在0000_0000处启动程序时)、它会按预期工作。
这是我的 bootloader 程序的内存映射:
MEMORY { VECTORS (X) : origin=0x00000000 length=0x00000080 FLASH_API (RX) : origin=0x00000080 length=0x000014E0 FLASHBOOT (RX) : origin=0x00001560 length=0x0007EB00 STACKS (RW) : origin=0x08000000 length=0x00002000 RAM (RW) : origin=0x08002000 length=0x0003E000 }
这是我的引导加载程序 矢量表(sys_intvecs.asm)文件:
.sect ".intvecs" .arm ;------------------------------------------------------------------------------- ; import reference for interrupt routines .ref _c_int00 .ref _dabort .def resetEntry ;------------------------------------------------------------------------------- resetEntry ; Since the user application starts @ 0x00020000, so each interrupt ; entry needs to be set to 0x1FFF8 which is 0x00020000 - 0x8. Basically ; when an interrupt occurs, the interrupt vector table will force the ; PC to jump to the appropriate location in flash that was set by the ; user application. b _c_int00 ;0x00 b #0x1FFF8 ;0x04 ; ; vUndefAbort on User Application b #0x1FFF8 ;0x08, Software interrupt ; vSafeRTOSSVCHandler on User Application b #0x1FFF8 ;0x0C, Abort (prefetch) ; vPrefetchAbort on User Application b #0x1FFF8 ;0x10, Abort (data) ; vDataAbort on User Application reservedEntry b #0x1FFF8 ;phantomInterrupt on User Application ldr pc,[pc,#-0x1b0] ldr pc,[pc,#-0x1b0] ;-------------------------------------------------------------------------------
在我的可引导式 SAFERTOS 用户应用程序中、有以下存储器映射:
MEMORY { VECTORS (X) : origin=0x00020000 length=0x00000080 KERN_FUNC (RX) : origin=0x00020080 length=0x0000FF80 FLASH0 (RX) : origin=0x00030000 length=0x0010FFFF STACKS (RW) : origin=0x08000000 length=0x00001800 KERN_DATA (RW) : origin=0x08001800 length=0x00000800 RAM (RW) : origin=0x08002000 length=0x0002C000 }
这是我的矢量表:
.sect ".intvecs" .arm ;------------------------------------------------------------------------------- ; import reference for interrupt routines .ref _c_int00 .ref vUndefAbort .ref vSafeRTOSSVCHandler .ref vPrefetchAbort .ref vDataAbort .ref phantomInterrupt .def resetEntry ;------------------------------------------------------------------------------- ; interrupt vectors resetEntry b _c_int00 b vUndefAbort b vSafeRTOSSVCHandler b vPrefetchAbort b vDataAbort b phantomInterrupt ldr pc,[pc,#-0x1b0] ldr pc,[pc,#-0x1b0]
当用户应用程序运行且发生预取中止时、相关 CP15将变为:
Cp15_CP15_AUX_DIRECTOR_FAULT_STATUS = 0x00400000
Cp15_CP15_instruction_fault_address = 0x0005409C
此故障地址位于 vPortIdleHook 函数中:
我认为、当应用程序调用闪存地址0005_4098上的服务调用指令(SVC #4)时会出现此问题。 该指令将分支到0000_0008 (软件中断)、我的引导加载程序矢量表将立即发出到0002_0008的跳转。 这一切都是合法的,我看到正在跳。
0002_0008包含 SafeRTOS SVC 处理程序、当我逐步执行它时、我可以看到已读取并发送了正确的服务编号(#4)。
SVC 正在退出、有一条指令在执行时获得预取中止。
_vPortSVC_exit: LDMFD SP!, { R4, R5, PC }^ ; Pop saved R4 and R5, and the LR into the PC to return
在执行该行之前、以下是我的完整寄存器导出:
执行该行后、以下是我的完整寄存器导出:
在这两个文件中、我们可以清楚地看到 Cp15_CP15_AUX_DIAG_FAULT_STATUS 和 Cp15_CP15_DIRECTOR_FAULT_ADDRESS 更改。
通过单步执行代码、我们可以清楚地看到从0002_71cc 到0000_000c、然后在发生该预取中止时变为0002_000c 的流程。
如前所述、当 用户应用程序从0000_0000开始时、绝对没有问题。
如果能 深入了解如何解决此问题以及发生预取中止的原因、我将非常感激。