手把手教你学用嵌入式操作系统

  1. 主页
  2. 手把手教你学用嵌入式操作系统
  3. 第4章 任务中断间的同步与通信
  4. 利用全局数据实现数据通信

利用全局数据实现数据通信

内容纲要

本小节开始介绍怎样在任务之间进行数据通信。

前面介绍了各个任务之间在执行流程上的行为同步,除了同步之外,任务之间或者中断与任务之间还有可能出于某些需要进行通信,例如给对方发消息,报告状态等待。

本小节介绍最简单的通信方案,使用全局数据。

主要内容

所谓使用全局数据通信,就是让多个任务共享全局数据。

如下图所求,两个任务需要通信时,前一任务可将要通信的数据写入到全局数据中,另一任务在需要时再进行读取。

但这里可能需要解决几个问题。

全局数据共享

多个任务在共享全局数据时,如前面章节所介绍的,需要使用一些资源共享的保护方案。

根据前面所介绍的内容,可使用关中断、信号量等机制保护。

数据缓存

全局数据可能需要缓存多次写入的值,否则如果只能写入一份,将会导致前面已写入的值被覆盖。

该缓存机制可以使用一些数据结构,比如环形队列、链表,甚至哪怕最简单的数组。

读写同步

需要加入某种通知或等待机制,来实现任务在读写资源时的同步。

例如,任务在需要读取数据时,先等待,直到另一任务发通知后已经写入有效数据后,再读取。

这种通知,可以使用本章所介绍的各种同步方案来实现。

示例

在课程中,我们演示了一个非常简单的例子。

static int count = 0;
static tSem syncSem;

/**
 * 任务的运行代码
 * @param param 任务初始运行参数
 */
void task1Entry (void *param) {
    for (;;) {
        count++;
        tSemNotify(&syncSem);

        task1Flag = 1;
        tTaskDelay(1);
        task1Flag = 0;
        tTaskDelay(1);
    }
}

/**
 * 任务的运行代码
 * @param param 任务初始运行参数
 */
void task2Entry (void *param) {
    for (;;) {
        tSemWait(&syncSem, 0);
        xprintf("task2 count:%d", count);
    }
}

在这个例子中,定义了全局变量count。但是:

  • 没有使用资源保护机制。因这里功能简单,只是一方读写,写入过程中即便出现打断,读取也不会出现问题,所以不需要保护。
  • 由于只是计数,所以即使task1多次写入,计数仍会累加,task2只关心最后一次写入,所以保护一份最终数据即可。
  • 使用了syncSem进行任务之间的同步。

重点难点

注意事项

可能有的同学觉得这个示例较简单,在课程最终章节的综合实例中,可以看到了在实现串口驱动时,采用了一个更为复杂的例子,用循环FIFO+开关中断+计数信号量实现串口收发中断与多个任务通信的例子。

在这里,请先理解用全局数据进行通信时要处理的几个问题。

常见问题

这篇文章对您有用吗?

我们要如何帮助您?

发表评论

电子邮件地址不会被公开。 必填项已用*标注