我定义了一个ISR来触发外部中断。外部中断可能并不总是被启用,但在某些情况下,我希望能够在主代码中注册一个在中断内调用ONCE的函数。在下一次中断之前,该函数可能被另一个函数替换或删除。
我对PIC32上的同步技术了解不多,但我想出了以下内容:
volatile BOOL callbackInterrupted = FALSE;
volatile BOOL callbackWritten = FALSE;
void (*myCallback)() = NULL;
void RegisterCallback(void (*callback)())
{
do
{
callbackWritten = FALSE;
myCallback = callback;
}
while(callbackInterrupted);
callbackWritten = (callback != NULL);
}
void interrupt MyExternalInterrupt() @EXTERNAL_1_VCTR
{
// Do a bunch of other things here...
if(callbackWritten)
{
myCallback();
myCallback = NULL;
callbackInterrupted = TRUE;
callbackWritten = FALSE;
}
}
虽然我无法推理它。这实际上是否符合我的期望,即。防止ISR调用半集函数指针,或者调用函数两次? do ... while
循环是多余的吗?还有更好的方法吗?
已添加:禁用此中断是不可能的。它用于计时。
为flag = TRUE
生成的说明:
lui s1,0x0
ori s1,s1,0x1
addiu at,s1,0
or t0,at,zero
为fnc1 = &testfunc
生成的说明:
lui a2,0x9d00
ori a2,a2,0x50
or a1,a2,zero
sw a1,16376(gp)
答案 0 :(得分:2)
假设设置bool是一个原子操作(反汇编和读取手册以确定) - 我会使用一个标志来设置函数指针,但这个标志只能由ISR读取,并且只能由普通代码,给你一个简单的信号量。如果写入函数指针是原子的(再次通过反汇编检查),则可以使用它而不是标志。
像这样(在我的头顶)
void (*myCallback)() = NULL;
void RegisterCallback(void (*callback)())
{
myCallback = callback;
}
void interrupt MyExternalInterrupt() @EXTERNAL_1_VCTR
{
// Do a bunch of other things here...
if (myCallback!=NULL)
myCallback();
myCallback = NULL;
}
修改的 在看到反汇编指令后,使用函数指针作为标志将起作用。修改后的代码以显示用法。
答案 1 :(得分:1)
鉴于ISR存在于时间脉冲的事实,为什么要在ISR中调用该函数呢?为什么不在主代码中调用它,主代码检查脉冲时序的结果?
如果你的答案是关键的代码是在ISR的火上执行的,那么我认为你也有机会在每次执行中断之前设置一个函数来调用。在这种情况下,您唯一的选择是确定在ISR中调用下一个中断的正确函数,或者在确定在代码中的其他地方调用的正确函数时禁用中断。如果时序很关键,你还应该确保这个ISR不会受到更高优先级中断的影响。
答案 2 :(得分:0)
我只使用一个函数指针并检查中断中的非null,调用并将其设置为null。在设置指针的地方,标准解决方案是禁用中断。