]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/Common/Minimal/StreamBufferInterrupt.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Demo / Common / Minimal / StreamBufferInterrupt.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  * A simple example that shows a stream buffer being used to pass data from an\r
31  * interrupt to a task.\r
32  *\r
33  * There are two strings, pcStringToSend and pcStringToReceive, where\r
34  * pcStringToReceive is a substring of pcStringToSend.  The interrupt sends\r
35  * a few bytes of pcStringToSend to a stream buffer ever few times that it\r
36  * executes.  A task reads the bytes from the stream buffer, looking for the\r
37  * substring, and flagging an error if the received data is invalid.\r
38  */\r
39 \r
40 /* Standard includes. */\r
41 #include "stdio.h"\r
42 #include "string.h"\r
43 \r
44 /* FreeRTOS includes. */\r
45 #include "FreeRTOS.h"\r
46 #include "task.h"\r
47 #include "stream_buffer.h"\r
48 \r
49 /* Demo app includes. */\r
50 #include "StreamBufferInterrupt.h"\r
51 \r
52 #define sbiSTREAM_BUFFER_LENGTH_BYTES           ( ( size_t ) 100 )\r
53 #define sbiSTREAM_BUFFER_TRIGGER_LEVEL_10       ( ( BaseType_t ) 10 )\r
54 \r
55 /*-----------------------------------------------------------*/\r
56 \r
57 /* Implements the task that receives a stream of bytes from the interrupt. */\r
58 static void prvReceivingTask( void *pvParameters );\r
59 \r
60 /*-----------------------------------------------------------*/\r
61 \r
62 /* The stream buffer that is used to send data from an interrupt to the task. */\r
63 static StreamBufferHandle_t xStreamBuffer = NULL;\r
64 \r
65 /* The string that is sent from the interrupt to the task four bytes at a\r
66 time.  Must be multiple of 4 bytes long as the ISR sends 4 bytes at a time*/\r
67 static const char * pcStringToSend = "_____Hello FreeRTOS_____";\r
68 \r
69 /* The string to task is looking for, which must be a substring of\r
70 pcStringToSend. */\r
71 static const char * pcStringToReceive = "Hello FreeRTOS";\r
72 \r
73 /* Set to pdFAIL if anything unexpected happens. */\r
74 static BaseType_t xDemoStatus = pdPASS;\r
75 \r
76 /* Incremented each time pcStringToReceive is correctly received, provided no\r
77 errors have occurred.  Used so the check task can check this task is still\r
78 running as expected. */\r
79 static uint32_t ulCycleCount = 0;\r
80 \r
81 /*-----------------------------------------------------------*/\r
82 \r
83 void vStartStreamBufferInterruptDemo( void )\r
84 {\r
85         /* Create the stream buffer that sends data from the interrupt to the\r
86         task, and create the task. */\r
87         xStreamBuffer = xStreamBufferCreate( /* The buffer length in bytes. */\r
88                                                                                  sbiSTREAM_BUFFER_LENGTH_BYTES,\r
89                                                                                  /* The stream buffer's trigger level. */\r
90                                                                                  sbiSTREAM_BUFFER_TRIGGER_LEVEL_10 );\r
91 \r
92         xTaskCreate( prvReceivingTask, /* The function that implements the task. */\r
93                                  "StrIntRx",       /* Human readable name for the task. */\r
94                                  configMINIMAL_STACK_SIZE,      /* Stack size (in words!). */\r
95                                  NULL,                     /* Task parameter is not used. */\r
96                                  tskIDLE_PRIORITY + 2, /* The priority at which the task is created. */\r
97                                  NULL );                   /* No use for the task handle. */\r
98 }\r
99 /*-----------------------------------------------------------*/\r
100 \r
101 static void prvReceivingTask( void *pvParameters )\r
102 {\r
103 char cRxBuffer[ 20 ];\r
104 BaseType_t xNextByte = 0;\r
105 \r
106         /* Remove warning about unused parameters. */\r
107         ( void ) pvParameters;\r
108 \r
109         /* Make sure the string will fit in the Rx buffer, including the NULL\r
110         terminator. */\r
111         configASSERT( sizeof( cRxBuffer ) > strlen( pcStringToReceive ) );\r
112 \r
113         /* Make sure the stream buffer has been created. */\r
114         configASSERT( xStreamBuffer != NULL );\r
115 \r
116         /* Start with the Rx buffer in a known state. */\r
117         memset( cRxBuffer, 0x00, sizeof( cRxBuffer ) );\r
118 \r
119         for( ;; )\r
120         {\r
121                 /* Keep receiving characters until the end of the string is received.\r
122                 Note:  An infinite block time is used to simplify the example.  Infinite\r
123                 block times are not recommended in production code as they do not allow\r
124                 for error recovery. */\r
125                 xStreamBufferReceive( /* The stream buffer data is being received from. */\r
126                                                           xStreamBuffer,\r
127                                                           /* Where to place received data. */\r
128                                                           ( void * ) &( cRxBuffer[ xNextByte ] ),\r
129                                                           /* The number of bytes to receive. */\r
130                                                           sizeof( char ),\r
131                                                           /* The time to wait for the next data if the buffer\r
132                                                           is empty. */\r
133                                                           portMAX_DELAY );\r
134 \r
135                 /* If xNextByte is 0 then this task is looking for the start of the\r
136                 string, which is 'H'. */\r
137                 if( xNextByte == 0 )\r
138                 {\r
139                         if( cRxBuffer[ xNextByte ] == 'H' )\r
140                         {\r
141                                 /* The start of the string has been found.  Now receive\r
142                                 characters until the end of the string is found. */\r
143                                 xNextByte++;\r
144                         }\r
145                 }\r
146                 else\r
147                 {\r
148                         /* Receiving characters while looking for the end of the string,\r
149                         which is an 'S'. */\r
150                         if( cRxBuffer[ xNextByte ] == 'S' )\r
151                         {\r
152                                 /* The string has now been received.  Check its validity. */\r
153                                 if( strcmp( cRxBuffer, pcStringToReceive ) != 0 )\r
154                                 {\r
155                                         xDemoStatus = pdFAIL;\r
156                                 }\r
157 \r
158                                 /* Return to start looking for the beginning of the string\r
159                                 again. */\r
160                                 memset( cRxBuffer, 0x00, sizeof( cRxBuffer ) );\r
161                                 xNextByte = 0;\r
162 \r
163                                 /* Increment the cycle count as an indication to the check task\r
164                                 that this demo is still running. */\r
165                                 if( xDemoStatus == pdPASS )\r
166                                 {\r
167                                         ulCycleCount++;\r
168                                 }\r
169                         }\r
170                         else\r
171                         {\r
172                                 /* Receive the next character the next time around, while\r
173                                 continuing to look for the end of the string. */\r
174                                 xNextByte++;\r
175 \r
176                                 configASSERT( xNextByte < sizeof( cRxBuffer ) );\r
177                         }\r
178                 }\r
179         }\r
180 }\r
181 /*-----------------------------------------------------------*/\r
182 \r
183 void vBasicStreamBufferSendFromISR( void )\r
184 {\r
185 static size_t xNextByteToSend = 0;\r
186 const BaseType_t xCallsBetweenSends = 100, xBytesToSend = 4;\r
187 static BaseType_t xCallCount = 0;\r
188 \r
189         /* Is it time to write to the stream buffer again? */\r
190         xCallCount++;\r
191         if( xCallCount > xCallsBetweenSends )\r
192         {\r
193                 xCallCount = 0;\r
194 \r
195                 /* Send the next four bytes to the stream buffer. */\r
196                 xStreamBufferSendFromISR( xStreamBuffer,\r
197                                                                   ( void * ) ( pcStringToSend + xNextByteToSend ),\r
198                                                                   xBytesToSend,\r
199                                                                   NULL );\r
200 \r
201                 /* Send the next four bytes the next time around, wrapping to the start\r
202                 of the string if necessary. */\r
203                 xNextByteToSend += xBytesToSend;\r
204 \r
205                 if( xNextByteToSend >= strlen( pcStringToSend ) )\r
206                 {\r
207                         xNextByteToSend = 0;\r
208                 }\r
209         }\r
210 }\r
211 /*-----------------------------------------------------------*/\r
212 \r
213 BaseType_t xIsInterruptStreamBufferDemoStillRunning( void )\r
214 {\r
215 uint32_t ulLastCycleCount = 0;\r
216 \r
217         /* Check the demo is still running. */\r
218         if( ulLastCycleCount == ulCycleCount )\r
219         {\r
220                 xDemoStatus = pdFAIL;\r
221         }\r
222         else\r
223         {\r
224                 ulLastCycleCount = ulCycleCount;\r
225         }\r
226 \r
227         return xDemoStatus;\r
228 }\r
229 \r