the queue will hold. */
} xQUEUE;
这是一个颇为标准的队列,不但包括了头部和尾部指针,而且指针指向我们刚刚读过或者写过的位置。
当刚刚创建一个队列,用户指定了队列的长度和需要队列跟踪的项目大小。pcHead和pcTail被用来跟踪队列的内部存储器。加入一个项目到队列就对队列内部存储器进行一次深拷贝。
FreeRTOS用深拷贝替代在项目中存放一个指针是因为有可能项目插入的生命周期要比队列的生命周期短。例如,试想一个简单的整数队列使用局部变量,跨几个函数调用的插入和删除。如果这个队列在局部变量里存储这些整数的指针,当整数的局部变量离开作用域时指针将会失效,同时局部变量的存储空间将被新的数使用。
什么需要用户选择使用队列。若内容很少,用户可以把复制的内容进行排列,就像上图中简单整数的例子,或者,若内容很多,用户可以排列内容的指针。请注意,在这两种情况下FreeRTOS都是在做深拷贝:如果用户选择排列复制的内容,那么这个队列存储了每项内容的一份深拷贝;如果用户选择了排列指针,队列存储了指针的一份深拷贝。当然,用户在队列里存储了指针,那么用户有责任管理与内存相关的指针。队列并不关心你存储了什么样的数据,它只需要知道数据的大小。
FreeRTOS支持阻塞和非阻塞队列的插入和移除。非阻塞队列操作会立即返回"队列的插入是否完成?"或者 "队列的移除是否完成?"的状态。阻塞操作则根据特定的超时。一个任务可以无限期地阻塞或者在有限时间里阻塞。
特别需要注意的是,当任务被阻塞在一个队列时,系统保持运行所带来的风险;以及当任务被阻塞在一个队列时,有其他任务或中断在继续运行。这种阻塞任务的方法能不浪费CPU周期,使其他任务和中断可以有效地使用CPU周期。
FreeRTOS使用xTasksWaitingToSend列表来保持对正阻塞在插入队列里的任务的跟踪。每当有一个元素被移出队列,xTasksWaitingToSend列表就会被检查。如果有个任务在那个列表中等待,那个是未阻塞任务。同样的,xTasksWaitingToReceive保持对那些正阻塞在移除队列里的任务的跟踪。每当有一个新元素入到队列,xTasksWaitingToReceive列表就会被检查。如果有个任务在那个列表中等待,那个是未阻塞任务。
信号灯和互斥
FreeRTOS使用它的队列与任务通信,也在任务间通信。FreeRTOS也使用它的队列来实现信号灯与互斥。
有什么区别?
信号灯与互斥听上去像一回事,但它们不是。FreeRTOS同样地实现了它们,但本来它们以不同的方式被使用。它们是如何不同地被使用?嵌入式系统宗师Michael Barr说这是在他文章中写得最好的,“信号灯与互斥揭秘”:
The correct use of a semaphore is for signaling from one task to another. A mutex is meant to be taken and released, always in that order, by each task that uses the shared resource it protects. By contrast, tasks that use semaphores either signal ["send" in FreeRTOS terms] or wait ["receive" in FreeRTOS terms] - not both.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-30698-9.html
科技上
为什么还会失败
有去无回