]> begriffs open source - cmsis-freertos/blob - Demo/Common/Minimal/QueueOverwrite.c
Updated pack to FreeRTOS 10.3.1
[cmsis-freertos] / Demo / Common / Minimal / QueueOverwrite.c
1 /*
2  * FreeRTOS Kernel V10.3.1
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * http://www.FreeRTOS.org
23  * http://aws.amazon.com/freertos
24  *
25  * 1 tab == 4 spaces!
26  */
27
28 /*
29  * Basic task to demonstrate the xQueueOverwrite() function.  See the comments
30  * in the function itself.
31  */
32
33 /* Scheduler include files. */
34 #include "FreeRTOS.h"
35 #include "task.h"
36 #include "queue.h"
37
38 /* Demo program include files. */
39 #include "QueueOverwrite.h"
40
41 /* A block time of 0 just means "don't block". */
42 #define qoDONT_BLOCK            0
43
44 /* Number of times to overwrite the value in the queue. */
45 #define qoLOOPS                 5
46
47 /* The task that uses the queue. */
48 static void prvQueueOverwriteTask( void *pvParameters );
49
50 /* Variable that is incremented on each loop of prvQueueOverwriteTask() provided
51 prvQueueOverwriteTask() has not found any errors. */
52 static uint32_t ulLoopCounter = 0;
53
54 /* Set to pdFALSE if an error is discovered by the
55 vQueueOverwritePeriodicISRDemo() function. */
56 static BaseType_t xISRTestStatus = pdPASS;
57
58 /* The queue that is accessed from the ISR.  The queue accessed by the task is
59 created inside the task itself. */
60 static QueueHandle_t xISRQueue = NULL;
61
62 /*-----------------------------------------------------------*/
63
64 void vStartQueueOverwriteTask( UBaseType_t uxPriority )
65 {
66 const UBaseType_t uxQueueLength = 1;
67
68         /* Create the queue used by the ISR.  xQueueOverwriteFromISR() should only
69         be used on queues that have a length of 1. */
70         xISRQueue = xQueueCreate( uxQueueLength, ( UBaseType_t ) sizeof( uint32_t ) );
71
72         /* Create the test task.  The queue used by the test task is created inside
73         the task itself. */
74         xTaskCreate( prvQueueOverwriteTask, "QOver", configMINIMAL_STACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL );
75 }
76 /*-----------------------------------------------------------*/
77
78 static void prvQueueOverwriteTask( void *pvParameters )
79 {
80 QueueHandle_t xTaskQueue;
81 const UBaseType_t uxQueueLength = 1;
82 uint32_t ulValue, ulStatus = pdPASS, x;
83
84         /* The parameter is not used. */
85         ( void ) pvParameters;
86
87         /* Create the queue.  xQueueOverwrite() should only be used on queues that
88         have a length of 1. */
89         xTaskQueue = xQueueCreate( uxQueueLength, ( UBaseType_t ) sizeof( uint32_t ) );
90         configASSERT( xTaskQueue );
91
92         for( ;; )
93         {
94                 /* The queue is empty.  Writing to the queue then reading from the queue
95                 should return the item written. */
96                 ulValue = 10;
97                 xQueueOverwrite( xTaskQueue, &ulValue );
98
99                 ulValue = 0;
100                 xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK );
101
102                 if( ulValue != 10 )
103                 {
104                         ulStatus = pdFAIL;
105                 }
106
107                 /* Now try writing to the queue several times.  Each time the value
108                 in the queue should get overwritten. */
109                 for( x = 0; x < qoLOOPS; x++ )
110                 {
111                         /* Write to the queue. */
112                         xQueueOverwrite( xTaskQueue, &x );
113
114                         /* Check the value in the queue is that written, even though the
115                         queue was not necessarily empty. */
116                         xQueuePeek( xTaskQueue, &ulValue, qoDONT_BLOCK );
117                         if( ulValue != x )
118                         {
119                                 ulStatus = pdFAIL;
120                         }
121
122                         /* There should always be one item in the queue. */
123                         if( uxQueueMessagesWaiting( xTaskQueue ) != uxQueueLength )
124                         {
125                                 ulStatus = pdFAIL;
126                         }
127                 }
128
129                 /* Empty the queue again. */
130                 xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK );
131
132                 if( uxQueueMessagesWaiting( xTaskQueue ) != 0 )
133                 {
134                         ulStatus = pdFAIL;
135                 }
136
137                 if( ulStatus != pdFAIL )
138                 {
139                         /* Increment a counter to show this task is still running without
140                         error. */
141                         ulLoopCounter++;
142                 }
143
144                 #if( configUSE_PREEMPTION == 0 )
145                         taskYIELD();
146                 #endif
147         }
148 }
149 /*-----------------------------------------------------------*/
150
151 BaseType_t xIsQueueOverwriteTaskStillRunning( void )
152 {
153 BaseType_t xReturn;
154
155         if( xISRTestStatus != pdPASS )
156         {
157                 xReturn = pdFAIL;
158         }
159         else if( ulLoopCounter > 0 )
160         {
161                 xReturn = pdPASS;
162         }
163         else
164         {
165                 /* The task has either stalled of discovered an error. */
166                 xReturn = pdFAIL;
167         }
168
169         ulLoopCounter = 0;
170
171         return xReturn;
172 }
173 /*-----------------------------------------------------------*/
174
175 void vQueueOverwritePeriodicISRDemo( void )
176 {
177 static uint32_t ulCallCount = 0;
178 const uint32_t ulTx1 = 10UL, ulTx2 = 20UL, ulNumberOfSwitchCases = 3UL;
179 uint32_t ulRx;
180
181         /* This function should be called from an interrupt, such as the tick hook
182         function vApplicationTickHook(). */
183
184         configASSERT( xISRQueue );
185
186         switch( ulCallCount )
187         {
188                 case 0:
189                         /* The queue is empty.  Write ulTx1 to the queue.  In this demo the
190                         last parameter is not used because there are no tasks blocked on
191                         this queue. */
192                         xQueueOverwriteFromISR( xISRQueue, &ulTx1, NULL );
193
194                         /* Peek the queue to check it holds the expected value. */
195                         xQueuePeekFromISR( xISRQueue, &ulRx );
196                         if( ulRx != ulTx1 )
197                         {
198                                 xISRTestStatus = pdFAIL;
199                         }
200                         break;
201
202                 case 1:
203                         /* The queue already holds ulTx1.  Overwrite the value in the queue
204                         with ulTx2. */
205                         xQueueOverwriteFromISR( xISRQueue, &ulTx2, NULL );
206                         break;
207
208                 case 2:
209                         /* Read from the queue to empty the queue again.  The value read
210                         should be ulTx2. */
211                         xQueueReceiveFromISR( xISRQueue, &ulRx, NULL );
212
213                         if( ulRx != ulTx2 )
214                         {
215                                 xISRTestStatus = pdFAIL;
216                         }
217                         break;
218         }
219
220         /* Run the next case in the switch statement above next time this function
221         is called. */
222         ulCallCount++;
223
224         if( ulCallCount >= ulNumberOfSwitchCases )
225         {
226                 /* Go back to the start. */
227                 ulCallCount = 0;
228         }
229 }
230