freertos通信---信号量与队列
嘿嘿.又见面了.
到这里,任务的调度和切换,你已经有了深刻的理解.
接下来,自然而然就是任务间的通讯咯.把相关的任务串联起来,就形成了程序的基本架构.
一.队列
为什么要先讲解队列了,因为信号量就是利用队列来实现的.
走,一起瞅瞅
1.1队列的创建
#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) )
默认队列创建是一个宏定义,真正调用的是xQueueGenericCreate,最后一个参数保留给信号量使用.
1.申请内存
2.队列结构体初始化
1.2队列结构体
队列其实是一个类似环形缓冲区的buffer
有发送和接受列表
RxLock和CTxLock是一个特别的地方,后边我们在讲解
注意,前面说过了.由于信号量也使用队列完成,所以使用了联合体区分队列和信号量
1.3队列初始化
初始化很简单.需要注意的就是uxItemSize是0.指向的是队列头.这表示信号量的使用,信号量中互斥锁是特别的,它的head指向null.
2.1队列的发送
#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
发送队列内容稍微有点多.
仔细看,其实也很简单
主要由连个部分要处理,1队列满超时阻塞,2入队操作
先来看入队操作
1.拷贝数据到队列.注意:只是数据项的拷贝.
2.如果接受列表中有任务,则做切换准备.
简单吧,就是把接收队列的任务加入正确的队列.
再来看看超时处理的部分
1.设置正确的超时时间
2.挂起调度器.
3.上锁.重点来了,上锁就是为了防止中断响应,操作队列
4.把当前任务加入队列发送列表,然后加入延时列表
5.解锁.并且判断上锁时,是否有中断响应并且操作队列
6.重启调度器
7.切换任务
8.等待超时,之后又回到入队操作.
2.2队列中断操作函数没有超时阻塞,只有入队操作
3 队列接收
队列接收和队列发送基本思路一致.当你明白了发送的流程,接收也不再话下.
三.思考与总结
到这里,你已经掌握了基本的任务通信方法,队列.
回想一下,队列就是入队,出队,任务的切换,超时阻塞.核心内容还是任务的调度.