消息队列
1、消息队列初始化
创建消息队列时 FreeRTOS 会先给消息队列分配一块内存空间
内存的大小 = 控制块大小 +(单个消息空间大小 * 消息队列长度)
控制块 = 消息的存储位置 + 头指针 pcHead + 尾指针 pcTail + 消息大小 uxItemSize + 队列长度 uxLength + …
每个消息队列都与消息空间在同一段连续的内存空间中,在创建成功的时候,这些内存就被占用了,只有删除了消息队列的时候,这段内存才会被释放掉,创建成功的时候就已经分配好每个消息空间与消息队列的容量,无法更改。
消息空间可以存放不大于消息大小 uxItemSize 的任意类型的数据,所有消息队列中的消息空间总数即是消息队列的长度,这个长度可在消息队列创建时指定。
2、写
对象: 任务或中断服务程序
队列未满: FreeRTOS 会将消息拷贝到消息队列队尾
队列已满: 根据用户指定的阻塞时时间进行阻塞,在这段时间中,如果队列一直不允许入队,该任务将保持阻塞状态以等待队列允许入队。当等待的时间超过了指定的阻塞时间,即使队列中还不允许入队,任务也会自动从阻塞态转移为就绪态,此时发送消息的任务或者中断程序会收到一个 错误码 errQUEUE_FULL。
紧急消息: 发送的位置是消息队列队头而非队尾,这样,接收者就能够优先接收到紧急消息,从而及时进行消息处理。
3、读
对象: 任务或中断服务程序
队列为空: 任务将保持阻塞状态以等待队列数据有效。当其它任务或中断服务程序往其等待的队列中写入了数据,该任务将自动由阻塞态转移为就绪态
阻塞超时时间: 当等待的时间超过了指定的阻塞时间,即使队列中尚无有效数据,任务也会自动从阻塞态转移为就绪态。、
4、阻塞机制
读
- 不等,做其他事,不进入阻塞态
- 设定阻塞超时时间,进入阻塞态,超过时间则恢复就绪态
- 进入阻塞态,直到读到数据
写
只有在任务中发送消息才允许进行阻塞状态,而在中断中发送消息不允许带有阻塞机制的,需要调用在中断中发送消息的 API 函数接口,因为发送消息的上下文环境是在中断中,不允许有阻塞的情况。