我创建了一个应用程序,其内存映射中有2个固件插槽。它工作得很好,两个插槽都是根据存储在FLASH中的32位音序器编号正确执行的。
当我尝试使用FreeRTOS时出现问题。默认情况下,会为第一个插槽编译固件...并且运行此插槽没有任何问题。但是,当设备启动保存在第二个插槽中的固件时,当RTOS在 prvPortStartFirstTask 中启动其第一个任务时,然后跳转到 vPortSVCHandler ,它将切换到第一个插槽中的任务。 / p>
我做错了什么?我认为编译后函数地址是相对的,因此使用2个固件插槽运行此应用程序应该没有困难。
修改
从引导加载程序切换到主应用程序时的流程如下: 1.检查应使用哪个固件插槽。 2.禁用IRQ。 2.将向量表复制到RAM。两个插槽的RAM部分相同。在复制过程中,我正在更改每个地址的偏移量,因此它们将与特定的固件插槽兼容。默认情况下,地址没有偏移量,在后编译阶段将其删除。 3.根据RAM中向量表中的第一个字设置堆栈指针。将向量表复制到RAM时,不会更改该地址。 4.设置SCB-> VTOR。 5.执行数据同步屏障DSB()。 6.从复制到RAM的向量表中跳转到复位处理程序。
编辑2
当我将具有更改的FLASH存储器地址范围的应用程序编译到辅助插槽时,它可以正常工作。 是否有可能编译代码使得应用程序将独立于PC,至少它会在那种情况下起作用?
编辑3
# Generate position independent code.
-fPIC
# Access bss via the GOT.
-mno-pic-data-is-text-relative
# GOT is not PC-relative; store GOT location in a register.
-msingle-pic-base
# Store GOT location in r9.
-mpic-register=r9
但是,现在这个插槽停止工作了。
我认为我的问题类似于one。
答案 0 :(得分:1)
通常情况下,固件不是position independent构建的,所以我不相信所有的#34;函数地址在编译后都是相对的"。您可以编译特定起始位置(第一个或第二个固件插槽)的固件。
至于你的主要问题,你有没有把中断处理程序/中断向量从一个固件插槽切换到另一个?或者您在调用SVC处理程序时跳转到第一个固件的中断处理程序?
如何更改中断向量因架构而异。对于stm32f429,您可能看起来here