]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/Common/Minimal/crhook.c
Update version numbers in preparation for V8.2.0 release candidate 1.
[freertos] / FreeRTOS / Demo / Common / Minimal / crhook.c
1 /*\r
2     FreeRTOS V8.2.0rc1 - Copyright (C) 2014 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     This file is part of the FreeRTOS distribution.\r
8 \r
9     FreeRTOS is free software; you can redistribute it and/or modify it under\r
10     the terms of the GNU General Public License (version 2) as published by the\r
11     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
12 \r
13     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
14     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
15     >>!   obliged to provide the source code for proprietary components     !<<\r
16     >>!   outside of the FreeRTOS kernel.                                   !<<\r
17 \r
18     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
19     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
20     FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
21     link: http://www.freertos.org/a00114.html\r
22 \r
23     1 tab == 4 spaces!\r
24 \r
25     ***************************************************************************\r
26      *                                                                       *\r
27      *    Having a problem?  Start by reading the FAQ "My application does   *\r
28      *    not run, what could be wrong?".  Have you defined configASSERT()?  *\r
29      *                                                                       *\r
30      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
31      *                                                                       *\r
32     ***************************************************************************\r
33 \r
34     ***************************************************************************\r
35      *                                                                       *\r
36      *    FreeRTOS provides completely free yet professionally developed,    *\r
37      *    robust, strictly quality controlled, supported, and cross          *\r
38      *    platform software that is more than just the market leader, it     *\r
39      *    is the industry's de facto standard.                               *\r
40      *                                                                       *\r
41      *    Help yourself get started quickly while simultaneously helping     *\r
42      *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
43      *    tutorial book, reference manual, or both:                          *\r
44      *    http://www.FreeRTOS.org/Documentation                              *\r
45      *                                                                       *\r
46     ***************************************************************************\r
47 \r
48     ***************************************************************************\r
49      *                                                                       *\r
50      *   Investing in training allows your team to be as productive as       *\r
51      *   possible as early as possible, lowering your overall development    *\r
52      *   cost, and enabling you to bring a more robust product to market     *\r
53      *   earlier than would otherwise be possible.  Richard Barry is both    *\r
54      *   the architect and key author of FreeRTOS, and so also the world's   *\r
55      *   leading authority on what is the world's most popular real time     *\r
56      *   kernel for deeply embedded MCU designs.  Obtaining your training    *\r
57      *   from Richard ensures your team will gain directly from his in-depth *\r
58      *   product knowledge and years of usage experience.  Contact Real Time *\r
59      *   Engineers Ltd to enquire about the FreeRTOS Masterclass, presented  *\r
60      *   by Richard Barry:  http://www.FreeRTOS.org/contact\r
61      *                                                                       *\r
62     ***************************************************************************\r
63 \r
64     ***************************************************************************\r
65      *                                                                       *\r
66      *    You are receiving this top quality software for free.  Please play *\r
67      *    fair and reciprocate by reporting any suspected issues and         *\r
68      *    participating in the community forum:                              *\r
69      *    http://www.FreeRTOS.org/support                                    *\r
70      *                                                                       *\r
71      *    Thank you!                                                         *\r
72      *                                                                       *\r
73     ***************************************************************************\r
74 \r
75     http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
76     license and Real Time Engineers Ltd. contact details.\r
77 \r
78     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
79     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
80     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
81 \r
82     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
83     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
84 \r
85     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
86     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
87     licenses offer ticketed support, indemnification and commercial middleware.\r
88 \r
89     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
90     engineered and independently SIL3 certified version for use in safety and\r
91     mission critical applications that require provable dependability.\r
92 \r
93     1 tab == 4 spaces!\r
94 */\r
95 \r
96 /*\r
97  * This demo file demonstrates how to send data between an ISR and a \r
98  * co-routine.  A tick hook function is used to periodically pass data between\r
99  * the RTOS tick and a set of 'hook' co-routines.\r
100  *\r
101  * hookNUM_HOOK_CO_ROUTINES co-routines are created.  Each co-routine blocks\r
102  * to wait for a character to be received on a queue from the tick ISR, checks\r
103  * to ensure the character received was that expected, then sends the number\r
104  * back to the tick ISR on a different queue.\r
105  * \r
106  * The tick ISR checks the numbers received back from the 'hook' co-routines \r
107  * matches the number previously sent.\r
108  *\r
109  * If at any time a queue function returns unexpectedly, or an incorrect value\r
110  * is received either by the tick hook or a co-routine then an error is \r
111  * latched.\r
112  *\r
113  * This demo relies on each 'hook' co-routine to execute between each \r
114  * hookTICK_CALLS_BEFORE_POST tick interrupts.  This and the heavy use of \r
115  * queues from within an interrupt may result in an error being detected on \r
116  * slower targets simply due to timing.\r
117  */\r
118 \r
119 /* Scheduler includes. */\r
120 #include "FreeRTOS.h"\r
121 #include "croutine.h"\r
122 #include "queue.h"\r
123 \r
124 /* Demo application includes. */\r
125 #include "crhook.h"\r
126 \r
127 /* The number of 'hook' co-routines that are to be created. */\r
128 #define hookNUM_HOOK_CO_ROUTINES        ( 4 )\r
129 \r
130 /* The number of times the tick hook should be called before a character is \r
131 posted to the 'hook' co-routines. */\r
132 #define hookTICK_CALLS_BEFORE_POST      ( 500 )\r
133 \r
134 /* There should never be more than one item in any queue at any time. */\r
135 #define hookHOOK_QUEUE_LENGTH           ( 1 )\r
136 \r
137 /* Don't block when initially posting to the queue. */\r
138 #define hookNO_BLOCK_TIME               ( 0 )\r
139 \r
140 /* The priority relative to other co-routines (rather than tasks) that the\r
141 'hook' co-routines should take. */\r
142 #define mainHOOK_CR_PRIORITY                    ( 1 )\r
143 /*-----------------------------------------------------------*/\r
144 \r
145 /*\r
146  * The co-routine function itself.\r
147  */\r
148 static void prvHookCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex );\r
149 \r
150 \r
151 /*\r
152  * The tick hook function.  This receives a number from each 'hook' co-routine\r
153  * then sends a number to each co-routine.  An error is flagged if a send or \r
154  * receive fails, or an unexpected number is received.\r
155  */\r
156 void vApplicationTickHook( void );\r
157 \r
158 /*-----------------------------------------------------------*/\r
159 \r
160 /* Queues used to send data FROM a co-routine TO the tick hook function.\r
161 The hook functions received (Rx's) on these queues.  One queue per\r
162 'hook' co-routine. */\r
163 static QueueHandle_t xHookRxQueues[ hookNUM_HOOK_CO_ROUTINES ];\r
164 \r
165 /* Queues used to send data FROM the tick hook TO a co-routine function.\r
166 The hood function transmits (Tx's) on these queues.  One queue per\r
167 'hook' co-routine. */\r
168 static QueueHandle_t xHookTxQueues[ hookNUM_HOOK_CO_ROUTINES ];\r
169 \r
170 /* Set to true if an error is detected at any time. */\r
171 static BaseType_t xCoRoutineErrorDetected = pdFALSE;\r
172 \r
173 /*-----------------------------------------------------------*/\r
174 \r
175 void vStartHookCoRoutines( void )\r
176 {\r
177 UBaseType_t uxIndex, uxValueToPost = 0;\r
178 \r
179         for( uxIndex = 0; uxIndex < hookNUM_HOOK_CO_ROUTINES; uxIndex++ )\r
180         {\r
181                 /* Create a queue to transmit to and receive from each 'hook' \r
182                 co-routine. */\r
183                 xHookRxQueues[ uxIndex ] = xQueueCreate( hookHOOK_QUEUE_LENGTH, sizeof( UBaseType_t ) );\r
184                 xHookTxQueues[ uxIndex ] = xQueueCreate( hookHOOK_QUEUE_LENGTH, sizeof( UBaseType_t ) );\r
185 \r
186                 /* To start things off the tick hook function expects the queue it \r
187                 uses to receive data to contain a value.  */\r
188                 xQueueSend( xHookRxQueues[ uxIndex ], &uxValueToPost, hookNO_BLOCK_TIME );\r
189 \r
190                 /* Create the 'hook' co-routine itself. */\r
191                 xCoRoutineCreate( prvHookCoRoutine, mainHOOK_CR_PRIORITY, uxIndex );\r
192         }\r
193 }\r
194 /*-----------------------------------------------------------*/\r
195 \r
196 static UBaseType_t uxCallCounter = 0, uxNumberToPost = 0;\r
197 void vApplicationTickHook( void )\r
198 {\r
199 UBaseType_t uxReceivedNumber;\r
200 BaseType_t xIndex, xCoRoutineWoken;\r
201 \r
202         /* Is it time to talk to the 'hook' co-routines again? */\r
203         uxCallCounter++;\r
204         if( uxCallCounter >= hookTICK_CALLS_BEFORE_POST )\r
205         {\r
206                 uxCallCounter = 0;\r
207 \r
208                 for( xIndex = 0; xIndex < hookNUM_HOOK_CO_ROUTINES; xIndex++ )\r
209                 {\r
210                         xCoRoutineWoken = pdFALSE;\r
211                         if( crQUEUE_RECEIVE_FROM_ISR( xHookRxQueues[ xIndex ], &uxReceivedNumber, &xCoRoutineWoken ) != pdPASS )\r
212                         {\r
213                                 /* There is no reason why we would not expect the queue to \r
214                                 contain a value. */\r
215                                 xCoRoutineErrorDetected = pdTRUE;\r
216                         }\r
217                         else\r
218                         {\r
219                                 /* Each queue used to receive data from the 'hook' co-routines \r
220                                 should contain the number we last posted to the same co-routine. */\r
221                                 if( uxReceivedNumber != uxNumberToPost )\r
222                                 {\r
223                                         xCoRoutineErrorDetected = pdTRUE;\r
224                                 }\r
225 \r
226                                 /* Nothing should be blocked waiting to post to the queue. */\r
227                                 if( xCoRoutineWoken != pdFALSE )\r
228                                 {\r
229                                         xCoRoutineErrorDetected = pdTRUE;\r
230                                 }\r
231                         }\r
232                 }\r
233 \r
234                 /* Start the next cycle by posting the next number onto each Tx queue. */\r
235                 uxNumberToPost++;\r
236 \r
237                 for( xIndex = 0; xIndex < hookNUM_HOOK_CO_ROUTINES; xIndex++ )\r
238                 {\r
239                         if( crQUEUE_SEND_FROM_ISR( xHookTxQueues[ xIndex ], &uxNumberToPost, pdFALSE ) != pdTRUE )\r
240                         {\r
241                                 /* Posting to the queue should have woken the co-routine that \r
242                                 was blocked on the queue. */\r
243                                 xCoRoutineErrorDetected = pdTRUE;\r
244                         }\r
245                 }\r
246         }\r
247 }\r
248 /*-----------------------------------------------------------*/\r
249 \r
250 static void prvHookCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )\r
251 {\r
252 static UBaseType_t uxReceivedValue[ hookNUM_HOOK_CO_ROUTINES ];\r
253 BaseType_t xResult;\r
254 \r
255         /* Each co-routine MUST start with a call to crSTART(); */\r
256         crSTART( xHandle );\r
257 \r
258         for( ;; )\r
259         {\r
260                 /* Wait to receive a value from the tick hook. */\r
261                 xResult = pdFAIL;\r
262                 crQUEUE_RECEIVE( xHandle, xHookTxQueues[ uxIndex ], &( uxReceivedValue[ uxIndex ] ), portMAX_DELAY, &xResult );\r
263 \r
264                 /* There is no reason why we should not have received something on\r
265                 the queue. */\r
266                 if( xResult != pdPASS )\r
267                 {\r
268                         xCoRoutineErrorDetected = pdTRUE;\r
269                 }\r
270 \r
271                 /* Send the same number back to the idle hook so it can verify it. */\r
272                 xResult = pdFAIL;\r
273                 crQUEUE_SEND( xHandle, xHookRxQueues[ uxIndex ], &( uxReceivedValue[ uxIndex ] ), hookNO_BLOCK_TIME, &xResult );\r
274                 if( xResult != pdPASS )\r
275                 {\r
276                         /* There is no reason why we should not have been able to post to \r
277                         the queue. */\r
278                         xCoRoutineErrorDetected = pdTRUE;\r
279                 }\r
280         }\r
281 \r
282         /* Each co-routine MUST end with a call to crEND(). */\r
283         crEND();\r
284 }\r
285 /*-----------------------------------------------------------*/\r
286 \r
287 BaseType_t xAreHookCoRoutinesStillRunning( void )\r
288 {\r
289         if( xCoRoutineErrorDetected )\r
290         {\r
291                 return pdFALSE;\r
292         }\r
293         else\r
294         {\r
295                 return pdTRUE;\r
296         }\r
297 }\r
298 \r
299 \r
300 \r