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