我已经将主存储器分成了引导加载程序和应用程序区域。 希望尝试将中断矢量移动到 RAM 以执行具有尽可能平滑和清晰的中断的引导加载程序。
我已经搜索了这方面的真实示例; 使用 SYCTL 中的 SYSRIVECT 位将中断向量移动到 RAM。 有没有人具有旧的应用手册或示例(预填了 IAR 示例、但不是必需的)? 我找到了一条链接、但自2021年以来就已失效!!
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
我已经将主存储器分成了引导加载程序和应用程序区域。 希望尝试将中断矢量移动到 RAM 以执行具有尽可能平滑和清晰的中断的引导加载程序。
我已经搜索了这方面的真实示例; 使用 SYCTL 中的 SYSRIVECT 位将中断向量移动到 RAM。 有没有人具有旧的应用手册或示例(预填了 IAR 示例、但不是必需的)? 我找到了一条链接、但自2021年以来就已失效!!
如果您有链接(URL)、请尝试使用 Wayback Machine。
亲爱的大卫。 感谢您的输入、但返航机器以某种方式只会在页面被删除时通知我(如网页上显示的内容)。 我缺少什么吗?
我实际上使用了 Chat GPT、了解如何将中断矢量从只读存储器移动到 MSP430器件上的 RAM (但不使用 SYSRIVECT)
这是它产生的结果。 不是一个代码示例、但具有非常好的参考指令
在 MSP430微控制器中、默认情况下、中断矢量表通常位于只读存储器(ROM)中。 但是、在某些情况下、可能需要将中断矢量表移动到 RAM。 以下是操作方法:
1)禁止中断:在将中断向量表移至 RAM 之前、请务必禁用中断、以防止该过程中出现任何潜在的中断。 您可以通过清除状态寄存器中的 GIE (全局中断使能)位来实现这一点。
2)将中断矢量表复制到 RAM:使用存储器复制例程将中断矢量表从其在 ROM 中的原始位置复制到 RAM 中的新位置。 您可以在 C 中使用 memcpy()函数,或编写自己的内存复制例程。 新位置应位于 RAM 中、并且必须在2字节边界上对齐。
3)设置中断矢量表指针:一旦将中断矢量表复制到 RAM、就需要更新 IV (中断矢量)寄存器以指向新位置。 IV 寄存器是用于保存中断向量表地址的16位寄存器。 若要将其设置为 RAM 中的新位置、只需将新位置的地址写入 IV 寄存器即可。
4)重新启用中断:在中断矢量表已成功移至 RAM 并且 IV 寄存器已更新后、您可以通过设置状态寄存器中的 GIE 位来重新启用中断。
注意:请注意、将中断矢量表移动到 RAM 可能会影响系统的中断响应时间、因此应该小心谨慎。 此外、重要的是要确保在正常程序执行期间、RAM 中的新位置不会被覆盖。
我明白你的观点。 我认为 IAR 的工作方式与 CCS 类似、自上而下进行分配。 不过、该表是作为第一件事定义和分配的、但原则上该 区域可以被覆盖-但除非我在引导加载程序中直接设置了一些愚蠢的内容、否则您如何看待这种情况。 我想我可以通过更改链接器文件来减小堆栈能够分配/使用的 RAM 空间。 这样一来、就需要一个额外的安全构建(假设我能够/并且能够处理堆栈之外的存储器区域)?
我不知道您的引导加载程序是如何工作的、因此可能通过某种方式避免了这一切。
查看(仅限)在.c 文件时、我认为该示例是偶然发生的。 它只启用一个中断、并且 main ()在 LPM0中永久停止、所以我怀疑中断堆栈没有完全到达(覆盖)内存中的定时器中断矢量字;如果你试图在实际的程序中使用它、这个方法会失败。 (一个测试用例是在 main ()中定义一个本地80字节的数组并填充0xFF、然后查看计时器中断是否仍然有效。)
在 CCS 中、我将更改链接器文件以将 RAM 存储器段分成两个部分、将高端部分切换到一个新段、例如 RAMIVEC、以使堆栈(">RAM (HIGH)")不会放在那里。 我已经很长时间没有使用 IAR、但我模糊地回忆起项目属性中的一个存储器映射窗口、在这个窗口中、你可以进行类似的操作。
我之前有个项目希望使用引导加载程序、因此我对此作了更详细的思考。
所有这一切都从复位矢量开始。 这必须始终指向引导加载程序代码。 如果您将中断矢量用于应用、则在擦除段和写入矢量之间将有一段时间、在这段时间内、一个字节将使器件砖化。 危险最好避免。
因此、闪存中的中断矢量可由引导加载程序使用。 在引导加载程序中使用中断会带来额外的危险。 为中断配置的任何外设在传输到应用之前都必须被禁用并被清除 GIE。
在 RAM 中为交替向量保留空间非常简单。 链接器脚本通过起始地址和长度定义 RAM。 只需将长度减少0x80即可。 (另一种复杂的方法是在 main()中分配128字节的数组。 这将被放置在堆栈上。 只是要确保不要使用它,并且在 main ()中没有任何其他的自动变量。 堆栈的初始位置恰好在该位置之后。 MSP430是一种预减量类型的 CPU。 请注意、只需要对应用程序代码执行此操作。
另一方面、初始化这些向量需要一些工作。 你可以改变链接器脚本、以便在 RAM 中找到它们、但这是一种浪费。 如果引导加载程序将它们写入此处、它们会在下一次下电上电时消失。 因此、它们需要在应用程序中的某个位置进行初始化。 我认为最简单的方法是将矢量重新定位到复位矢量正下方的段。 0xfd80 - 0xfdff。 编译器将响应代码中常见的 ISR 调用、并将其向量放在那里。 然后、当应用程序启动时、使用 memcpy ()将它们移动到 RAM 中、设置 SYSRIVECT、然后启用中断。
亲爱的大卫-我想你在这里谈到了一件非常重要的事情,我也想到了。 当 MCU 复位时 、我的引导加载程序代码始终是首先启动的。 在这里、我的目的是能够 通过将 IVT 表复制到 RAM 中来使用中断。
但我明白您的观点、即闪存写入周期是否因各种不同的事物(我们正在使用无线模块与应用程序进行通信来传输数据!!)的千分之一而中断。
但如果这种风险很明显,为什么提出解决方案 -我缺少什么吗?. 我看到双映像流程的风险较低、但我/我们没有请求。 空间和这也可以 f... 一切。 引导加载程序中的中断只是一个 NO GO、或者我是否完全误解。
PS:如果我将引导加载程序放置在 IVT 表正下方、并将向量重置到闪存中、如果我确保不擦除或覆盖这些区域、那么在引导加载程序中使用中断会带来什么问题。 另一个问题:我在引导加载程序中的最后一个序列是修复了存储/启动应用程序代码的地址。 为什么我真的需要使用重定位技巧 RAM ?
我在上一次答复中并不完全正确。 这里对我正在进行的确切设置进行了相当好的解释。 www.electronicsforu.com/.../interrupt-bootloader-design-embedded-system-updates
我将更一般的引导加载程序设计推迟到 David、因为我40多年没有编写过引导加载程序(这是用于大型机)。
您链接到的文档似乎非常笼统。 TI 在 SLAA450中具有有关该主题的一些注释:
https://www.ti.com/lit/an/slaa450g/slaa450g.pdf
文档的内部链接的其他工具。