0

我将软件分为两部分:引导加载程序(不带 RTX)、带 RTX 的应用程序映像。但是引导加载程序无法使用 RTX 加载应用程序映像。Flash 设置如下:

-------------------------------------------------- ------------------
        起始地址大小
IROM 1: 0x08000000 0x2800 - 引导加载程序(无 RTX)
IROM 2:0x08002800 0xD000 - 应用程序映像(带有 RTX)

我测试了 3 种方法:(1)使用另一个没有 RTX 的应用程序。引导加载程序可以成功加载应用程序。

(2) 使用 RTX 项目 IROM 设置更改应用程序。我将应用程序项目 IROM 起始地址从 0x08002800 更改为 0x08000000。我将应用程序映像从地址 0x08000000 下载到闪存中。图像可以从 0x08000000 成功运行。

(3) 应用映像 IROM 起始地址设置为 0x08002800。将bootloader和app镜像下载到flash后,我在keil中一步步调试app项目。我发现有一个“osTimerthread 堆栈溢出”错误。然后主线程栈也溢出了。我试图增加堆栈大小,但它不起作用。我发现该应用程序在 RTX 内核切换中表现得很明显。所有线程都处于等待状态,并且没有运行。

ps,我在keil调试的时候,test item(2)在内核初始化的时候也会出现栈溢出错误。item(2) 到目前为止工作正常。所以我只是把任何需要的信息放在这里。

这是第(3)项的调试图片。 在此处输入图像描述

4

1 回答 1

0

您实际上是0x08002800在使用引导加载程序时将链接描述文件更改为开始链接,还是仅0x08000000在偏移量处加载应用程序(链接在)0x2800?仔细检查此(查看地图文件)以获取链接输出,以确保您的所有符号都未链接在该0x08000000 - 0x08002800范围内。

此外,请确保您使用正确的入口点和堆栈指针。应用程序的堆栈指针应该是 at 0x08002800,而复位向量应该是 at 0x08002804MSP在跳转到应用程序之前,您的引导加载程序需要使用正确的堆栈指针设置寄存器。以下是 ST 的 USB DFU 引导加载程序的一些示例代码:

typedef  void (*pFunction)(void);
pFunction JumpToApplication;
uint32_t JumpAddress;

/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (USBD_DFU_APP_DEFAULT_ADD + 4);
JumpToApplication = (pFunction) JumpAddress;

/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) USBD_DFU_APP_DEFAULT_ADD);
JumpToApplication();

此外,根据您的引导加载程序在跳转到应用程序之前配置了多少,您可能需要“取消配置”某些外围设备。例如,如果您在决定跳转到应用程序之前在引导加载程序中设置了时钟,如果假定时钟已经处于默认配置中,您可能会在应用程序中遇到问题。如果您的引导加载程序在跳转到应用程序之前使用它们,则 NVIC 和 SysTick 可能会发生类似的事情。

最后,与上一节一样,应用程序可能会假设外围设备的状态为默认,但它也可能会假设外围设备的默认值是正确的。例如:SCB->VTOR有一个默认值(我相信它总是0x00000000),并且这个指向向量表。您的引导加载程序将被链接以在该位置拥有其向量表。您需要确保当您的应用程序启动时,它会更新VTOR寄存器以指向其向量表的实际位置。

希望这些部分之一可以帮助您识别问题。

于 2016-09-02T13:10:04.863 回答