本帖最后由 TLLED 于 2018-4-18 21:42 编辑 9 |4 T+ u8 r/ v7 H 0 h* C# @ j9 d& [, `; M; V* l 队列是主要的任务间通讯方式。消息队列就是通过 RTOS 内核提供的服务,任务或中断程序可以将一个消息放入到队列。同样,一个或者多个任务可以通过 RTOS 内核服务从队列中得到消息。通过这个方式实现任务之间的数据传递。; T& |1 H6 F1 \& K 程序任务框图: 下图是本次程序实现任务之间消息队列传递数据的框图 程序执行条件:8 K" D) o4 H5 N; k% a > 创建消息队列:" P ?0 D8 [8 e 通过调用 xQueueCreate()函数来创建消息队列。- [4 L: k& Y1 c! X% g7 U, \ > 任务创建: > 任务1:vAppStartTask 实现LED等闪烁,和消息队列无关联。 > 任务2:vAppQueueProducer 实现 向消息队列放数据。 > 任务3:vAppQueueConsumer 实现 从消息队列取数据。 ( s. ]3 O; ]' A' d3 k# p% K* R 消息队列相关API函数:' }! Y& |7 M0 A) [) t& o* ]- @ > 函数: xQueueCreate) O% B. v" f7 B6 } 函数原型: 函数描述: #函数 xQueueCreate 用于创建消息队列 & B+ \& a; s7 S+ P, V/ ?/ r #第一个参数是消息队列的个数 #第二个参数是每个消息的大小,单位是字节。 ! ]* F! t1 S2 X #返回值:如果创建成功则返回队列的句柄,如果返回NULL,则表示没有足够的堆空间来分配,队列创建失败; > 函数:xQueueSend 函数原型:% s8 l+ Y! ^0 w4 J 函数描述: #函数 xQueueSend用于消息发送。 7 r. U; U! d4 R4 y* M6 W #第一个参数是消息队列句柄 #第二个参数是要传递数据地址,每次发送都是将消息队列创建函数xQueueCreate所指定的单个消息大小复制到消息队列空间中。 #返回,若消息队列创建成功会返回消息队列的句柄。8 v0 g3 s+ a4 O > 函数:xQueueReceive* Y9 @! Y! t7 x 函数原型: 函数描述: #函数 xQueueReceive用于接收消息队列中的数据。 #第一个参数是消息队列句柄。5 z2 Y" E6 V$ }) s( ~0 T #第二个参数是数据缓冲区指针,用来保存从队列读取出来的数据; #第三个参数是阻塞超时时间,如果写入队列时,队列已满,那么这个时间就是任务处于阻塞状态等待队列空间有效的最长等待时间,使用时经常利用portTICK_RATE_MS转换为ms;- S$ n3 z9 d) x9 I/ L# K" k # 返回值: . H$ R! b6 ]8 i4 t 1. pdPASS:表示数据成功写入队列,返回值为pdPASS; ; z& K7 t7 V4 j9 S6 j8 N8 A 2. errQUEUE_EMPTY:表示队列已空,无法读出数据; 程序代码截图: $ S- @( ]8 S' j- s0 ]* o4 j 创建消息队列,创建3个任务。6 I- z4 W' _0 z* d 任务1函数:vAppStartTask 实现LED等闪烁,和消息队列无关联。 任务2函数:vAppQueueProducer 实现 将变量ProducerValue的值放入向消息队列。 任务3函数:vAppQueueConsumer 实现 从消息队列取数据并串口打印。 程序执行结果: 任务三不断输出从任务2放入消息队列的数据。 * j( l8 W" ]* t7 i, F; m2 ` i# p" G- V- h/ y1 q$ p & w& C) E+ ~ }! k" P, p 2 ?! a! }. W; {% [5 C* ? % W+ U; h- T9 O" z8 m( ~ i' m4 C6 ^4 K/ P& `9 p7 A , x H8 v( N+ k+ y / y( q$ C# [2 x/ j ! p, Q& c0 W8 k, E! {* _ / L. R1 Y6 u/ m8 } 4 U, @7 E5 h0 o% B" c |