本小节介绍另一种对共享资源访问的完全不同的处理机制。

这种方式改变了资源访问模式,从”资源共享”变成”资源独享”,从而避免了共享造成的问题。

主要内容

本小节所介绍的方法不仅适用于任务与中断共享资源,也适用于任务之间、中断之间共享资源。
此种方法可以简而言之描述为:让某任务/中断享有对资源的所有权,其它任务中断需要访问资源时必须发起请求。然后由资源所有者完成访问,再将结果告之给发起请求的一方。
视频中,我们使用这种方式解决本章开头所提示的问题。
请求模式解决任务中断共享资源冲突 - 图1
使用这种方式,可以看到不存在资源共享,也就需要使用前面所提到的各种资源保护机制。在编写读写资源的代码时,也就简单很多了。

重点难点

需要自行编写通信机制

使用这种方式,需要使用某种通信机制,在请求方和资源所有者之间通信,传递请求和访问结果。
RTOS提供了这种通信机制:邮箱/消息队列;但我们还需要根据实际应用特点,定制请求命令及其处理流程代码等。
示例中定义了删除结点的命令,然后通过邮箱传递给任务1,再由任务1具体处理。这样在任务1中调用listPrint时,就需要再进行保护。

  1. /**
  2. * 高优先级中断处理函数
  3. */
  4. void IRQHighHandler (void) {
  5. // 在中断中,可能会访问链表,然后对链表进行一些修改操作
  6. // 比如删除第1个。而如果此时任务恰好在访问第1个结点,则会链表访问混乱,出现错误
  7. //tListRemoveFirst(&list);
  8. **tMboxNotify(&cmdMbox, (void *)CMD_REMOVE_FIRST, tMBOXSendNormal);**
  9. }
  10. /**
  11. * 任务的运行代码
  12. * @param param 任务初始运行参数
  13. */
  14. void task1Entry (void *param) {
  15. listInit();
  16. listPrint();
  17. for (;;) {
  18. uint32_t err = 0;
  19. void * cmd = 0;
  20. task1Flag = 1;
  21. tTaskDelay(1);
  22. task1Flag = 0;
  23. tTaskDelay(1);
  24. **err = tMboxNoWaitGet(&cmdMbox, &cmd);**
  25. if (err == tErrorNoError) {
  26. if ((uint32_t)cmd == CMD_REMOVE_FIRST) {
  27. tListRemoveFirst(&list);
  28. }
  29. }
  30. }
  31. }

在课程的最后综合实际中,还可以看到这种方法的具体使用。

注意事项

常见问题