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