本小节介绍另一种对共享资源访问的完全不同的处理机制。
这种方式改变了资源访问模式,从”资源共享”变成”资源独享”,从而避免了共享造成的问题。
主要内容
本小节所介绍的方法不仅适用于任务与中断共享资源,也适用于任务之间、中断之间共享资源。
此种方法可以简而言之描述为:让某任务/中断享有对资源的所有权,其它任务中断需要访问资源时必须发起请求。然后由资源所有者完成访问,再将结果告之给发起请求的一方。
视频中,我们使用这种方式解决本章开头所提示的问题。
使用这种方式,可以看到不存在资源共享,也就需要使用前面所提到的各种资源保护机制。在编写读写资源的代码时,也就简单很多了。
重点难点
需要自行编写通信机制
使用这种方式,需要使用某种通信机制,在请求方和资源所有者之间通信,传递请求和访问结果。
RTOS提供了这种通信机制:邮箱/消息队列;但我们还需要根据实际应用特点,定制请求命令及其处理流程代码等。
示例中定义了删除结点的命令,然后通过邮箱传递给任务1,再由任务1具体处理。这样在任务1中调用listPrint时,就需要再进行保护。
/**
* 高优先级中断处理函数
*/
void IRQHighHandler (void) {
// 在中断中,可能会访问链表,然后对链表进行一些修改操作
// 比如删除第1个。而如果此时任务恰好在访问第1个结点,则会链表访问混乱,出现错误
//tListRemoveFirst(&list);
**tMboxNotify(&cmdMbox, (void *)CMD_REMOVE_FIRST, tMBOXSendNormal);**
}
/**
* 任务的运行代码
* @param param 任务初始运行参数
*/
void task1Entry (void *param) {
listInit();
listPrint();
for (;;) {
uint32_t err = 0;
void * cmd = 0;
task1Flag = 1;
tTaskDelay(1);
task1Flag = 0;
tTaskDelay(1);
**err = tMboxNoWaitGet(&cmdMbox, &cmd);**
if (err == tErrorNoError) {
if ((uint32_t)cmd == CMD_REMOVE_FIRST) {
tListRemoveFirst(&list);
}
}
}
}