无论是开关全局中断还是关指定中断,都会对中断的响应时间造成影响。
关中断的时间越长,中断被延迟响应的时间也越长,所以在编写代码时,要尽可能地保护关中断的时间要尽可能地短。但是有时会发现,任务或低优先级中断访问资源的时间较长,此时我们需要调整代码,缩短关中断时间。
主要内容
提取耗时操作
这种思路简而言之是:调整代码,优化访问资源的时间,将部分耗时的操作从原操作中提取出来。。
在之间的示例中,可以看到有个链表遍历。如果单就链表遍历本身来看,其速度还是比较快的,但是由于遍历过程中有使用xprintf打印,如果考虑打印是通过串口输出,那么整个遍历过程将会比较耗时。当结点数量很多,串口的波特率较低时,其耗时就更长。
void listPrint (void) {
uint32_t count = 0;
tNode *currentNode = 0;
// 遍历整个链表,然后打印出各个结点对应的序号
for (currentNode = tListFirst(&list); currentNode != (tNode *) 0; currentNode = tListNext(&list, currentNode)) {
xprintf("Node %d\n", count);
// 假设在此期间,突然发生了中断。由于中断操作了链表,导致再次返回任务时
// 头结点已经从链表中移除。此时,再继续后面的循环发现,
currentNode = tListNext(&list, currentNode) 为0
// 导致没有办法再扫描链表中后面的其它结点
if (count++ == 0) {
interruptByIRQ(IRQ_PRIO_HIGH);
}
}
}
在这种情况下,如果采用关中断的方式,将会导致中断长时间的关闭,产生很大的影响。通过调整代码,我们可以将打印这个耗时操作给提取出来,不在链表遍历过程中执行。这样链表遍历过程就可以快速地执行完毕,从而尽快地让中断执行。
划分为多次开关中断
有时我们会对大块的代码进行开关中断保护,代码块越大,往往执行时间也越多。
但如果对这些大块代码分析可能会发现,并不是所有的代码都涉及到对共享资源的访问。所以有时可以将这些大块代码进行”划分”,将原本对整个大块代码进行开关中断保护,分隔为多块保护。这样就相比之前就允许中断尽可能早的响应。
重点难点
注意事项
注意,视频中我们采用的是用一个数组记录所有结点然后打印,这种处理方式较简单。可考虑采用其它方式记录要打印的结点,比如链表。
此外,在这里只是提供一种解决思路,示例问题仅是用来演示这种思路的应用,示例功能本身并没有什么意义,无需关注。