c - 在 FreeRTOS 第一个任务运行期间,第二个固件插槽跳转到第一个插槽

标签 c assembly embedded freertos

我创建了一个应用程序,它的内存映射中有 2 个固件插槽。它工作得很好,两个插槽都根据存储在闪存中的 32 位序列号正确执行。

当我尝试使用 FreeRTOS 时出现问题。默认情况下,固件是为第一个插槽编译的……运行这个插槽没有任何问题。但是,当设备启动保存在第二个插槽中的固件时,当 RTOS 在 prvPortStartFirstTask 中启动其第一个任务,然后跳转到 vPortSVCHandler 时,它会切换到第一个插槽中的任务。

我做错了什么?我认为函数地址在编译后是相对的,所以用 2 个固件插槽运行这个应用程序应该没有困难。


编辑

我从bootloader切换到main application的流程如下: 1. 检查应使用哪个固件插槽。 2. 禁用 IRQ。 2. 将 vector 表复制到 RAM。这两个插槽的 RAM 部分相同。在复制过程中,我正在更改每个地址的偏移量,因此它们将与特定的固件插槽兼容。默认地址没有偏移量,它在编译后阶段被删除。 3. 根据RAM 中 vector 表的第一个字设置堆栈指针。将 vector 表复制到 RAM 时,该地址不会更改。 4. 设置 SCB->VTOR。 5. 执行数据同步屏障 DSB()。 6. 从复制到 RAM 的 vector 表跳转到 Reset Handler。


编辑 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 .

最佳答案

通常不会构建固件 position independent ,所以我不相信所有“函数地址在编译后都是相对的”。您为特定的起始位置(第一个或第二个固件插槽)编译固件。

至于您的主要问题,您是否做过任何事情来将中断处理程序/中断 vector 从一个固件插槽切换到另一个固件插槽?还是在调用 SVC 处理程序时跳转到第一个固件的中断处理程序?

如何更改中断 vector 因体系结构而异。对于 stm32f429,您也许可以查看 here

关于c - 在 FreeRTOS 第一个任务运行期间,第二个固件插槽跳转到第一个插槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50554221/

相关文章:

linux - 停止 qt 写入/dev/tty0

assembly - xchg 如何在英特尔汇编语言中工作

c - 是否可以通过内联汇编访问硬件寄存器

c - 指向链表开头的指针

c - Scanf() 与格式说明符中提供的\n 和 '\n' 的工作方式不同

c - 硬件如何知道一个变量是正数还是负数?

c - 使用 DMA 提高 SPI6 的性能

c - 如何在仅支持常量表达式的函数中使用变量作为参数

c - 使用 libcurl 从特定 URL 接收垃圾数据

c - 将指针(矩阵)传递给c中的函数