无论是开关全局中断还是关指定中断,都会对中断的响应时间造成影响。

关中断的时间越长,中断被延迟响应的时间也越长,所以在编写代码时,要尽可能地保护关中断的时间要尽可能地短。但是有时会发现,任务或低优先级中断访问资源的时间较长,此时我们需要调整代码,缩短关中断时间。

主要内容

本课时只是介绍两种思路,在具体的应用中请根据实际情况调整。

提取耗时操作

这种思路简而言之是:调整代码,优化访问资源的时间,将部分耗时的操作从原操作中提取出来。
在之间的示例中,可以看到有个链表遍历。如果单就链表遍历本身来看,其速度还是比较快的,但是由于遍历过程中有使用xprintf打印,如果考虑打印是通过串口输出,那么整个遍历过程将会比较耗时。当结点数量很多,串口的波特率较低时,其耗时就更长。

  1. void listPrint (void) {
  2. uint32_t count = 0;
  3. tNode *currentNode = 0;
  4. // 遍历整个链表,然后打印出各个结点对应的序号
  5. for (currentNode = tListFirst(&list); currentNode != (tNode *) 0; currentNode = tListNext(&list, currentNode)) {
  6. xprintf("Node %d\n", count);
  7. // 假设在此期间,突然发生了中断。由于中断操作了链表,导致再次返回任务时
  8. // 头结点已经从链表中移除。此时,再继续后面的循环发现,
  9. currentNode = tListNext(&list, currentNode) 0
  10. // 导致没有办法再扫描链表中后面的其它结点
  11. if (count++ == 0) {
  12. interruptByIRQ(IRQ_PRIO_HIGH);
  13. }
  14. }
  15. }

在这种情况下,如果采用关中断的方式,将会导致中断长时间的关闭,产生很大的影响。通过调整代码,我们可以将打印这个耗时操作给提取出来,不在链表遍历过程中执行。这样链表遍历过程就可以快速地执行完毕,从而尽快地让中断执行。
优化缩短关中断的时间 - 图1

划分为多次开关中断

有时我们会对大块的代码进行开关中断保护,代码块越大,往往执行时间也越多。
但如果对这些大块代码分析可能会发现,并不是所有的代码都涉及到对共享资源的访问。所以有时可以将这些大块代码进行”划分”,将原本对整个大块代码进行开关中断保护,分隔为多块保护。这样就相比之前就允许中断尽可能早的响应。
优化缩短关中断的时间 - 图2

重点难点

注意事项

注意,视频中我们采用的是用一个数组记录所有结点然后打印,这种处理方式较简单。可考虑采用其它方式记录要打印的结点,比如链表。
此外,在这里只是提供一种解决思路,示例问题仅是用来演示这种思路的应用,示例功能本身并没有什么意义,无需关注。

常见问题