Write interrupt safe function
如何保证主函数被中断函数打断后正常运行? 先看如下的例子:
static volatile uint8_t g_ucIntCnt = 0;
void RTC_ISR(void) interrupt 5
{
g_ucIntCnt++;
}
void loop(void) | void loop(void)
{ | {
while (1) | while (1)
{ | {
do_something1(); | do_something1();
|
if (g_ucIntCnt == 100) | if (g_ucIntCnt >= 100)
{ | {
do_something2(); | do_something2();
} | g_ucIntCnt = 0;
| }
g_ucIntCnt = 0; |
do_something3(); | do_something3();
} | }
} | }
void main(void)
{
init();
loop();
}
请思考一下,程序中的 do_something2 会按预期每隔 100 个 rtc 单位运行一次吗?
左边的代码中:
- 由于 do_something1 的代码复杂度未知,很大概率无法撞上 g_ucIntCnt = 100 的条件;
- 另一方面,如果 do_something1 很短,在主循环中,在 g_ucIntCnt 还很小时过早清 0,也会导致无法满足条件;
- 即使刚好凑巧,可以运行到 do_something2,假如函数内部有用到 g_ucIntCnt 也会导致程序错误。
右边的代码中:
- 如果 do_something1 过于复杂,导致运行完之后 g_ucIntCnt 已经溢出,也无法运行 do_something2;
- 同样有左边代码 3 的问题。
static volatile uint8_t g_ucIntCntFlag = 0;
void RTC_ISR(void) interrupt 5
{
static volatile uint8_t g_ucIntCnt = 0;
if (++g_ucIntCnt > 100)
{
g_ucIntCnt = 0;
g_ucIntCntFlag = 1;
}
}
void loop(void)
{
while (1)
{
do_something1();
if (g_ucIntCntFlag)
{
do_something2();
g_ucIntCntFlag = 0;
}
do_something3();
}
}
void main(void)
{
init();
loop();
}