#include <stdlib.h>
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "AltBlckQ.h"
Go to the source code of this file.
Data Structures | |
struct | BLOCKING_QUEUE_PARAMETERS |
Defines | |
#define | blckqNUM_TASK_SETS ( 3 ) |
#define | blckqSTACK_SIZE configMINIMAL_STACK_SIZE |
Typedefs | |
typedef struct BLOCKING_QUEUE_PARAMETERS | xBlockingQueueParameters |
Functions | |
static | portTASK_FUNCTION (vBlockingQueueConsumer, pvParameters) |
static | portTASK_FUNCTION (vBlockingQueueProducer, pvParameters) |
static | portTASK_FUNCTION_PROTO (vBlockingQueueConsumer, pvParameters) |
static | portTASK_FUNCTION_PROTO (vBlockingQueueProducer, pvParameters) |
void | vStartAltBlockingQueueTasks (unsigned portBASE_TYPE uxPriority) |
portBASE_TYPE | xAreAltBlockingQueuesStillRunning (void) |
Variables | |
static volatile portSHORT | sBlockingConsumerCount [blckqNUM_TASK_SETS] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 } |
static volatile portSHORT | sBlockingProducerCount [blckqNUM_TASK_SETS] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 } |
#define blckqNUM_TASK_SETS ( 3 ) |
Definition at line 92 of file AltBlckQ.c.
Referenced by xAreAltBlockingQueuesStillRunning(), and xAreBlockingQueuesStillRunning().
#define blckqSTACK_SIZE configMINIMAL_STACK_SIZE |
Definition at line 91 of file AltBlckQ.c.
Referenced by vStartAltBlockingQueueTasks(), and vStartBlockingQueueTasks().
typedef struct BLOCKING_QUEUE_PARAMETERS xBlockingQueueParameters |
static portTASK_FUNCTION | ( | vBlockingQueueConsumer | , | |
pvParameters | ||||
) | [static] |
Definition at line 242 of file AltBlckQ.c.
References pdFALSE, pdPASS, pdTRUE, portCHAR, BLOCKING_QUEUE_PARAMETERS::psCheckVariable, vPrintDisplayMessage(), BLOCKING_QUEUE_PARAMETERS::xBlockTime, BLOCKING_QUEUE_PARAMETERS::xQueue, and xQueueAltReceive.
00243 { 00244 unsigned portSHORT usData, usExpectedValue = 0; 00245 xBlockingQueueParameters *pxQueueParameters; 00246 portSHORT sErrorEverOccurred = pdFALSE; 00247 00248 #ifdef USE_STDIO 00249 void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); 00250 00251 const portCHAR * const pcTaskStartMsg = "Alt blocking queue consumer task started.\r\n"; 00252 00253 /* Queue a message for printing to say the task has started. */ 00254 vPrintDisplayMessage( &pcTaskStartMsg ); 00255 #endif 00256 00257 pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; 00258 00259 for( ;; ) 00260 { 00261 if( xQueueAltReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS ) 00262 { 00263 if( usData != usExpectedValue ) 00264 { 00265 /* Catch-up. */ 00266 usExpectedValue = usData; 00267 00268 sErrorEverOccurred = pdTRUE; 00269 } 00270 else 00271 { 00272 /* We have successfully received a message, so increment the 00273 variable used to check we are still running. */ 00274 if( sErrorEverOccurred == pdFALSE ) 00275 { 00276 ( *pxQueueParameters->psCheckVariable )++; 00277 } 00278 00279 /* Increment the value we expect to remove from the queue next time 00280 round. */ 00281 ++usExpectedValue; 00282 } 00283 } 00284 } 00285 }
static portTASK_FUNCTION | ( | vBlockingQueueProducer | , | |
pvParameters | ||||
) | [static] |
Definition at line 202 of file AltBlckQ.c.
References pdFALSE, pdPASS, pdTRUE, portCHAR, BLOCKING_QUEUE_PARAMETERS::psCheckVariable, vPrintDisplayMessage(), BLOCKING_QUEUE_PARAMETERS::xBlockTime, BLOCKING_QUEUE_PARAMETERS::xQueue, and xQueueAltSendToBack.
00203 { 00204 unsigned portSHORT usValue = 0; 00205 xBlockingQueueParameters *pxQueueParameters; 00206 portSHORT sErrorEverOccurred = pdFALSE; 00207 00208 #ifdef USE_STDIO 00209 void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend ); 00210 00211 const portCHAR * const pcTaskStartMsg = "Alt blocking queue producer task started.\r\n"; 00212 00213 /* Queue a message for printing to say the task has started. */ 00214 vPrintDisplayMessage( &pcTaskStartMsg ); 00215 #endif 00216 00217 pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; 00218 00219 for( ;; ) 00220 { 00221 if( xQueueAltSendToBack( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS ) 00222 { 00223 sErrorEverOccurred = pdTRUE; 00224 } 00225 else 00226 { 00227 /* We have successfully posted a message, so increment the variable 00228 used to check we are still running. */ 00229 if( sErrorEverOccurred == pdFALSE ) 00230 { 00231 ( *pxQueueParameters->psCheckVariable )++; 00232 } 00233 00234 /* Increment the variable we are going to post next time round. The 00235 consumer will expect the numbers to follow in numerical order. */ 00236 ++usValue; 00237 } 00238 } 00239 }
static portTASK_FUNCTION_PROTO | ( | vBlockingQueueConsumer | , | |
pvParameters | ||||
) | [static] |
static portTASK_FUNCTION_PROTO | ( | vBlockingQueueProducer | , | |
pvParameters | ||||
) | [static] |
void vStartAltBlockingQueueTasks | ( | unsigned portBASE_TYPE | uxPriority | ) |
Definition at line 120 of file AltBlckQ.c.
References blckqSTACK_SIZE, portBASE_TYPE, portCHAR, portTICK_RATE_MS, BLOCKING_QUEUE_PARAMETERS::psCheckVariable, pvPortMalloc(), sBlockingConsumerCount, tskIDLE_PRIORITY, BLOCKING_QUEUE_PARAMETERS::xBlockTime, BLOCKING_QUEUE_PARAMETERS::xQueue, xQueueCreate(), and xTaskCreate.
00121 { 00122 xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2; 00123 xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4; 00124 xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6; 00125 const unsigned portBASE_TYPE uxQueueSize1 = 1, uxQueueSize5 = 5; 00126 const portTickType xBlockTime = ( portTickType ) 1000 / portTICK_RATE_MS; 00127 const portTickType xDontBlock = ( portTickType ) 0; 00128 00129 /* Create the first two tasks as described at the top of the file. */ 00130 00131 /* First create the structure used to pass parameters to the consumer tasks. */ 00132 pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); 00133 00134 /* Create the queue used by the first two tasks to pass the incrementing number. 00135 Pass a pointer to the queue in the parameter structure. */ 00136 pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); 00137 00138 /* The consumer is created first so gets a block time as described above. */ 00139 pxQueueParameters1->xBlockTime = xBlockTime; 00140 00141 /* Pass in the variable that this task is going to increment so we can check it 00142 is still running. */ 00143 pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] ); 00144 00145 /* Create the structure used to pass parameters to the producer task. */ 00146 pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); 00147 00148 /* Pass the queue to this task also, using the parameter structure. */ 00149 pxQueueParameters2->xQueue = pxQueueParameters1->xQueue; 00150 00151 /* The producer is not going to block - as soon as it posts the consumer will 00152 wake and remove the item so the producer should always have room to post. */ 00153 pxQueueParameters2->xBlockTime = xDontBlock; 00154 00155 /* Pass in the variable that this task is going to increment so we can check 00156 it is still running. */ 00157 pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] ); 00158 00159 00160 /* Note the producer has a lower priority than the consumer when the tasks are 00161 spawned. */ 00162 xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL ); 00163 xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL ); 00164 00165 00166 00167 /* Create the second two tasks as described at the top of the file. This uses 00168 the same mechanism but reverses the task priorities. */ 00169 00170 pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); 00171 pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); 00172 pxQueueParameters3->xBlockTime = xDontBlock; 00173 pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] ); 00174 00175 pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); 00176 pxQueueParameters4->xQueue = pxQueueParameters3->xQueue; 00177 pxQueueParameters4->xBlockTime = xBlockTime; 00178 pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] ); 00179 00180 xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL ); 00181 xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "QConsB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL ); 00182 00183 00184 00185 /* Create the last two tasks as described above. The mechanism is again just 00186 the same. This time both parameter structures are given a block time. */ 00187 pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); 00188 pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); 00189 pxQueueParameters5->xBlockTime = xBlockTime; 00190 pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] ); 00191 00192 pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); 00193 pxQueueParameters6->xQueue = pxQueueParameters5->xQueue; 00194 pxQueueParameters6->xBlockTime = xBlockTime; 00195 pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] ); 00196 00197 xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL ); 00198 xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL ); 00199 }
portBASE_TYPE xAreAltBlockingQueuesStillRunning | ( | void | ) |
Definition at line 289 of file AltBlckQ.c.
References blckqNUM_TASK_SETS, pdFALSE, pdPASS, portBASE_TYPE, and sBlockingConsumerCount.
00290 { 00291 static portSHORT sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 }; 00292 static portSHORT sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 }; 00293 portBASE_TYPE xReturn = pdPASS, xTasks; 00294 00295 /* Not too worried about mutual exclusion on these variables as they are 16 00296 bits and we are only reading them. We also only care to see if they have 00297 changed or not. 00298 00299 Loop through each check variable to and return pdFALSE if any are found not 00300 to have changed since the last call. */ 00301 00302 for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ ) 00303 { 00304 if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ] ) 00305 { 00306 xReturn = pdFALSE; 00307 } 00308 sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ]; 00309 00310 00311 if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ] ) 00312 { 00313 xReturn = pdFALSE; 00314 } 00315 sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ]; 00316 } 00317 00318 return xReturn; 00319 }
volatile portSHORT sBlockingConsumerCount[blckqNUM_TASK_SETS] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 } [static] |
Definition at line 112 of file AltBlckQ.c.
Referenced by vStartAltBlockingQueueTasks(), vStartBlockingQueueTasks(), xAreAltBlockingQueuesStillRunning(), and xAreBlockingQueuesStillRunning().
volatile portSHORT sBlockingProducerCount[blckqNUM_TASK_SETS] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 } [static] |
Definition at line 116 of file AltBlckQ.c.