前言% O7 a9 J/ O0 t' z
本文主要带大家了解队列的基本知识和队列的基本操作。
4 `3 {- I! \0 B! B
1 t7 [2 a4 T6 \4 Q/ S一、队列基本知识介绍0 a4 M2 ^! o* c. O- I( E. x- Q y# d
队列是为了任务与任务、任务与中断之间的通信而准备的,可以在任务与任务、任务与中断之间传递消息,队列中可以存储有限的、大小固定的数据项目。任务与任务、任务与中断之间要交流的数据保存在队列中,叫做队列项目。队列所能保存的最大数据项目数量叫做队列的长度,创建队列的时候会指定数据项目的大小和队列的长度。由于队列用来传递消息的,所以也称为消息队列。(本段话取自正点原子freeRTOS开发手册这里只做简单介绍想要详细了解可以去看看原子的手册,这里主要教大家如何去配置和使用队列)
! t |7 F, z( S3 E- `
, W' w+ k# |: y1 K$ f, W二、队列的基本操作
3 a: P& g& Q! I7 d* Z) E7 k. z T( YcubeMX配置* h6 b' E9 _! K8 l# l) d, W
: R/ x$ C' D5 F# f
; z2 D" W7 _0 ]8 [. B' k. n& _+ c! g" z2 K1 I M9 y
1.Queue name:队列名字
; _5 p6 h2 B+ q* V4 a- S( M2.Queue size:队列大小! s8 p2 \7 ~, v/ v9 b9 [, Q! u; R/ x
3.Lite size:队列里面每一个数据的类型9 C3 r3 y3 d9 q5 @" y3 ?4 s
8 x- u. Z2 ~6 U& d" [) n q/ M
代码讲解
) b* t# u' p- C/ n1.cubeMX自动生成的创建队列代码
% v/ W2 N& G& _4 c
4 m: t/ F5 H! S, @* f }- /* Create the queue(s) */6 w7 Q; v+ Y! f
- /* definition and creation of myQueue01 */
5 U M% D1 I0 I2 z8 E* q% k: P - osMessageQDef(myQueue01, 16, uint16_t);8 P R; Z$ Y9 x3 s
- myQueue01Handle = osMessageCreate(osMessageQ(myQueue01), NULL);
E! G3 ^8 x9 @
/ J2 H" H ^: L [( V- /* USER CODE BEGIN RTOS_QUEUES */, y- \' M6 G- p; m) R/ k. ?1 i
- /* add queues, ... */
$ \, r4 l& `) b3 ?0 h; I4 x' e6 M( ? G - /* USER CODE END RTOS_QUEUES */
复制代码 ' {, s0 n; R4 e) k2 q% ]
2.把一个消息写入队列函数$ |: D' }4 p* F4 C# l# H* }
6 G( H$ k$ I7 C7 E9 ?/ y- /**% C% V. U' O( B5 F8 q M' o4 }. U. [
- * @brief Put a Message to a Queue.+ ^! n4 y: S+ Y0 s+ i
- * @param queue_id message queue ID obtained with \ref osMessageCreate.
9 J3 X! f/ Y( a4 o% n- P" e/ p- F - * @param info message information.
$ _# k; ^& N8 E& e& ^" D - * @param millisec timeout value or 0 in case of no time-out.) V! V. s m) ^; n! w
- * @retval status code that indicates the execution status of the function.! x' [+ W) E1 }/ z5 O
- * @note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS.! |% B& S4 b c, z+ g, b8 z
- */- J9 S, l2 a& a7 x$ i; y6 f9 X+ L
- osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec)
( T, i! W$ `% R' Z - {
- c3 Y& [* P/ r/ y - portBASE_TYPE taskWoken = pdFALSE;: v: v5 y5 ~. R+ C
- TickType_t ticks;
+ U9 D; [/ w+ i. `. H
' [3 x8 \* ?3 F. W- ticks = millisec / portTICK_PERIOD_MS;
% x0 ~6 K4 @1 }, Z - if (ticks == 0) {+ |8 S& X X: |7 E, Z
- ticks = 1;
: x* G1 m) h$ y1 x7 B4 W% R6 S - }
' B* X/ {; Y/ W. g" ~$ c6 C% K: S - * q1 I( \& Q& W/ M- f* u; W
- if (inHandlerMode()) {
1 b& S, X" C7 e& i - if (xQueueSendFromISR(queue_id, &info, &taskWoken) != pdTRUE) {
1 f7 T: D' z: D' i- L( G$ G6 l/ S - return osErrorOS;
2 F; _0 \2 Y8 R. V! V' @# \ - }
" e' Y' x! g- p# E( Z. b - portEND_SWITCHING_ISR(taskWoken);
. B2 V% v' W T - }7 `9 m6 N9 X4 z# j
- else {6 P z) v- y; S& H+ T5 @6 D$ }5 \ v" ^ L
- if (xQueueSend(queue_id, &info, ticks) != pdTRUE) {
5 N' s5 X) f$ {5 s& z: p( K9 {2 _ - return osErrorOS;
/ Q- a( D, M2 \! L! b3 u# ` - }' y: L1 B1 x7 j9 S: \+ C
- }2 r& ^; b3 I2 _- @6 G3 C
- 6 }" u/ ~( ]- A" z) M1 B s
- return osOK;
2 j5 o, v: L$ f5 A1 a - }
复制代码
) Z, x1 u7 g4 v( c. J9 `& X2 |0 w3.从队列中读出消息函数
4 c$ @; X# A0 Q; o/ n2 d. P- ^7 q! w; J) B
- /**( E& \' j# C* o( c2 b3 \$ `
- * @brief Get a Message or Wait for a Message from a Queue.
$ G' l; J! p. @/ D0 g- K4 v S4 f - * @param queue_id message queue ID obtained with \ref osMessageCreate.8 F1 N$ a6 u* w% Q2 j5 _
- * @param millisec timeout value or 0 in case of no time-out., |0 C: f. C# u1 w
- * @retval event information that includes status code.' {% e' N3 U4 y$ p9 m
- * @note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS.
# z# ^4 t2 T$ p$ [( p - */
* G# n9 W v( e4 J - osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec)5 M, a* @2 d1 T- q6 R
- {
) J0 S$ D9 `7 u+ C - portBASE_TYPE taskWoken;& u2 ?! J# x: n4 w9 X
- TickType_t ticks;& J @1 ~) ^3 j1 @3 t" Y' L
- osEvent event;
9 ?. P( _# R: J# H& m8 U+ h
9 e3 K7 C/ z" D' M- event.def.message_id = queue_id;' j! `& j, G. C+ I
- event.value.v = 0;
) H: z$ x0 q7 C; ?, m$ M - ; j h) e( _% X
- if (queue_id == NULL) {
# D4 e0 f* n2 L# q$ z5 r - event.status = osErrorParameter;2 I" i: ^, D7 N: l( J
- return event;# i/ Y: R9 Z6 I$ r @
- }
' t. X2 K- l4 t0 {
+ {3 b. I j/ v- taskWoken = pdFALSE;. P- N- j% t" R# r2 L A/ h* T" \
- 1 k# j1 r- P, W5 K
- ticks = 0;3 o' l0 m7 W; d+ x
- if (millisec == osWaitForever) {; t! G( N* A- v( V- ^+ o5 _% n. `
- ticks = portMAX_DELAY;
0 I6 _* s" @; O4 m- O - }& Y$ Z* _% ?* [- c- Z
- else if (millisec != 0) {# q/ H9 i0 y) k: W# d: P
- ticks = millisec / portTICK_PERIOD_MS;/ T; `; k3 h2 I- n5 e6 g" t
- if (ticks == 0) {" h, c: z1 y- F
- ticks = 1;
9 z0 ^% K4 m* `: g/ O" X/ Q - }" `" Q/ S& H k a' @. Z. e3 R
- }3 W( H4 I: B" \5 O8 D* I4 L
- - c( [: D: @9 |- z- t
- if (inHandlerMode()) {
2 g7 t" `- \ ^' S% x - if (xQueueReceiveFromISR(queue_id, &event.value.v, &taskWoken) == pdTRUE) {6 f) x0 B' @# b9 X& ^ a
- /* We have mail */
* v! l5 m6 V* F- N8 R - event.status = osEventMessage;
2 Q9 X3 |. V# k, ~. o - }# e, Q2 I, h, w
- else {2 g3 ]1 c m$ _9 u5 }( o2 P
- event.status = osOK;
* j/ N) D# ^% z5 c3 A2 L$ Q - }
: O6 v6 L2 F* V - portEND_SWITCHING_ISR(taskWoken);7 `. a& O; d- n; O
- }3 z, k! j" B) z" W3 n% g& R; [
- else { S' r: A; F: w* a1 `2 a
- if (xQueueReceive(queue_id, &event.value.v, ticks) == pdTRUE) {9 o3 x7 I4 N6 n9 a: z9 L
- /* We have mail */
2 f, T8 R1 K! U8 F: v- G' n% } - event.status = osEventMessage;" j& P' M# h! s9 }7 K" ~
- }
5 S, q ~- Q, A% Q1 ?! A( X - else {$ S$ b. e8 r5 i& T9 E
- event.status = (ticks == 0) ? osOK : osEventTimeout;" j: a* `! B u( Z- k( U* Y2 [
- }
) |2 K& Y. }2 I - }7 h9 A) Y- O# i! ^9 D$ B
- ! Y8 {) P5 g% e$ n' `$ z
- return event;
: b% c1 _2 b# ~ k7 N, q - }
复制代码
8 m _% P5 l- B6 p H2 J总结' }( Q4 `& T8 y" s
队列操作大家可以试一试还是很简单的。5 q9 ]9 ^0 y! p) V) A2 R' e8 Z
' @' S5 {7 x& i* W1 K8 A2 p" |: F$ b* x, R& ?* [8 K" r
|