由于 MSP430F2013上的闪存数量有限 、我的引导加载程序(位于闪存的上限1K)处理一些低级 I2C 功能并将执行传递给应用(位于闪存的下限1K)。 使用常规函数调用传递执行。
要在中断退出时更改电源状态、应用需要在退出时更改 SR 寄存器的状态以进行中断。 为此、我分配了一个变量 SR_ADDRESS_ON_EXIT (地址0x027C)、该变量在引导加载程序和应用程序之间共享。 在引导加载程序调用应用程序之前、它会将"堆栈" SR 寄存器的地址写入 0x027C。 如果应用程序需要在退出时更改电源状态、它将从 0x027C 中获取存储 SR 的地址、并根据需要进行更新。
问题是确定 SR 在堆栈上的位置。 调用 __get_SR_register_ON_EXIT ()会返回 SR 寄存器的"中断退出"值。
调用__get_sp_register()将返回当前值,而不考虑帧大小(在中断开始时调用 push.W)。
一种方法是用汇编语言编写 ISR、此时这是不可行的。
最好具有一个内在函数__get_sp_on_exit (),该函数将返回 SP 的值+"push.W 调用添加的任何内容"。
是否可以使用当前工具在堆栈上获取 SR 地址而不在汇编语言中写入整个 ISR?
2.另一种方法是 调用 __get_SR_register_ON_EXIT ()并将 SR 值保存在共享位置。 如果需要、应用程序将更新共享位置的值。 返回到引导加载程序后、来自共享位置的值应写入栈上的 SR 值。 在汇编语言中、它可以用一条指令来完成。 由于__set_SR_ON_EXIT (val)不存在,我必须进行两次调用:
__bic_SR_register_on_exit(~sr_value_on_exit);
__bis_SR_register_on_exit(sr_value_on_exit);
这些将展开为四条指令:
MOV.W &sr_value_on_exit+0,r15
INV.W r15
BIC.W r15,10(SP)
BIS.W &sr_value_on_exit+0,10(SP)
任何使编译器生成指令的方法:
MOV.W &sr_value_on_exit+0,10(SP)
自动? 这会将4条指令替换为仅1条指令(节省一些闪存空间和执行时间)。