我已经为预取中止操作困扰了几天了。 根据文档、 预取中止与指令提取而非数据访问相关联。 当发生预取中止时、处理器将预取指令标记为无效、但在执行该指令之前不会接收到异常。
我们已安装 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开始时、绝对没有问题。
如果能 深入了解如何解决此问题以及发生预取中止的原因、我将非常感激。


