root/webserver/example/freeRTOSexample/EnergyMeters/Common/Minimal/crhook.c

Revision 14, 8.8 kB (checked in by phil, 15 years ago)

added unmodified FreeRTOS package V5.4.1 with only web srv demo source for LPC2368 for CrossWorks?

Line 
1 /*
2         FreeRTOS V5.4.1 - Copyright (C) 2009 Real Time Engineers Ltd.
3
4         This file is part of the FreeRTOS distribution.
5
6         FreeRTOS is free software; you can redistribute it and/or modify it     under
7         the terms of the GNU General Public License (version 2) as published by the
8         Free Software Foundation and modified by the FreeRTOS exception.
9         **NOTE** The exception to the GPL is included to allow you to distribute a
10         combined work that includes FreeRTOS without being obliged to provide the
11         source code for proprietary components outside of the FreeRTOS kernel. 
12         Alternative commercial license and support terms are also available upon
13         request.  See the licensing section of http://www.FreeRTOS.org for full
14         license details.
15
16         FreeRTOS is distributed in the hope that it will be useful,     but WITHOUT
17         ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18         FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19         more details.
20
21         You should have received a copy of the GNU General Public License along
22         with FreeRTOS; if not, write to the Free Software Foundation, Inc., 59
23         Temple Place, Suite 330, Boston, MA  02111-1307  USA.
24
25
26         ***************************************************************************
27         *                                                                         *
28         * Looking for a quick start?  Then check out the FreeRTOS eBook!          *
29         * See http://www.FreeRTOS.org/Documentation for details                   *
30         *                                                                         *
31         ***************************************************************************
32
33         1 tab == 4 spaces!
34
35         Please ensure to read the configuration and relevant port sections of the
36         online documentation.
37
38         http://www.FreeRTOS.org - Documentation, latest information, license and
39         contact details.
40
41         http://www.SafeRTOS.com - A version that is certified for use in safety
42         critical systems.
43
44         http://www.OpenRTOS.com - Commercial support, development, porting,
45         licensing and training services.
46 */
47
48 /*
49  * This demo file demonstrates how to send data between an ISR and a
50  * co-routine.  A tick hook function is used to periodically pass data between
51  * the RTOS tick and a set of 'hook' co-routines.
52  *
53  * hookNUM_HOOK_CO_ROUTINES co-routines are created.  Each co-routine blocks
54  * to wait for a character to be received on a queue from the tick ISR, checks
55  * to ensure the character received was that expected, then sends the number
56  * back to the tick ISR on a different queue.
57  *
58  * The tick ISR checks the numbers received back from the 'hook' co-routines
59  * matches the number previously sent.
60  *
61  * If at any time a queue function returns unexpectedly, or an incorrect value
62  * is received either by the tick hook or a co-routine then an error is
63  * latched.
64  *
65  * This demo relies on each 'hook' co-routine to execute between each
66  * hookTICK_CALLS_BEFORE_POST tick interrupts.  This and the heavy use of
67  * queues from within an interrupt may result in an error being detected on
68  * slower targets simply due to timing.
69  */
70
71 /* Scheduler includes. */
72 #include "FreeRTOS.h"
73 #include "croutine.h"
74 #include "queue.h"
75
76 /* Demo application includes. */
77 #include "crhook.h"
78
79 /* The number of 'hook' co-routines that are to be created. */
80 #define hookNUM_HOOK_CO_ROUTINES        ( 4 )
81
82 /* The number of times the tick hook should be called before a character is
83 posted to the 'hook' co-routines. */
84 #define hookTICK_CALLS_BEFORE_POST      ( 500 )
85
86 /* There should never be more than one item in any queue at any time. */
87 #define hookHOOK_QUEUE_LENGTH           ( 1 )
88
89 /* Don't block when initially posting to the queue. */
90 #define hookNO_BLOCK_TIME               ( 0 )
91
92 /* The priority relative to other co-routines (rather than tasks) that the
93 'hook' co-routines should take. */
94 #define mainHOOK_CR_PRIORITY                    ( 1 )
95 /*-----------------------------------------------------------*/
96
97 /*
98  * The co-routine function itself.
99  */
100 static void prvHookCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex );
101
102
103 /*
104  * The tick hook function.  This receives a number from each 'hook' co-routine
105  * then sends a number to each co-routine.  An error is flagged if a send or
106  * receive fails, or an unexpected number is received.
107  */
108 void vApplicationTickHook( void );
109
110 /*-----------------------------------------------------------*/
111
112 /* Queues used to send data FROM a co-routine TO the tick hook function.
113 The hook functions received (Rx's) on these queues.  One queue per
114 'hook' co-routine. */
115 static xQueueHandle xHookRxQueues[ hookNUM_HOOK_CO_ROUTINES ];
116
117 /* Queues used to send data FROM the tick hook TO a co-routine function.
118 The hood function transmits (Tx's) on these queues.  One queue per
119 'hook' co-routine. */
120 static xQueueHandle xHookTxQueues[ hookNUM_HOOK_CO_ROUTINES ];
121
122 /* Set to true if an error is detected at any time. */
123 static portBASE_TYPE xCoRoutineErrorDetected = pdFALSE;
124
125 /*-----------------------------------------------------------*/
126
127 void vStartHookCoRoutines( void )
128 {
129 unsigned portBASE_TYPE uxIndex, uxValueToPost = 0;
130
131         for( uxIndex = 0; uxIndex < hookNUM_HOOK_CO_ROUTINES; uxIndex++ )
132         {
133                 /* Create a queue to transmit to and receive from each 'hook'
134                 co-routine. */
135                 xHookRxQueues[ uxIndex ] = xQueueCreate( hookHOOK_QUEUE_LENGTH, sizeof( unsigned portBASE_TYPE ) );
136                 xHookTxQueues[ uxIndex ] = xQueueCreate( hookHOOK_QUEUE_LENGTH, sizeof( unsigned portBASE_TYPE ) );
137
138                 /* To start things off the tick hook function expects the queue it
139                 uses to receive data to contain a value.  */
140                 xQueueSend( xHookRxQueues[ uxIndex ], &uxValueToPost, hookNO_BLOCK_TIME );
141
142                 /* Create the 'hook' co-routine itself. */
143                 xCoRoutineCreate( prvHookCoRoutine, mainHOOK_CR_PRIORITY, uxIndex );
144         }
145 }
146 /*-----------------------------------------------------------*/
147
148 static unsigned portBASE_TYPE uxCallCounter = 0, uxNumberToPost = 0;
149 void vApplicationTickHook( void )
150 {
151 unsigned portBASE_TYPE uxReceivedNumber;
152 signed portBASE_TYPE xIndex, xCoRoutineWoken;
153
154         /* Is it time to talk to the 'hook' co-routines again? */
155         uxCallCounter++;
156         if( uxCallCounter >= hookTICK_CALLS_BEFORE_POST )
157         {
158                 uxCallCounter = 0;
159
160                 for( xIndex = 0; xIndex < hookNUM_HOOK_CO_ROUTINES; xIndex++ )
161                 {
162                         xCoRoutineWoken = pdFALSE;
163                         if( crQUEUE_RECEIVE_FROM_ISR( xHookRxQueues[ xIndex ], &uxReceivedNumber, &xCoRoutineWoken ) != pdPASS )
164                         {
165                                 /* There is no reason why we would not expect the queue to
166                                 contain a value. */
167                                 xCoRoutineErrorDetected = pdTRUE;
168                         }
169                         else
170                         {
171                                 /* Each queue used to receive data from the 'hook' co-routines
172                                 should contain the number we last posted to the same co-routine. */
173                                 if( uxReceivedNumber != uxNumberToPost )
174                                 {
175                                         xCoRoutineErrorDetected = pdTRUE;
176                                 }
177
178                                 /* Nothing should be blocked waiting to post to the queue. */
179                                 if( xCoRoutineWoken != pdFALSE )
180                                 {
181                                         xCoRoutineErrorDetected = pdTRUE;
182                                 }
183                         }
184                 }
185
186                 /* Start the next cycle by posting the next number onto each Tx queue. */
187                 uxNumberToPost++;
188
189                 for( xIndex = 0; xIndex < hookNUM_HOOK_CO_ROUTINES; xIndex++ )
190                 {
191                         if( crQUEUE_SEND_FROM_ISR( xHookTxQueues[ xIndex ], &uxNumberToPost, pdFALSE ) != pdTRUE )
192                         {
193                                 /* Posting to the queue should have woken the co-routine that
194                                 was blocked on the queue. */
195                                 xCoRoutineErrorDetected = pdTRUE;
196                         }
197                 }
198         }
199 }
200 /*-----------------------------------------------------------*/
201
202 static void prvHookCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
203 {
204 static unsigned portBASE_TYPE uxReceivedValue[ hookNUM_HOOK_CO_ROUTINES ];
205 portBASE_TYPE xResult;
206
207         /* Each co-routine MUST start with a call to crSTART(); */
208         crSTART( xHandle );
209
210         for( ;; )
211         {
212                 /* Wait to receive a value from the tick hook. */
213                 xResult = pdFAIL;
214                 crQUEUE_RECEIVE( xHandle, xHookTxQueues[ uxIndex ], &( uxReceivedValue[ uxIndex ] ), portMAX_DELAY, &xResult );
215
216                 /* There is no reason why we should not have received something on
217                 the queue. */
218                 if( xResult != pdPASS )
219                 {
220                         xCoRoutineErrorDetected = pdTRUE;
221                 }
222
223                 /* Send the same number back to the idle hook so it can verify it. */
224                 xResult = pdFAIL;
225                 crQUEUE_SEND( xHandle, xHookRxQueues[ uxIndex ], &( uxReceivedValue[ uxIndex ] ), hookNO_BLOCK_TIME, &xResult );
226                 if( xResult != pdPASS )
227                 {
228                         /* There is no reason why we should not have been able to post to
229                         the queue. */
230                         xCoRoutineErrorDetected = pdTRUE;
231                 }
232         }
233
234         /* Each co-routine MUST end with a call to crEND(). */
235         crEND();
236 }
237 /*-----------------------------------------------------------*/
238
239 portBASE_TYPE xAreHookCoRoutinesStillRunning( void )
240 {
241         if( xCoRoutineErrorDetected )
242         {
243                 return pdFALSE;
244         }
245         else
246         {
247                 return pdTRUE;
248         }
249 }
250
251
252
Note: See TracBrowser for help on using the browser.