【发布时间】:2016-12-03 14:19:42
【问题描述】:
我正在为使用相对复杂的通信接口的 ARM Cortex-M3 编写引导加载程序;这与实际应用程序使用的相同。该应用程序使用 Keil 的 RTX 作为其内核,而通信堆栈依赖于此。当然是使用 GCC。
引导加载程序执行以下基本步骤:
- 在启动时,检查有效的应用程序图像;如果没有可用,则进入升级模式;
- 它检查按钮按下作为进入升级模式的请求;如果发现,则进入升级模式。
- 找到有效映像且没有升级请求后,它会“启动”应用程序。
这是相当简化的,但它充分描述了我们的目的。
令人惊讶地证明困难的最后一个问题是启动应用程序。想法是禁用中断,设置向量表,堆栈指针,并跳转到新向量表中的应用程序的重置向量。所有这一切都很顺利,只是此后不久,我遇到了一个硬故障。
通过实验,如果我在一个简单的引导加载程序(不使用 RTX,当然也不使用通讯堆栈)中执行此操作,应用程序的引导工作正常。所以看来 RTX 是问题所在。
问题是,真正的引导加载程序在进入升级模式之前不需要 RTX。因此,显而易见的方法是在确定需要 RTX 之前不要启动它;但是,它似乎被黑进了启动代码,所以当我进入引导加载程序代码时,为时已晚;事实上,bootloader main() 函数已经是一个线程了!
最好的方法似乎是在需要之前不启动 RTX(太糟糕了,我没有使用过 FreeRTOS!);但是,这似乎需要一些黑客攻击。另一种方法是以某种方式禁用所有中断和异常,但由于某种原因,我在那里也没有成功。有人有这两种方法的例子吗?
【问题讨论】:
-
所以引导加载程序和应用程序都是基于 RTX 的?如果是这样,我觉得最好的选择可能是彻底改变计划 - 将所有内容链接到一个程序中,将初始检查作为启动任务运行,然后启动“升级”或“应用程序”任务作为合适的。这也应该通过不在单独的“引导加载程序”和“应用程序”图像之间复制“相对复杂”的通信代码来节省您的闪存空间。
-
似乎需要从 RAM 或类似的地方运行,并覆盖引导加载程序(因为它是正在上传的应用程序的一部分!);恐怕这会使系统变得过于僵化。但有趣的想法。显然,当我说“相对复杂”时,我误导了您;虽然它很复杂,但它并不是特别大 - 我的引导加载程序大约 20 KB,我的应用程序是 80 KB,设备有 1 MB!