Fix formatting in kernel demo application files (#1148)

* Fix formatting in kernel demo application files

* Fix header check fail in the demo files

* Add ignored patterns in core header check file

* Fix formatting

* Update vApplicationStackOverflowHook for AVR_ATMega4809_MPLAB.X/main.c

Co-authored-by: Soren Ptak <ptaksoren@gmail.com>

* Update vApplicationStackOverflowHook for AVR_ATMega4809_MPLAB.X/main.c

Co-authored-by: Soren Ptak <ptaksoren@gmail.com>

* Update vApplicationStackOverflowHook for AVR_Dx_IAR/main.c

Co-authored-by: Soren Ptak <ptaksoren@gmail.com>

* Update vApplicationStackOverflowHook for AVR_Dx_IAR/main.c

Co-authored-by: Soren Ptak <ptaksoren@gmail.com>

* Update vApplicationStackOverflowHook for AVR_Dx_MPLAB.X/main.c

Co-authored-by: Soren Ptak <ptaksoren@gmail.com>

* Update vApplicationMallocFailedHook for AVR_Dx_MPLAB.X/main.c

Co-authored-by: Soren Ptak <ptaksoren@gmail.com>

* Fix formatting AVR32_UC3

---------

Co-authored-by: Soren Ptak <ptaksoren@gmail.com>
This commit is contained in:
Rahul Kar 2024-01-02 11:05:59 +05:30 committed by GitHub
parent 85ed21bcfb
commit 121fbe295b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
169 changed files with 22211 additions and 21557 deletions

View file

@ -305,11 +305,16 @@ FREERTOS_IGNORED_PATTERNS = [
r'FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Keil/.*', r'FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Keil/.*',
r'FreeRTOS/Demo/AVR_ATMega4809_Atmel_Studio/RTOSDemo/.*', r'FreeRTOS/Demo/AVR_ATMega4809_Atmel_Studio/RTOSDemo/.*',
r'FreeRTOS/Demo/AVR32_UC3/.*', r'FreeRTOS/Demo/AVR32_UC3/.*',
r'FreeRTOS/Demo/AVR_ATMega4809_IAR/.*',
r'FreeRTOS/Demo/AVR_ATMega4809_MPLAB.X/.*',
r'FreeRTOS/Demo/AVR_Dx_IAR/.*',
r'FreeRTOS/Demo/AVR_Dx_MPLAB.X/.*',
r'FreeRTOS/Demo/ARM7_STR75x_GCC/STLibrary/inc/.*', r'FreeRTOS/Demo/ARM7_STR75x_GCC/STLibrary/inc/.*',
r'FreeRTOS/Demo/ARM7_STR75x_IAR/STLibrary/inc/.*', r'FreeRTOS/Demo/ARM7_STR75x_IAR/STLibrary/inc/.*',
r'FreeRTOS/Demo/CORTEX_R4F_RZ_T_GCC_IAR/System/GCC/inc/.*', r'FreeRTOS/Demo/CORTEX_R4F_RZ_T_GCC_IAR/System/GCC/inc/.*',
r'FreeRTOS/Demo/CORTEX_A5_SAMA5D2x_Xplained_IAR/AtmelFiles/drivers/misc/.*', r'FreeRTOS/Demo/CORTEX_A5_SAMA5D2x_Xplained_IAR/AtmelFiles/drivers/misc/.*',
r'FreeRTOS/Demo/CORTEX_ATSAM3X_Atmel_Studio/src/.*', r'FreeRTOS/Demo/CORTEX_ATSAM3X_Atmel_Studio/src/.*',
r'FreeRTOS/Demo/MSP430X_MSP430FR5969_LaunchPad_IAR_CCS/.*',
r'FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/.*', r'FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Trace_Recorder_Configuration/.*',
r'FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/.*', r'FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Echo_Posix/Trace_Recorder_Configuration/.*',
r'FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/.*', r'FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/common/WinPCap/.*',

View file

@ -25,12 +25,12 @@
*/ */
/* /*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used. * these demo application projects then ensure Supervisor mode is used.
*/ */
/* /*
@ -96,7 +96,7 @@
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* The rate at which the on board LED will toggle when there is/is not an /* The rate at which the on board LED will toggle when there is/is not an
error. */ * error. */
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
#define mainON_BOARD_LED_BIT ( ( unsigned long ) 7 ) #define mainON_BOARD_LED_BIT ( ( unsigned long ) 7 )
@ -113,7 +113,7 @@ error. */
#define MAX_WAIT_STATES 8 #define MAX_WAIT_STATES 8
static const unsigned long ululCSRWaitValues[ MAX_WAIT_STATES + 1 ] = static const unsigned long ululCSRWaitValues[ MAX_WAIT_STATES + 1 ] =
{ {
WaitState1,/* There is no "zero wait state" value, so use one wait state */ WaitState1, /* There is no "zero wait state" value, so use one wait state */
WaitState1, WaitState1,
WaitState2, WaitState2,
WaitState3, WaitState3,
@ -136,14 +136,14 @@ static long prvCheckOtherTasksAreStillRunning( unsigned long ulMemCheckTaskCount
* prvCheckOtherTasksAreStillRunning(). See the description at the top * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Dynamically created and deleted during each cycle of the vErrorChecks() * Dynamically created and deleted during each cycle of the vErrorChecks()
* task. This is done to check the operation of the memory allocator. * task. This is done to check the operation of the memory allocator.
* See the top of vErrorChecks for more details. * See the top of vErrorChecks for more details.
*/ */
static void vMemCheckTask( void *pvParameters ); static void vMemCheckTask( void * pvParameters );
/* /*
* Configure the processor for use with the Olimex demo board. This includes * Configure the processor for use with the Olimex demo board. This includes
@ -175,12 +175,12 @@ int main( void )
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Now all the tasks have been started - start the scheduler. /* Now all the tasks have been started - start the scheduler.
*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used here. */ * these demo application projects then ensure Supervisor mode is used here. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Should never reach here! */ /* Should never reach here! */
@ -188,35 +188,36 @@ int main( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
unsigned long ulMemCheckTaskRunningCount; unsigned long ulMemCheckTaskRunningCount;
TaskHandle_t xCreatedTask; TaskHandle_t xCreatedTask;
/* Just to stop compiler warnings. */ /* Just to stop compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period * operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so * is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. * the on board LED flash rate will increase.
*
* In addition to the standard tests the memory allocator is tested through
* the dynamic creation and deletion of a task each cycle. Each time the
* task is created memory must be allocated for its stack. When the task is
* deleted this memory is returned to the heap. If the task cannot be created
* then it is likely that the memory allocation failed. */
In addition to the standard tests the memory allocator is tested through for( ; ; )
the dynamic creation and deletion of a task each cycle. Each time the
task is created memory must be allocated for its stack. When the task is
deleted this memory is returned to the heap. If the task cannot be created
then it is likely that the memory allocation failed. */
for( ;; )
{ {
/* Reset xCreatedTask. This is modified by the task about to be /* Reset xCreatedTask. This is modified by the task about to be
created so we can tell if it is executing correctly or not. */ * created so we can tell if it is executing correctly or not. */
xCreatedTask = mainNO_TASK; xCreatedTask = mainNO_TASK;
/* Dynamically create a task - passing ulMemCheckTaskRunningCount as a /* Dynamically create a task - passing ulMemCheckTaskRunningCount as a
parameter. */ * parameter. */
ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE; ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;
if( xTaskCreate( vMemCheckTask, "MEM_CHECK", configMINIMAL_STACK_SIZE, ( void * ) &ulMemCheckTaskRunningCount, tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS ) if( xTaskCreate( vMemCheckTask, "MEM_CHECK", configMINIMAL_STACK_SIZE, ( void * ) &ulMemCheckTaskRunningCount, tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )
{ {
/* Could not create the task - we have probably run out of heap. */ /* Could not create the task - we have probably run out of heap. */
@ -233,8 +234,8 @@ TaskHandle_t xCreatedTask;
} }
/* Check all the standard demo application tasks are executing without /* Check all the standard demo application tasks are executing without
error. ulMemCheckTaskRunningCount is checked to ensure it was * error. ulMemCheckTaskRunningCount is checked to ensure it was
modified by the task just deleted. */ * modified by the task just deleted. */
if( prvCheckOtherTasksAreStillRunning( ulMemCheckTaskRunningCount ) != pdPASS ) if( prvCheckOtherTasksAreStillRunning( ulMemCheckTaskRunningCount ) != pdPASS )
{ {
/* An error has been detected in one of the tasks - flash faster. */ /* An error has been detected in one of the tasks - flash faster. */
@ -242,7 +243,7 @@ TaskHandle_t xCreatedTask;
} }
/* The toggle rate of the LED depends on how long this task delays for. /* The toggle rate of the LED depends on how long this task delays for.
An error reduces the delay period and so increases the toggle rate. */ * An error reduces the delay period and so increases the toggle rate. */
vParTestToggleLED( mainON_BOARD_LED_BIT ); vParTestToggleLED( mainON_BOARD_LED_BIT );
} }
} }
@ -250,7 +251,7 @@ TaskHandle_t xCreatedTask;
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
long lCount; long lCount;
#ifdef RUN_FROM_ROM #ifdef RUN_FROM_ROM
{ {
@ -259,16 +260,16 @@ long lCount;
unsigned long ulCSRWaitValue; unsigned long ulCSRWaitValue;
/* We are compiling to run from ROM (either on-chip or off-chip flash). /* We are compiling to run from ROM (either on-chip or off-chip flash).
Leave the RAM/flash mapped the way they are on reset * Leave the RAM/flash mapped the way they are on reset
(flash @ 0x00000000, RAM @ 0x00300000), and set up the * (flash @ 0x00000000, RAM @ 0x00300000), and set up the
proper flash wait states (starts out at the maximum number * proper flash wait states (starts out at the maximum number
of wait states on reset, so we should be able to reduce it). * of wait states on reset, so we should be able to reduce it).
Most of this code will probably get removed by the compiler * Most of this code will probably get removed by the compiler
if optimization is enabled, since these calculations are * if optimization is enabled, since these calculations are
based on constants. But the compiler should still produce * based on constants. But the compiler should still produce
a correct wait state register value. */ * a correct wait state register value. */
nsecsPerClockTick = ( portFLOAT ) 1000000000 / configCPU_CLOCK_HZ; nsecsPerClockTick = ( portFLOAT ) 1000000000 / configCPU_CLOCK_HZ;
lNumWaitStates = ( long )( ( configFLASH_SPEED_NSEC / nsecsPerClockTick ) + 0.5 ) - 1; lNumWaitStates = ( long ) ( ( configFLASH_SPEED_NSEC / nsecsPerClockTick ) + 0.5 ) - 1;
if( lNumWaitStates < 0 ) if( lNumWaitStates < 0 )
{ {
@ -291,11 +292,11 @@ long lCount;
#else /* else we are compiling to run from on-chip RAM */ #else /* else we are compiling to run from on-chip RAM */
{ {
/* If compiling to run from RAM, we expect the on-chip RAM to already /* If compiling to run from RAM, we expect the on-chip RAM to already
be mapped at 0x00000000. This is typically done with an initialization * be mapped at 0x00000000. This is typically done with an initialization
script for the JTAG emulator you are using to download and run the * script for the JTAG emulator you are using to download and run the
demo application. So there is nothing to do here in this case. */ * demo application. So there is nothing to do here in this case. */
} }
#endif #endif /* ifdef RUN_FROM_ROM */
/* Disable all interrupts at the AIC level initially... */ /* Disable all interrupts at the AIC level initially... */
AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF; AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;
@ -303,7 +304,7 @@ long lCount;
/* Set all SVR and SMR entries to default values (start with a clean slate)... */ /* Set all SVR and SMR entries to default values (start with a clean slate)... */
for( lCount = 0; lCount < 32; lCount++ ) for( lCount = 0; lCount < 32; lCount++ )
{ {
AT91C_BASE_AIC->AIC_SVR[ lCount ] = (unsigned long) 0; AT91C_BASE_AIC->AIC_SVR[ lCount ] = ( unsigned long ) 0;
AT91C_BASE_AIC->AIC_SMR[ lCount ] = AIC_SRCTYPE_INT_EDGE_TRIGGERED; AT91C_BASE_AIC->AIC_SMR[ lCount ] = AIC_SRCTYPE_INT_EDGE_TRIGGERED;
} }
@ -314,7 +315,7 @@ long lCount;
AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF; AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF;
/* Perform 8 "End Of Interrupt" cmds to make sure AIC will not Lock out /* Perform 8 "End Of Interrupt" cmds to make sure AIC will not Lock out
nIRQ */ * nIRQ */
for( lCount = 0; lCount < 8; lCount++ ) for( lCount = 0; lCount < 8; lCount++ )
{ {
AT91C_BASE_AIC->AIC_EOICR = 0; AT91C_BASE_AIC->AIC_EOICR = 0;
@ -327,11 +328,11 @@ long lCount;
static long prvCheckOtherTasksAreStillRunning( unsigned long ulMemCheckTaskCount ) static long prvCheckOtherTasksAreStillRunning( unsigned long ulMemCheckTaskCount )
{ {
long lReturn = ( long ) pdPASS; long lReturn = ( long ) pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected * that they are all still running, and that none of them have detected
an error. */ * an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -371,7 +372,7 @@ long lReturn = ( long ) pdPASS;
if( ulMemCheckTaskCount == mainCOUNT_INITIAL_VALUE ) if( ulMemCheckTaskCount == mainCOUNT_INITIAL_VALUE )
{ {
/* The vMemCheckTask did not increment the counter - it must /* The vMemCheckTask did not increment the counter - it must
have failed. */ * have failed. */
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
@ -379,26 +380,26 @@ long lReturn = ( long ) pdPASS;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vMemCheckTask( void *pvParameters ) static void vMemCheckTask( void * pvParameters )
{ {
unsigned long *pulMemCheckTaskRunningCounter; unsigned long * pulMemCheckTaskRunningCounter;
void *pvMem1, *pvMem2, *pvMem3; void * pvMem1, * pvMem2, * pvMem3;
static long lErrorOccurred = pdFALSE; static long lErrorOccurred = pdFALSE;
/* This task is dynamically created then deleted during each cycle of the /* This task is dynamically created then deleted during each cycle of the
vErrorChecks task to check the operation of the memory allocator. Each time * vErrorChecks task to check the operation of the memory allocator. Each time
the task is created memory is allocated for the stack and TCB. Each time * the task is created memory is allocated for the stack and TCB. Each time
the task is deleted this memory is returned to the heap. This task itself * the task is deleted this memory is returned to the heap. This task itself
exercises the allocator by allocating and freeing blocks. * exercises the allocator by allocating and freeing blocks.
*
The task executes at the idle priority so does not require a delay. * The task executes at the idle priority so does not require a delay.
*
pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the * pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the
vErrorChecks() task that this task is still executing without error. */ * vErrorChecks() task that this task is still executing without error. */
pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters; pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters;
for( ;; ) for( ; ; )
{ {
if( lErrorOccurred == pdFALSE ) if( lErrorOccurred == pdFALSE )
{ {
@ -408,16 +409,17 @@ static long lErrorOccurred = pdFALSE;
else else
{ {
/* There has been an error so reset the counter so the check task /* There has been an error so reset the counter so the check task
can tell that an error occurred. */ * can tell that an error occurred. */
*pulMemCheckTaskRunningCounter = mainCOUNT_INITIAL_VALUE; *pulMemCheckTaskRunningCounter = mainCOUNT_INITIAL_VALUE;
} }
/* Allocate some memory - just to give the allocator some extra /* Allocate some memory - just to give the allocator some extra
exercise. This has to be in a critical section to ensure the * exercise. This has to be in a critical section to ensure the
task does not get deleted while it has memory allocated. */ * task does not get deleted while it has memory allocated. */
vTaskSuspendAll(); vTaskSuspendAll();
{ {
pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 ); pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );
if( pvMem1 == NULL ) if( pvMem1 == NULL )
{ {
lErrorOccurred = pdTRUE; lErrorOccurred = pdTRUE;
@ -434,6 +436,7 @@ static long lErrorOccurred = pdFALSE;
vTaskSuspendAll(); vTaskSuspendAll();
{ {
pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 ); pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 );
if( pvMem2 == NULL ) if( pvMem2 == NULL )
{ {
lErrorOccurred = pdTRUE; lErrorOccurred = pdTRUE;
@ -450,6 +453,7 @@ static long lErrorOccurred = pdFALSE;
vTaskSuspendAll(); vTaskSuspendAll();
{ {
pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 ); pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );
if( pvMem3 == NULL ) if( pvMem3 == NULL )
{ {
lErrorOccurred = pdTRUE; lErrorOccurred = pdTRUE;
@ -463,4 +467,3 @@ static long lErrorOccurred = pdFALSE;
xTaskResumeAll(); xTaskResumeAll();
} }
} }

View file

@ -25,12 +25,12 @@
*/ */
/* /*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used. * these demo application projects then ensure Supervisor mode is used.
*/ */
/* /*
* Creates all the demo application tasks, then starts the scheduler. The WEB * Creates all the demo application tasks, then starts the scheduler. The WEB
@ -92,7 +92,7 @@
* prvCheckOtherTasksAreStillRunning(). See the description at the top * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Configure the processor for use with the Atmel demo board. Setup is minimal * Configure the processor for use with the Atmel demo board. Setup is minimal
@ -116,7 +116,7 @@ static long prvCheckOtherTasksAreStillRunning( void );
void main( void ) void main( void )
{ {
/* Setup any hardware that has not already been configured by the low /* Setup any hardware that has not already been configured by the low
level init routines. */ * level init routines. */
prvSetupHardware(); prvSetupHardware();
/* Initialise the LED outputs for use by the demo application tasks. */ /* Initialise the LED outputs for use by the demo application tasks. */
@ -138,32 +138,31 @@ void main( void )
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Start the scheduler. /* Start the scheduler.
*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used here. */ * these demo application projects then ensure Supervisor mode is used here. */
vTaskStartScheduler(); vTaskStartScheduler();
/* We should never get here as control is now taken by the scheduler. */ /* We should never get here as control is now taken by the scheduler. */
return;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* When using the JTAG debugger the hardware is not always initialised to /* When using the JTAG debugger the hardware is not always initialised to
the correct default state. This line just ensures that this does not * the correct default state. This line just ensures that this does not
cause all interrupts to be masked at the start. */ * cause all interrupts to be masked at the start. */
AT91C_BASE_AIC->AIC_EOICR = 0; AT91C_BASE_AIC->AIC_EOICR = 0;
/* Most setup is performed by the low level init function called from the /* Most setup is performed by the low level init function called from the
startup asm file. */ * startup asm file. */
/* Configure the PIO Lines corresponding to LED1 to LED4 to be outputs as /* Configure the PIO Lines corresponding to LED1 to LED4 to be outputs as
well as the UART Tx line. */ * well as the UART Tx line. */
AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK ); AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK );
/* Enable the peripheral clock. */ /* Enable the peripheral clock. */
@ -171,25 +170,25 @@ static void prvSetupHardware( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
/* The parameters are not used in this task. */ /* The parameters are not used in this task. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period * operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so * is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. */ * the on board LED flash rate will increase. */
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. */ /* Delay until it is time to execute again. */
vTaskDelay( xDelayPeriod ); vTaskDelay( xDelayPeriod );
/* Check all the standard demo application tasks are executing without /* Check all the standard demo application tasks are executing without
error. */ * error. */
if( prvCheckOtherTasksAreStillRunning() != pdPASS ) if( prvCheckOtherTasksAreStillRunning() != pdPASS )
{ {
/* An error has been detected in one of the tasks - flash faster. */ /* An error has been detected in one of the tasks - flash faster. */
@ -203,11 +202,11 @@ TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
static long prvCheckOtherTasksAreStillRunning( void ) static long prvCheckOtherTasksAreStillRunning( void )
{ {
long lReturn = ( long ) pdPASS; long lReturn = ( long ) pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected * that they are all still running, and that none of them have detected
an error. */ * an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -242,5 +241,3 @@ long lReturn = ( long ) pdPASS;
return lReturn; return lReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -25,12 +25,12 @@
*/ */
/* /*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used. * these demo application projects then ensure Supervisor mode is used.
*/ */
/* /*
@ -58,16 +58,16 @@
*/ */
/* /*
Changes from V2.4.2 * Changes from V2.4.2
*
+ The vErrorChecks() task now dynamically creates then deletes a task each + The vErrorChecks() task now dynamically creates then deletes a task each
cycle. This tests the operation of the memory allocator. + cycle. This tests the operation of the memory allocator.
+
Changes from V2.5.2 + Changes from V2.5.2
+
+ vParTestInitialise() is called during initialisation to ensure all the + vParTestInitialise() is called during initialisation to ensure all the
LED's start off. + LED's start off.
*/ */
/* Standard includes. */ /* Standard includes. */
@ -127,7 +127,7 @@
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* The rate at which the on board LED will toggle when there is/is not an /* The rate at which the on board LED will toggle when there is/is not an
error. */ * error. */
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
#define mainON_BOARD_LED_BIT ( ( unsigned long ) 0x80 ) #define mainON_BOARD_LED_BIT ( ( unsigned long ) 0x80 )
@ -160,14 +160,14 @@ static long prvCheckOtherTasksAreStillRunning( unsigned long ulMemCheckTaskCount
* prvCheckOtherTasksAreStillRunning(). See the description at the top * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Dynamically created and deleted during each cycle of the vErrorChecks() * Dynamically created and deleted during each cycle of the vErrorChecks()
* task. This is done to check the operation of the memory allocator. * task. This is done to check the operation of the memory allocator.
* See the top of vErrorChecks for more details. * See the top of vErrorChecks for more details.
*/ */
static void vMemCheckTask( void *pvParameters ); static void vMemCheckTask( void * pvParameters );
/* /*
* Configure the processor for use with the Olimex demo board. This includes * Configure the processor for use with the Olimex demo board. This includes
@ -199,12 +199,12 @@ int main( void )
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Now all the tasks have been started - start the scheduler. /* Now all the tasks have been started - start the scheduler.
*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used here. */ * these demo application projects then ensure Supervisor mode is used here. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Should never reach here! */ /* Should never reach here! */
@ -212,30 +212,30 @@ int main( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
unsigned long ulMemCheckTaskRunningCount; unsigned long ulMemCheckTaskRunningCount;
TaskHandle_t xCreatedTask; TaskHandle_t xCreatedTask;
/* The parameters are not used in this function. */ /* The parameters are not used in this function. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period * operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so * is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. * the on board LED flash rate will increase.
*
* In addition to the standard tests the memory allocator is tested through
* the dynamic creation and deletion of a task each cycle. Each time the
* task is created memory must be allocated for its stack. When the task is
* deleted this memory is returned to the heap. If the task cannot be created
* then it is likely that the memory allocation failed. */
In addition to the standard tests the memory allocator is tested through for( ; ; )
the dynamic creation and deletion of a task each cycle. Each time the
task is created memory must be allocated for its stack. When the task is
deleted this memory is returned to the heap. If the task cannot be created
then it is likely that the memory allocation failed. */
for( ;; )
{ {
/* Dynamically create a task - passing ulMemCheckTaskRunningCount as a /* Dynamically create a task - passing ulMemCheckTaskRunningCount as a
parameter. */ * parameter. */
ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE; ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;
xCreatedTask = mainNO_TASK; xCreatedTask = mainNO_TASK;
@ -255,8 +255,8 @@ TaskHandle_t xCreatedTask;
} }
/* Check all the standard demo application tasks are executing without /* Check all the standard demo application tasks are executing without
error. ulMemCheckTaskRunningCount is checked to ensure it was * error. ulMemCheckTaskRunningCount is checked to ensure it was
modified by the task just deleted. */ * modified by the task just deleted. */
if( prvCheckOtherTasksAreStillRunning( ulMemCheckTaskRunningCount ) != pdPASS ) if( prvCheckOtherTasksAreStillRunning( ulMemCheckTaskRunningCount ) != pdPASS )
{ {
/* An error has been detected in one of the tasks - flash faster. */ /* An error has been detected in one of the tasks - flash faster. */
@ -280,22 +280,24 @@ static void prvSetupHardware( void )
PCB_PINSEL0 |= mainRX_ENABLE; PCB_PINSEL0 |= mainRX_ENABLE;
/* Set all GPIO to output other than the P0.14 (BSL), and the JTAG pins. /* Set all GPIO to output other than the P0.14 (BSL), and the JTAG pins.
The JTAG pins are left as input as I'm not sure what will happen if the * The JTAG pins are left as input as I'm not sure what will happen if the
Wiggler is connected after powerup - not that it would be a good idea to * Wiggler is connected after powerup - not that it would be a good idea to
do that anyway. */ * do that anyway. */
GPIO_IODIR = ~( mainP0_14 + mainJTAG_PORT ); GPIO_IODIR = ~( mainP0_14 + mainJTAG_PORT );
/* Setup the PLL to multiply the XTAL input by 4. */ /* Setup the PLL to multiply the XTAL input by 4. */
SCB_PLLCFG = ( mainPLL_MUL_4 | mainPLL_DIV_1 ); SCB_PLLCFG = ( mainPLL_MUL_4 | mainPLL_DIV_1 );
/* Activate the PLL by turning it on then feeding the correct sequence of /* Activate the PLL by turning it on then feeding the correct sequence of
bytes. */ * bytes. */
SCB_PLLCON = mainPLL_ENABLE; SCB_PLLCON = mainPLL_ENABLE;
SCB_PLLFEED = mainPLL_FEED_BYTE1; SCB_PLLFEED = mainPLL_FEED_BYTE1;
SCB_PLLFEED = mainPLL_FEED_BYTE2; SCB_PLLFEED = mainPLL_FEED_BYTE2;
/* Wait for the PLL to lock... */ /* Wait for the PLL to lock... */
while( !( SCB_PLLSTAT & mainPLL_LOCK ) ); while( !( SCB_PLLSTAT & mainPLL_LOCK ) )
{
}
/* ...before connecting it using the feed sequence again. */ /* ...before connecting it using the feed sequence again. */
SCB_PLLCON = mainPLL_CONNECT; SCB_PLLCON = mainPLL_CONNECT;
@ -303,8 +305,8 @@ static void prvSetupHardware( void )
SCB_PLLFEED = mainPLL_FEED_BYTE2; SCB_PLLFEED = mainPLL_FEED_BYTE2;
/* Setup and turn on the MAM. Three cycle access is used due to the fast /* Setup and turn on the MAM. Three cycle access is used due to the fast
PLL used. It is possible faster overall performance could be obtained by * PLL used. It is possible faster overall performance could be obtained by
tuning the MAM and PLL settings. */ * tuning the MAM and PLL settings. */
MAM_TIM = mainMAM_TIM_3; MAM_TIM = mainMAM_TIM_3;
MAM_CR = mainMAM_MODE_FULL; MAM_CR = mainMAM_MODE_FULL;
@ -318,9 +320,10 @@ static void prvSetupHardware( void )
void prvToggleOnBoardLED( void ) void prvToggleOnBoardLED( void )
{ {
unsigned long ulState; unsigned long ulState;
ulState = GPIO0_IOPIN; ulState = GPIO0_IOPIN;
if( ulState & mainON_BOARD_LED_BIT ) if( ulState & mainON_BOARD_LED_BIT )
{ {
GPIO_IOCLR = mainON_BOARD_LED_BIT; GPIO_IOCLR = mainON_BOARD_LED_BIT;
@ -334,11 +337,11 @@ unsigned long ulState;
static long prvCheckOtherTasksAreStillRunning( unsigned long ulMemCheckTaskCount ) static long prvCheckOtherTasksAreStillRunning( unsigned long ulMemCheckTaskCount )
{ {
long lReturn = ( long ) pdPASS; long lReturn = ( long ) pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected * that they are all still running, and that none of them have detected
an error. */ * an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -378,7 +381,7 @@ long lReturn = ( long ) pdPASS;
if( ulMemCheckTaskCount == mainCOUNT_INITIAL_VALUE ) if( ulMemCheckTaskCount == mainCOUNT_INITIAL_VALUE )
{ {
/* The vMemCheckTask did not increment the counter - it must /* The vMemCheckTask did not increment the counter - it must
have failed. */ * have failed. */
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
@ -386,26 +389,26 @@ long lReturn = ( long ) pdPASS;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vMemCheckTask( void *pvParameters ) static void vMemCheckTask( void * pvParameters )
{ {
unsigned long *pulMemCheckTaskRunningCounter; unsigned long * pulMemCheckTaskRunningCounter;
void *pvMem1, *pvMem2, *pvMem3; void * pvMem1, * pvMem2, * pvMem3;
static long lErrorOccurred = pdFALSE; static long lErrorOccurred = pdFALSE;
/* This task is dynamically created then deleted during each cycle of the /* This task is dynamically created then deleted during each cycle of the
vErrorChecks task to check the operation of the memory allocator. Each time * vErrorChecks task to check the operation of the memory allocator. Each time
the task is created memory is allocated for the stack and TCB. Each time * the task is created memory is allocated for the stack and TCB. Each time
the task is deleted this memory is returned to the heap. This task itself * the task is deleted this memory is returned to the heap. This task itself
exercises the allocator by allocating and freeing blocks. * exercises the allocator by allocating and freeing blocks.
*
The task executes at the idle priority so does not require a delay. * The task executes at the idle priority so does not require a delay.
*
pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the * pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the
vErrorChecks() task that this task is still executing without error. */ * vErrorChecks() task that this task is still executing without error. */
pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters; pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters;
for( ;; ) for( ; ; )
{ {
if( lErrorOccurred == pdFALSE ) if( lErrorOccurred == pdFALSE )
{ {
@ -414,11 +417,12 @@ static long lErrorOccurred = pdFALSE;
} }
/* Allocate some memory - just to give the allocator some extra /* Allocate some memory - just to give the allocator some extra
exercise. This has to be in a critical section to ensure the * exercise. This has to be in a critical section to ensure the
task does not get deleted while it has memory allocated. */ * task does not get deleted while it has memory allocated. */
vTaskSuspendAll(); vTaskSuspendAll();
{ {
pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 ); pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );
if( pvMem1 == NULL ) if( pvMem1 == NULL )
{ {
lErrorOccurred = pdTRUE; lErrorOccurred = pdTRUE;
@ -435,6 +439,7 @@ static long lErrorOccurred = pdFALSE;
vTaskSuspendAll(); vTaskSuspendAll();
{ {
pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 ); pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 );
if( pvMem2 == NULL ) if( pvMem2 == NULL )
{ {
lErrorOccurred = pdTRUE; lErrorOccurred = pdTRUE;
@ -451,6 +456,7 @@ static long lErrorOccurred = pdFALSE;
vTaskSuspendAll(); vTaskSuspendAll();
{ {
pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 ); pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );
if( pvMem3 == NULL ) if( pvMem3 == NULL )
{ {
lErrorOccurred = pdTRUE; lErrorOccurred = pdTRUE;
@ -464,6 +470,3 @@ static long lErrorOccurred = pdFALSE;
xTaskResumeAll(); xTaskResumeAll();
} }
} }

View file

@ -26,12 +26,12 @@
/* /*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used. * these demo application projects then ensure Supervisor mode is used.
*/ */
/* /*
@ -112,7 +112,7 @@
* prvCheckOtherTasksAreStillRunning(). See the description at the top * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Configures the processor for use with this demo. * Configures the processor for use with this demo.
@ -149,17 +149,16 @@ void main( void )
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Start the scheduler. /* Start the scheduler.
*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used here. * these demo application projects then ensure Supervisor mode is used here.
*/ */
vTaskStartScheduler(); vTaskStartScheduler();
/* We should never get here as control is now taken by the scheduler. */ /* We should never get here as control is now taken by the scheduler. */
return;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -169,13 +168,15 @@ static void prvSetupHardware( void )
PLLCFG = ( mainPLL_MUL_5 | mainPLL_DIV_1 ); PLLCFG = ( mainPLL_MUL_5 | mainPLL_DIV_1 );
/* Activate the PLL by turning it on then feeding the correct sequence of /* Activate the PLL by turning it on then feeding the correct sequence of
bytes. */ * bytes. */
PLLCON = mainPLL_ENABLE; PLLCON = mainPLL_ENABLE;
PLLFEED = mainPLL_FEED_BYTE1; PLLFEED = mainPLL_FEED_BYTE1;
PLLFEED = mainPLL_FEED_BYTE2; PLLFEED = mainPLL_FEED_BYTE2;
/* Wait for the PLL to lock... */ /* Wait for the PLL to lock... */
while( !( PLLSTAT & mainPLL_LOCK ) ); while( !( PLLSTAT & mainPLL_LOCK ) )
{
}
/* ...before connecting it using the feed sequence again. */ /* ...before connecting it using the feed sequence again. */
PLLCON = mainPLL_CONNECT; PLLCON = mainPLL_CONNECT;
@ -183,8 +184,8 @@ static void prvSetupHardware( void )
PLLFEED = mainPLL_FEED_BYTE2; PLLFEED = mainPLL_FEED_BYTE2;
/* Setup and turn on the MAM. Three cycle access is used due to the fast /* Setup and turn on the MAM. Three cycle access is used due to the fast
PLL used. It is possible faster overall performance could be obtained by * PLL used. It is possible faster overall performance could be obtained by
tuning the MAM and PLL settings. */ * tuning the MAM and PLL settings. */
MAMTIM = mainMAM_TIM_3; MAMTIM = mainMAM_TIM_3;
MAMCR = mainMAM_MODE_FULL; MAMCR = mainMAM_MODE_FULL;
@ -203,25 +204,25 @@ static void prvSetupHardware( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
/* The parameters are not used in this task. */ /* The parameters are not used in this task. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period * operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so * is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. */ * the on board LED flash rate will increase. */
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. */ /* Delay until it is time to execute again. */
vTaskDelay( xDelayPeriod ); vTaskDelay( xDelayPeriod );
/* Check all the standard demo application tasks are executing without /* Check all the standard demo application tasks are executing without
error. */ * error. */
if( prvCheckOtherTasksAreStillRunning() != pdPASS ) if( prvCheckOtherTasksAreStillRunning() != pdPASS )
{ {
/* An error has been detected in one of the tasks - flash faster. */ /* An error has been detected in one of the tasks - flash faster. */
@ -235,11 +236,11 @@ TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
static long prvCheckOtherTasksAreStillRunning( void ) static long prvCheckOtherTasksAreStillRunning( void )
{ {
long lReturn = ( long ) pdPASS; long lReturn = ( long ) pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected * that they are all still running, and that none of them have detected
an error. */ * an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -274,5 +275,3 @@ long lReturn = ( long ) pdPASS;
return lReturn; return lReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -25,12 +25,12 @@
*/ */
/* /*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used. * these demo application projects then ensure Supervisor mode is used.
*/ */
/* /*
@ -89,10 +89,10 @@
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
/* Constants used by the "check" task. As described at the head of this file /* Constants used by the "check" task. As described at the head of this file
the check task toggles an LED. The rate at which the LED flashes is used to * the check task toggles an LED. The rate at which the LED flashes is used to
indicate whether an error has been detected or not. If the LED toggles every * indicate whether an error has been detected or not. If the LED toggles every
3 seconds then no errors have been detected. If the rate increases to 500ms * 3 seconds then no errors have been detected. If the rate increases to 500ms
then an error has been detected in at least one of the demo application tasks. */ * then an error has been detected in at least one of the demo application tasks. */
#define mainCHECK_LED ( 7 ) #define mainCHECK_LED ( 7 )
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
@ -110,7 +110,7 @@ static long prvCheckOtherTasksAreStillRunning( void );
* prvCheckOtherTasksAreStillRunning(). See the description at the top * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Configure the processor for use with the Keil demo board. This is very * Configure the processor for use with the Keil demo board. This is very
@ -141,44 +141,46 @@ int main( void )
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
/* Start the check task - which is defined in this file. This is the task /* Start the check task - which is defined in this file. This is the task
that periodically checks to see that all the other tasks are executing * that periodically checks to see that all the other tasks are executing
without error. */ * without error. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Now all the tasks have been started - start the scheduler. /* Now all the tasks have been started - start the scheduler.
*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used here. */ * these demo application projects then ensure Supervisor mode is used here. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Should never reach here! If you do then there was not enough heap /* Should never reach here! If you do then there was not enough heap
available for the idle task to be created. */ * available for the idle task to be created. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
/* Parameters are not used. */ /* Parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period * operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so * is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. * the on board LED flash rate will increase.
*
* This task runs at the highest priority. */
This task runs at the highest priority. */ for( ; ; )
for( ;; )
{ {
/* The period of the delay depends on whether an error has been /* The period of the delay depends on whether an error has been
detected or not. If an error has been detected then the period * detected or not. If an error has been detected then the period
is reduced to increase the LED flash rate. */ * is reduced to increase the LED flash rate. */
vTaskDelay( xDelayPeriod ); vTaskDelay( xDelayPeriod );
if( prvCheckOtherTasksAreStillRunning() != pdPASS ) if( prvCheckOtherTasksAreStillRunning() != pdPASS )
@ -196,7 +198,7 @@ TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Perform the hardware setup required. This is minimal as most of the /* Perform the hardware setup required. This is minimal as most of the
setup is managed by the settings in the project file. */ * setup is managed by the settings in the project file. */
/* Configure the UART1 pins. All other pins remain at their default of 0. */ /* Configure the UART1 pins. All other pins remain at their default of 0. */
PINSEL0 |= mainTX_ENABLE; PINSEL0 |= mainTX_ENABLE;
@ -212,11 +214,11 @@ static void prvSetupHardware( void )
static long prvCheckOtherTasksAreStillRunning( void ) static long prvCheckOtherTasksAreStillRunning( void )
{ {
long lReturn = pdPASS; long lReturn = pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected * that they are all still running, and that none of them have detected
an error. */ * an error. */
if( xAreComTestTasksStillRunning() != pdPASS ) if( xAreComTestTasksStillRunning() != pdPASS )
{ {
lReturn = pdFAIL; lReturn = pdFAIL;
@ -245,5 +247,3 @@ long lReturn = pdPASS;
return lReturn; return lReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -104,22 +104,22 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The semaphore used to wake the button task from within the external interrupt /* The semaphore used to wake the button task from within the external interrupt
handler. */ * handler. */
SemaphoreHandle_t xButtonSemaphore; SemaphoreHandle_t xButtonSemaphore;
/* The queue that is used to send message to vPrintTask for display in the /* The queue that is used to send message to vPrintTask for display in the
terminal output window. */ * terminal output window. */
QueueHandle_t xPrintQueue; QueueHandle_t xPrintQueue;
/* The rate at which the LED will toggle. The toggle rate increases if an /* The rate at which the LED will toggle. The toggle rate increases if an
error is detected in any task. */ * error is detected in any task. */
static TickType_t xLED_Delay = mainLED_DELAY; static TickType_t xLED_Delay = mainLED_DELAY;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Simply flashes the on board LED every mainLED_DELAY milliseconds. * Simply flashes the on board LED every mainLED_DELAY milliseconds.
*/ */
static void vLEDTask( void *pvParameters ); static void vLEDTask( void * pvParameters );
/* /*
* Checks the status of all the demo tasks then prints a message to the * Checks the status of all the demo tasks then prints a message to the
@ -130,21 +130,21 @@ static void vLEDTask( void *pvParameters );
* Messages are not written directly to the terminal, but passed to vPrintTask * Messages are not written directly to the terminal, but passed to vPrintTask
* via a queue. * via a queue.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* Controls all terminal output. If a task wants to send a message to the * Controls all terminal output. If a task wants to send a message to the
* terminal IO it posts a pointer to the text to vPrintTask via a queue. This * terminal IO it posts a pointer to the text to vPrintTask via a queue. This
* ensures serial access to the terminal IO. * ensures serial access to the terminal IO.
*/ */
static void vPrintTask( void *pvParameter ); static void vPrintTask( void * pvParameter );
/* /*
* Simply waits for an interrupt to be generated from the built in button, then * Simply waits for an interrupt to be generated from the built in button, then
* generates a table of tasks states that is then written by vPrintTask to the * generates a table of tasks states that is then written by vPrintTask to the
* terminal output window within CrossStudio. * terminal output window within CrossStudio.
*/ */
static void vButtonHandlerTask( void *pvParameters ); static void vButtonHandlerTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -170,7 +170,7 @@ int main( void )
#if configUSE_PREEMPTION == 1 #if configUSE_PREEMPTION == 1
{ {
/* The timing of console output when not using the preemptive /* The timing of console output when not using the preemptive
scheduler causes the block time tests to detect a timing problem. */ * scheduler causes the block time tests to detect a timing problem. */
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
} }
#endif #endif
@ -187,13 +187,13 @@ int main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* The scheduler should now be running, so we will only ever reach here if we /* The scheduler should now be running, so we will only ever reach here if we
ran out of heap space. */ * ran out of heap space. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vLEDTask( void *pvParameters ) static void vLEDTask( void * pvParameters )
{ {
/* Just to remove compiler warnings. */ /* Just to remove compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
@ -202,7 +202,7 @@ static void vLEDTask( void *pvParameters )
IO0DIR |= mainLED_BIT; IO0DIR |= mainLED_BIT;
IO0SET = mainLED_BIT; IO0SET = mainLED_BIT;
for( ;; ) for( ; ; )
{ {
/* Not very exiting - just delay... */ /* Not very exiting - just delay... */
vTaskDelay( xLED_Delay ); vTaskDelay( xLED_Delay );
@ -219,21 +219,21 @@ static void vLEDTask( void *pvParameters )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
portBASE_TYPE xErrorOccurred = pdFALSE; portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
const char * const pcPassMessage = "PASS\n"; const char * const pcPassMessage = "PASS\n";
const char * const pcFailMessage = "FAIL\n"; const char * const pcFailMessage = "FAIL\n";
/* Just to remove compiler warnings. */ /* Just to remove compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Perform this check every mainCHECK_DELAY milliseconds. */ /* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
@ -268,7 +268,7 @@ const char * const pcFailMessage = "FAIL\n";
#if configUSE_PREEMPTION == 1 #if configUSE_PREEMPTION == 1
{ {
/* The timing of console output when not using the preemptive /* The timing of console output when not using the preemptive
scheduler causes the block time tests to detect a timing problem. */ * scheduler causes the block time tests to detect a timing problem. */
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
@ -282,7 +282,7 @@ const char * const pcFailMessage = "FAIL\n";
} }
/* Send either a pass or fail message. If an error is found it is /* Send either a pass or fail message. If an error is found it is
never cleared again. */ * never cleared again. */
if( xErrorOccurred == pdTRUE ) if( xErrorOccurred == pdTRUE )
{ {
xLED_Delay = mainERROR_LED_DELAY; xLED_Delay = mainERROR_LED_DELAY;
@ -296,17 +296,19 @@ const char * const pcFailMessage = "FAIL\n";
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters ) static void vPrintTask( void * pvParameters )
{ {
char *pcMessage; char * pcMessage;
/* Just to stop compiler warnings. */ /* Just to stop compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
/* Wait for a message to arrive. */ /* Wait for a message to arrive. */
while( xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY ) != pdPASS ); while( xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY ) != pdPASS )
{
}
/* Write the message to the terminal IO. */ /* Write the message to the terminal IO. */
#ifndef NDEBUG #ifndef NDEBUG
@ -316,12 +318,13 @@ char *pcMessage;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vButtonHandlerTask( void *pvParameters ) static void vButtonHandlerTask( void * pvParameters )
{ {
static char cListBuffer[ mainLIST_BUFFER_SIZE ]; static char cListBuffer[ mainLIST_BUFFER_SIZE ];
const char *pcList = &( cListBuffer[ 0 ] ); const char * pcList = &( cListBuffer[ 0 ] );
const char * const pcHeader = "\nTask State Priority Stack #\n************************************************"; const char * const pcHeader = "\nTask State Priority Stack #\n************************************************";
extern void (vButtonISRWrapper) ( void );
extern void( vButtonISRWrapper ) ( void );
/* Just to stop compiler warnings. */ /* Just to stop compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
@ -342,7 +345,7 @@ extern void (vButtonISRWrapper) ( void );
} }
portEXIT_CRITICAL(); portEXIT_CRITICAL();
for( ;; ) for( ; ; )
{ {
/* For debouncing, wait a while then clear the semaphore. */ /* For debouncing, wait a while then clear the semaphore. */
vTaskDelay( mainSHORT_DELAY ); vTaskDelay( mainSHORT_DELAY );
@ -363,17 +366,15 @@ extern void (vButtonISRWrapper) ( void );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
/* Check pcTaskName for the name of the offending task, or pxCurrentTCB /* Check pcTaskName for the name of the offending task, or pxCurrentTCB
if pcTaskName has itself been corrupted. */ * if pcTaskName has itself been corrupted. */
( void ) pxTask; ( void ) pxTask;
( void ) pcTaskName; ( void ) pcTaskName;
for( ;; );
for( ; ; )
{
}
} }

View file

@ -35,21 +35,21 @@
* the work. This work should not be done in the wrapper itself unless * the work. This work should not be done in the wrapper itself unless
* you are absolutely sure that no stack space is used. * you are absolutely sure that no stack space is used.
*/ */
void vButtonISRWrapper( void ) __attribute__ ((naked)); void vButtonISRWrapper( void ) __attribute__( ( naked ) );
void vButtonHandler( void ) __attribute__ ((noinline)); void vButtonHandler( void ) __attribute__( ( noinline ) );
void vButtonHandler( void ) void vButtonHandler( void )
{ {
extern SemaphoreHandle_t xButtonSemaphore; extern SemaphoreHandle_t xButtonSemaphore;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );
if( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken )
{ {
/* We have woken a task. Calling "yield from ISR" here will ensure /* We have woken a task. Calling "yield from ISR" here will ensure
the interrupt returns to the woken task if it has a priority higher * the interrupt returns to the woken task if it has a priority higher
than the interrupted task. */ * than the interrupted task. */
portYIELD_FROM_ISR(); portYIELD_FROM_ISR();
} }
@ -64,13 +64,10 @@ void vButtonISRWrapper( void )
portSAVE_CONTEXT(); portSAVE_CONTEXT();
/* Call the handler to do the work. This must be a separate function to /* Call the handler to do the work. This must be a separate function to
the wrapper to ensure the correct stack frame is set up. */ * the wrapper to ensure the correct stack frame is set up. */
__asm volatile( "bl vButtonHandler" ); __asm volatile ( "bl vButtonHandler" );
/* Restore the context of whichever task is going to run once the interrupt /* Restore the context of whichever task is going to run once the interrupt
completes. */ * completes. */
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }

View file

@ -25,12 +25,12 @@
*/ */
/* /*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used. * these demo application projects then ensure Supervisor mode is used.
*/ */
/* /*
* Creates all the demo application tasks, then starts the scheduler. The WEB * Creates all the demo application tasks, then starts the scheduler. The WEB
@ -90,7 +90,7 @@
* prvCheckOtherTasksAreStillRunning(). See the description at the top * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Configure the processor for use with the IAR STR71x demo board. This * Configure the processor for use with the IAR STR71x demo board. This
@ -113,7 +113,7 @@ static long prvCheckOtherTasksAreStillRunning( void );
void main( void ) void main( void )
{ {
/* Setup any hardware that has not already been configured by the low /* Setup any hardware that has not already been configured by the low
level init routines. */ * level init routines. */
prvSetupHardware(); prvSetupHardware();
/* Initialise the LED outputs for use by the demo application tasks. */ /* Initialise the LED outputs for use by the demo application tasks. */
@ -132,17 +132,16 @@ void main( void )
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Start the scheduler. /* Start the scheduler.
*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used here. */ * these demo application projects then ensure Supervisor mode is used here. */
vTaskStartScheduler(); vTaskStartScheduler();
/* We should never get here as control is now taken by the scheduler. */ /* We should never get here as control is now taken by the scheduler. */
return;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -159,31 +158,31 @@ static void prvSetupHardware( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
TickType_t xLastWakeTime; TickType_t xLastWakeTime;
/* The parameters are not used in this task. */ /* The parameters are not used in this task. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil() /* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil()
functions correctly. */ * functions correctly. */
xLastWakeTime = xTaskGetTickCount(); xLastWakeTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period * operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so * is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. */ * the on board LED flash rate will increase. */
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. The delay period is /* Delay until it is time to execute again. The delay period is
shorter following an error so the LED flashes faster. */ * shorter following an error so the LED flashes faster. */
vTaskDelayUntil( &xLastWakeTime, xDelayPeriod ); vTaskDelayUntil( &xLastWakeTime, xDelayPeriod );
/* Check all the standard demo application tasks are executing without /* Check all the standard demo application tasks are executing without
error. */ * error. */
if( prvCheckOtherTasksAreStillRunning() != pdPASS ) if( prvCheckOtherTasksAreStillRunning() != pdPASS )
{ {
/* An error has been detected in one of the tasks - flash faster. */ /* An error has been detected in one of the tasks - flash faster. */
@ -197,11 +196,11 @@ TickType_t xLastWakeTime;
static long prvCheckOtherTasksAreStillRunning( void ) static long prvCheckOtherTasksAreStillRunning( void )
{ {
long lReturn = ( long ) pdPASS; long lReturn = ( long ) pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected * that they are all still running, and that none of them have detected
an error. */ * an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -236,5 +235,3 @@ long lReturn = ( long ) pdPASS;
return lReturn; return lReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -76,19 +76,19 @@
#define mainCHECK_TASK_CYCLE_TIME ( 3000 ) #define mainCHECK_TASK_CYCLE_TIME ( 3000 )
/* The maximum offset into the pass and fail strings sent to the LCD. An /* The maximum offset into the pass and fail strings sent to the LCD. An
offset is used a simple method of using a different column each time a message * offset is used a simple method of using a different column each time a message
is written to the LCD. */ * is written to the LCD. */
#define mainMAX_WRITE_COLUMN ( 14 ) #define mainMAX_WRITE_COLUMN ( 14 )
/* Baud rate used by the comtest tasks. */ /* Baud rate used by the comtest tasks. */
#define mainCOM_TEST_BAUD_RATE ( 19200 ) #define mainCOM_TEST_BAUD_RATE ( 19200 )
/* The LED used by the comtest tasks. See the comtest.c file for more /* The LED used by the comtest tasks. See the comtest.c file for more
information. */ * information. */
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
/* The number of messages that can be queued for display on the LCD at any one /* The number of messages that can be queued for display on the LCD at any one
time. */ * time. */
#define mainLCD_QUEUE_LENGTH ( 2 ) #define mainLCD_QUEUE_LENGTH ( 2 )
/* The time to wait when sending to mainLCD_QUEUE_LENGTH. */ /* The time to wait when sending to mainLCD_QUEUE_LENGTH. */
@ -99,7 +99,7 @@ time. */
/* The type that is posted to the LCD queue. */ /* The type that is posted to the LCD queue. */
typedef struct LCD_MESSAGE typedef struct LCD_MESSAGE
{ {
unsigned char *pucString; /* Points to the string to be displayed. */ unsigned char * pucString; /* Points to the string to be displayed. */
unsigned char ucLine; /* The line of the LCD that should be used. */ unsigned char ucLine; /* The line of the LCD that should be used. */
} LCDMessage; } LCDMessage;
@ -110,12 +110,12 @@ typedef struct LCD_MESSAGE
* all the other tasks in the system. See the description at the top of the * all the other tasks in the system. See the description at the top of the
* file. * file.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* ST provided routine to configure the processor. * ST provided routine to configure the processor.
*/ */
static void prvSetupHardware(void); static void prvSetupHardware( void );
/* /*
* The only task that should access the LCD. Other tasks wanting to write * The only task that should access the LCD. Other tasks wanting to write
@ -124,7 +124,7 @@ static void prvSetupHardware(void);
* waiting for the arrival of such messages, displays the message, then blocks * waiting for the arrival of such messages, displays the message, then blocks
* again. * again.
*/ */
static void vPrintTask( void *pvParameters ); static void vPrintTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -144,7 +144,7 @@ int main( void )
xLCDQueue = xQueueCreate( mainLCD_QUEUE_LENGTH, sizeof( LCDMessage ) ); xLCDQueue = xQueueCreate( mainLCD_QUEUE_LENGTH, sizeof( LCDMessage ) );
/* Create the standard demo application tasks. See the WEB documentation /* Create the standard demo application tasks. See the WEB documentation
for more information on these tasks. */ * for more information on these tasks. */
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
@ -159,25 +159,25 @@ int main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Execution will only reach here if there was insufficient heap to /* Execution will only reach here if there was insufficient heap to
start the scheduler. */ * start the scheduler. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
static unsigned long ulErrorDetected = pdFALSE; static unsigned long ulErrorDetected = pdFALSE;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
unsigned char *ucErrorMessage = ( unsigned char * )" FAIL"; unsigned char * ucErrorMessage = ( unsigned char * ) " FAIL";
unsigned char *ucSuccessMessage = ( unsigned char * )" PASS"; unsigned char * ucSuccessMessage = ( unsigned char * ) " PASS";
unsigned portBASE_TYPE uxColumn = mainMAX_WRITE_COLUMN; unsigned portBASE_TYPE uxColumn = mainMAX_WRITE_COLUMN;
LCDMessage xMessage; LCDMessage xMessage;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Wait until it is time for the next cycle. */ /* Wait until it is time for the next cycle. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_TASK_CYCLE_TIME ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_TASK_CYCLE_TIME );
@ -210,14 +210,14 @@ LCDMessage xMessage;
} }
/* Calculate the LCD line on which we would like the message to /* Calculate the LCD line on which we would like the message to
be displayed. The column variable is used for convenience as * be displayed. The column variable is used for convenience as
it is incremented each cycle anyway. */ * it is incremented each cycle anyway. */
xMessage.ucLine = ( unsigned char ) ( uxColumn & 0x01 ); xMessage.ucLine = ( unsigned char ) ( uxColumn & 0x01 );
/* The message displayed depends on whether an error was found or /* The message displayed depends on whether an error was found or
not. Any discovered error is latched. Here the column variable * not. Any discovered error is latched. Here the column variable
is used as an index into the text string as a simple way of moving * is used as an index into the text string as a simple way of moving
the text from column to column. */ * the text from column to column. */
if( ulErrorDetected == pdFALSE ) if( ulErrorDetected == pdFALSE )
{ {
xMessage.pucString = ucSuccessMessage + uxColumn; xMessage.pucString = ucSuccessMessage + uxColumn;
@ -231,8 +231,9 @@ LCDMessage xMessage;
xQueueSend( xLCDQueue, ( void * ) &xMessage, mainNO_DELAY ); xQueueSend( xLCDQueue, ( void * ) &xMessage, mainNO_DELAY );
/* Make sure the message is printed in a different column the next /* Make sure the message is printed in a different column the next
time around. */ * time around. */
uxColumn--; uxColumn--;
if( uxColumn == 0 ) if( uxColumn == 0 )
{ {
uxColumn = mainMAX_WRITE_COLUMN; uxColumn = mainMAX_WRITE_COLUMN;
@ -242,26 +243,28 @@ LCDMessage xMessage;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters ) static void vPrintTask( void * pvParameters )
{ {
LCDMessage xMessage; LCDMessage xMessage;
for( ;; ) for( ; ; )
{ {
/* Wait until a message arrives. */ /* Wait until a message arrives. */
while( xQueueReceive( xLCDQueue, ( void * ) &xMessage, portMAX_DELAY ) != pdPASS ); while( xQueueReceive( xLCDQueue, ( void * ) &xMessage, portMAX_DELAY ) != pdPASS )
{
}
/* The message contains the text to display, and the line on which the /* The message contains the text to display, and the line on which the
text should be displayed. */ * text should be displayed. */
LCD_Clear(); LCD_Clear();
LCD_DisplayString( xMessage.ucLine, xMessage.pucString, BlackText ); LCD_DisplayString( xMessage.ucLine, xMessage.pucString, BlackText );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware(void) static void prvSetupHardware( void )
{ {
ErrorStatus OSC4MStartUpStatus01; ErrorStatus OSC4MStartUpStatus01;
/* ST provided routine. */ /* ST provided routine. */
@ -271,42 +274,41 @@ ErrorStatus OSC4MStartUpStatus01;
/* Wait for OSC4M start-up */ /* Wait for OSC4M start-up */
OSC4MStartUpStatus01 = MRCC_WaitForOSC4MStartUp(); OSC4MStartUpStatus01 = MRCC_WaitForOSC4MStartUp();
if(OSC4MStartUpStatus01 == SUCCESS) if( OSC4MStartUpStatus01 == SUCCESS )
{ {
/* Set HCLK to 60MHz */ /* Set HCLK to 60MHz */
MRCC_HCLKConfig(MRCC_CKSYS_Div1); MRCC_HCLKConfig( MRCC_CKSYS_Div1 );
/* Set CKTIM to 60MHz */ /* Set CKTIM to 60MHz */
MRCC_CKTIMConfig(MRCC_HCLK_Div1); MRCC_CKTIMConfig( MRCC_HCLK_Div1 );
/* Set PCLK to 30MHz */ /* Set PCLK to 30MHz */
MRCC_PCLKConfig(MRCC_CKTIM_Div2); MRCC_PCLKConfig( MRCC_CKTIM_Div2 );
/* Enable Flash Burst mode */ /* Enable Flash Burst mode */
CFG_FLASHBurstConfig(CFG_FLASHBurst_Enable); CFG_FLASHBurstConfig( CFG_FLASHBurst_Enable );
/* Set CK_SYS to 60 MHz */ /* Set CK_SYS to 60 MHz */
MRCC_CKSYSConfig(MRCC_CKSYS_OSC4MPLL, MRCC_PLL_Mul_15); MRCC_CKSYSConfig( MRCC_CKSYS_OSC4MPLL, MRCC_PLL_Mul_15 );
} }
/* GPIO pins optimized for 3V3 operation */ /* GPIO pins optimized for 3V3 operation */
MRCC_IOVoltageRangeConfig(MRCC_IOVoltageRange_3V3); MRCC_IOVoltageRangeConfig( MRCC_IOVoltageRange_3V3 );
/* GPIO clock source enable */ /* GPIO clock source enable */
MRCC_PeripheralClockConfig(MRCC_Peripheral_GPIO, ENABLE); MRCC_PeripheralClockConfig( MRCC_Peripheral_GPIO, ENABLE );
/* EXTIT clock source enable */ /* EXTIT clock source enable */
MRCC_PeripheralClockConfig(MRCC_Peripheral_EXTIT, ENABLE); MRCC_PeripheralClockConfig( MRCC_Peripheral_EXTIT, ENABLE );
/* TB clock source enable */ /* TB clock source enable */
MRCC_PeripheralClockConfig(MRCC_Peripheral_TB, ENABLE); MRCC_PeripheralClockConfig( MRCC_Peripheral_TB, ENABLE );
/* Initialize the demonstration menu */ /* Initialize the demonstration menu */
LCD_Init(); LCD_Init();
LCD_DisplayString(Line1, ( unsigned char * ) "www.FreeRTOS.org", BlackText); LCD_DisplayString( Line1, ( unsigned char * ) "www.FreeRTOS.org", BlackText );
LCD_DisplayString(Line2, ( unsigned char * ) " STR750 Demo ", BlackText); LCD_DisplayString( Line2, ( unsigned char * ) " STR750 Demo ", BlackText );
EIC_IRQCmd(ENABLE); EIC_IRQCmd( ENABLE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -76,19 +76,19 @@
#define mainCHECK_TASK_CYCLE_TIME ( 3000 ) #define mainCHECK_TASK_CYCLE_TIME ( 3000 )
/* The maximum offset into the pass and fail strings sent to the LCD. An /* The maximum offset into the pass and fail strings sent to the LCD. An
offset is used a simple method of using a different column each time a message * offset is used a simple method of using a different column each time a message
is written to the LCD. */ * is written to the LCD. */
#define mainMAX_WRITE_COLUMN ( 14 ) #define mainMAX_WRITE_COLUMN ( 14 )
/* Baud rate used by the comtest tasks. */ /* Baud rate used by the comtest tasks. */
#define mainCOM_TEST_BAUD_RATE ( 19200 ) #define mainCOM_TEST_BAUD_RATE ( 19200 )
/* The LED used by the comtest tasks. See the comtest.c file for more /* The LED used by the comtest tasks. See the comtest.c file for more
information. */ * information. */
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
/* The number of messages that can be queued for display on the LCD at any one /* The number of messages that can be queued for display on the LCD at any one
time. */ * time. */
#define mainLCD_QUEUE_LENGTH ( 2 ) #define mainLCD_QUEUE_LENGTH ( 2 )
/* The time to wait when sending to mainLCD_QUEUE_LENGTH. */ /* The time to wait when sending to mainLCD_QUEUE_LENGTH. */
@ -99,7 +99,7 @@ time. */
/* The type that is posted to the LCD queue. */ /* The type that is posted to the LCD queue. */
typedef struct LCD_MESSAGE typedef struct LCD_MESSAGE
{ {
unsigned char *pucString; /* Points to the string to be displayed. */ unsigned char * pucString; /* Points to the string to be displayed. */
unsigned char ucLine; /* The line of the LCD that should be used. */ unsigned char ucLine; /* The line of the LCD that should be used. */
} LCDMessage; } LCDMessage;
@ -110,12 +110,12 @@ typedef struct LCD_MESSAGE
* all the other tasks in the system. See the description at the top of the * all the other tasks in the system. See the description at the top of the
* file. * file.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* ST provided routine to configure the processor. * ST provided routine to configure the processor.
*/ */
static void prvSetupHardware(void); static void prvSetupHardware( void );
/* /*
* The only task that should access the LCD. Other tasks wanting to write * The only task that should access the LCD. Other tasks wanting to write
@ -124,7 +124,7 @@ static void prvSetupHardware(void);
* waiting for the arrival of such messages, displays the message, then blocks * waiting for the arrival of such messages, displays the message, then blocks
* again. * again.
*/ */
static void vPrintTask( void *pvParameters ); static void vPrintTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -144,7 +144,7 @@ void main( void )
xLCDQueue = xQueueCreate( mainLCD_QUEUE_LENGTH, sizeof( LCDMessage ) ); xLCDQueue = xQueueCreate( mainLCD_QUEUE_LENGTH, sizeof( LCDMessage ) );
/* Create the standard demo application tasks. See the WEB documentation /* Create the standard demo application tasks. See the WEB documentation
for more information on these tasks. */ * for more information on these tasks. */
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
@ -159,24 +159,24 @@ void main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Execution will only reach here if there was insufficient heap to /* Execution will only reach here if there was insufficient heap to
start the scheduler. */ * start the scheduler. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
static unsigned long ulErrorDetected = pdFALSE; static unsigned long ulErrorDetected = pdFALSE;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
unsigned char *cErrorMessage = " FAIL"; unsigned char * cErrorMessage = " FAIL";
unsigned char *cSuccessMessage = " PASS"; unsigned char * cSuccessMessage = " PASS";
unsigned portBASE_TYPE uxColumn = mainMAX_WRITE_COLUMN; unsigned portBASE_TYPE uxColumn = mainMAX_WRITE_COLUMN;
LCDMessage xMessage; LCDMessage xMessage;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Wait until it is time for the next cycle. */ /* Wait until it is time for the next cycle. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_TASK_CYCLE_TIME ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_TASK_CYCLE_TIME );
@ -209,14 +209,14 @@ LCDMessage xMessage;
} }
/* Calculate the LCD line on which we would like the message to /* Calculate the LCD line on which we would like the message to
be displayed. The column variable is used for convenience as * be displayed. The column variable is used for convenience as
it is incremented each cycle anyway. */ * it is incremented each cycle anyway. */
xMessage.ucLine = ( unsigned char ) ( uxColumn & 0x01 ); xMessage.ucLine = ( unsigned char ) ( uxColumn & 0x01 );
/* The message displayed depends on whether an error was found or /* The message displayed depends on whether an error was found or
not. Any discovered error is latched. Here the column variable * not. Any discovered error is latched. Here the column variable
is used as an index into the text string as a simple way of moving * is used as an index into the text string as a simple way of moving
the text from column to column. */ * the text from column to column. */
if( ulErrorDetected == pdFALSE ) if( ulErrorDetected == pdFALSE )
{ {
xMessage.pucString = cSuccessMessage + uxColumn; xMessage.pucString = cSuccessMessage + uxColumn;
@ -230,8 +230,9 @@ LCDMessage xMessage;
xQueueSend( xLCDQueue, ( void * ) &xMessage, mainNO_DELAY ); xQueueSend( xLCDQueue, ( void * ) &xMessage, mainNO_DELAY );
/* Make sure the message is printed in a different column the next /* Make sure the message is printed in a different column the next
time around. */ * time around. */
uxColumn--; uxColumn--;
if( uxColumn == 0 ) if( uxColumn == 0 )
{ {
uxColumn = mainMAX_WRITE_COLUMN; uxColumn = mainMAX_WRITE_COLUMN;
@ -240,26 +241,28 @@ LCDMessage xMessage;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters ) static void vPrintTask( void * pvParameters )
{ {
LCDMessage xMessage; LCDMessage xMessage;
for( ;; ) for( ; ; )
{ {
/* Wait until a message arrives. */ /* Wait until a message arrives. */
while( xQueueReceive( xLCDQueue, ( void * ) &xMessage, portMAX_DELAY ) != pdPASS ); while( xQueueReceive( xLCDQueue, ( void * ) &xMessage, portMAX_DELAY ) != pdPASS )
{
}
/* The message contains the text to display, and the line on which the /* The message contains the text to display, and the line on which the
text should be displayed. */ * text should be displayed. */
LCD_Clear(); LCD_Clear();
LCD_DisplayString( xMessage.ucLine, xMessage.pucString, BlackText ); LCD_DisplayString( xMessage.ucLine, xMessage.pucString, BlackText );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware(void) static void prvSetupHardware( void )
{ {
ErrorStatus OSC4MStartUpStatus01; ErrorStatus OSC4MStartUpStatus01;
/* ST provided routine. */ /* ST provided routine. */
@ -269,41 +272,41 @@ ErrorStatus OSC4MStartUpStatus01;
/* Wait for OSC4M start-up */ /* Wait for OSC4M start-up */
OSC4MStartUpStatus01 = MRCC_WaitForOSC4MStartUp(); OSC4MStartUpStatus01 = MRCC_WaitForOSC4MStartUp();
if(OSC4MStartUpStatus01 == SUCCESS) if( OSC4MStartUpStatus01 == SUCCESS )
{ {
/* Set HCLK to 60MHz */ /* Set HCLK to 60MHz */
MRCC_HCLKConfig(MRCC_CKSYS_Div1); MRCC_HCLKConfig( MRCC_CKSYS_Div1 );
/* Set CKTIM to 60MHz */ /* Set CKTIM to 60MHz */
MRCC_CKTIMConfig(MRCC_HCLK_Div1); MRCC_CKTIMConfig( MRCC_HCLK_Div1 );
/* Set PCLK to 30MHz */ /* Set PCLK to 30MHz */
MRCC_PCLKConfig(MRCC_CKTIM_Div2); MRCC_PCLKConfig( MRCC_CKTIM_Div2 );
/* Enable Flash Burst mode */ /* Enable Flash Burst mode */
CFG_FLASHBurstConfig(CFG_FLASHBurst_Enable); CFG_FLASHBurstConfig( CFG_FLASHBurst_Enable );
/* Set CK_SYS to 60 MHz */ /* Set CK_SYS to 60 MHz */
MRCC_CKSYSConfig(MRCC_CKSYS_OSC4MPLL, MRCC_PLL_Mul_15); MRCC_CKSYSConfig( MRCC_CKSYS_OSC4MPLL, MRCC_PLL_Mul_15 );
} }
/* GPIO pins optimized for 3V3 operation */ /* GPIO pins optimized for 3V3 operation */
MRCC_IOVoltageRangeConfig(MRCC_IOVoltageRange_3V3); MRCC_IOVoltageRangeConfig( MRCC_IOVoltageRange_3V3 );
/* GPIO clock source enable */ /* GPIO clock source enable */
MRCC_PeripheralClockConfig(MRCC_Peripheral_GPIO, ENABLE); MRCC_PeripheralClockConfig( MRCC_Peripheral_GPIO, ENABLE );
/* EXTIT clock source enable */ /* EXTIT clock source enable */
MRCC_PeripheralClockConfig(MRCC_Peripheral_EXTIT, ENABLE); MRCC_PeripheralClockConfig( MRCC_Peripheral_EXTIT, ENABLE );
/* TB clock source enable */ /* TB clock source enable */
MRCC_PeripheralClockConfig(MRCC_Peripheral_TB, ENABLE); MRCC_PeripheralClockConfig( MRCC_Peripheral_TB, ENABLE );
/* Initialize the demonstration menu */ /* Initialize the demonstration menu */
LCD_Init(); LCD_Init();
LCD_DisplayString(Line1, "www.FreeRTOS.org", BlackText); LCD_DisplayString( Line1, "www.FreeRTOS.org", BlackText );
LCD_DisplayString(Line2, " STR750 Demo ", BlackText); LCD_DisplayString( Line2, " STR750 Demo ", BlackText );
EIC_IRQCmd(ENABLE); EIC_IRQCmd( ENABLE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -85,7 +85,7 @@
static void prvSetupHardware( void ); static void prvSetupHardware( void );
/* The check task as described at the top of this file. */ /* The check task as described at the top of this file. */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main() int main()
@ -94,8 +94,8 @@ int main()
prvSetupHardware(); prvSetupHardware();
/* First create the 'standard demo' tasks. These exist just to to /* First create the 'standard demo' tasks. These exist just to to
demonstrate API functions being used and test the kernel port. More * demonstrate API functions being used and test the kernel port. More
information is provided on the FreeRTOS.org WEB site. */ * information is provided on the FreeRTOS.org WEB site. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
@ -109,42 +109,44 @@ int main()
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
/* Create the check task - this is the task that checks all the other tasks /* Create the check task - this is the task that checks all the other tasks
are executing as expected and without reporting any errors. */ * are executing as expected and without reporting any errors. */
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL ); xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
/* The death demo tasks must be started last as the sanity checks performed /* The death demo tasks must be started last as the sanity checks performed
require knowledge of the number of other tasks in the system. */ * require knowledge of the number of other tasks in the system. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the scheduler. From this point on the execution will be under /* Start the scheduler. From this point on the execution will be under
the control of the kernel. */ * the control of the kernel. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient heap available for the /* Will only get here if there was insufficient heap available for the
idle task to be created. */ * idle task to be created. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTask( void * pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
TickType_t xNextWakeTime, xPeriod = mainNO_ERROR_PERIOD; TickType_t xNextWakeTime, xPeriod = mainNO_ERROR_PERIOD;
static volatile unsigned long ulErrorCode = 0UL; static volatile unsigned long ulErrorCode = 0UL;
/* Just to remove the compiler warning. */ /* Just to remove the compiler warning. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise xNextWakeTime prior to its first use. From this point on /* Initialise xNextWakeTime prior to its first use. From this point on
the value of the variable is handled automatically by the kernel. */ * the value of the variable is handled automatically by the kernel. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Delay until it is time for this task to execute again. */ /* Delay until it is time for this task to execute again. */
vTaskDelayUntil( &xNextWakeTime, xPeriod ); vTaskDelayUntil( &xNextWakeTime, xPeriod );
/* Check all the other tasks in the system - latch any reported errors /* Check all the other tasks in the system - latch any reported errors
into the ulErrorCode variable. */ * into the ulErrorCode variable. */
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
ulErrorCode |= 0x01UL; ulErrorCode |= 0x01UL;
@ -206,9 +208,9 @@ static volatile unsigned long ulErrorCode = 0UL;
} }
/* Reduce the block period and in so doing increase the frequency at /* Reduce the block period and in so doing increase the frequency at
which this task executes if any errors have been latched. The increased * which this task executes if any errors have been latched. The increased
frequency causes the LED toggle rate to increase and so gives some * frequency causes the LED toggle rate to increase and so gives some
visual feedback that an error has occurred. */ * visual feedback that an error has occurred. */
if( ulErrorCode != 0x00 ) if( ulErrorCode != 0x00 )
{ {
xPeriod = mainERROR_PERIOD; xPeriod = mainERROR_PERIOD;
@ -222,7 +224,7 @@ static volatile unsigned long ulErrorCode = 0UL;
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
const Pin xPins[] = { PIN_USART0_RXD, PIN_USART0_TXD }; const Pin xPins[] = { PIN_USART0_RXD, PIN_USART0_TXD };
/* Setup the LED outputs. */ /* Setup the LED outputs. */
vParTestInitialise(); vParTestInitialise();

View file

@ -25,7 +25,8 @@
*/ */
/*This file has been prepared for Doxygen automatic documentation generation.*/ /*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
/* \file *********************************************************************
* *
* \brief FreeRTOS Real Time Kernel example. * \brief FreeRTOS Real Time Kernel example.
* *
@ -79,10 +80,9 @@
#include "death.h" #include "death.h"
#include "flop.h" #include "flop.h"
/*! \name Priority definitions for most of the tasks in the demo application. /* Priority definitions for most of the tasks in the demo application.
* Some tasks just use the idle priority. * Some tasks just use the idle priority.
*/ */
//! @{
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
@ -90,45 +90,38 @@
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
//! @}
//! Baud rate used by the serial port tasks. /* Baud rate used by the serial port tasks. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 57600 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 57600 )
//! LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
//! and mainCOM_TEST_LED + 1 is toggled on each character Rx. * and mainCOM_TEST_LED + 1 is toggled on each character Rx. */
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
//! LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
//! that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
//! the LED is toggled. If an error is found at any time the LED toggles faster. * the LED is toggled. If an error is found at any time the LED toggles faster.
*/
#define mainCHECK_TASK_LED ( 6 ) #define mainCHECK_TASK_LED ( 6 )
//! LED that is set upon error. /* LED that is set upon error. */
#define mainERROR_LED ( 7 ) #define mainERROR_LED ( 7 )
//! The period between executions of the check task. /* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
//! If an error is detected in a task, the vErrorChecks task will enter in an /* If an error is detected in a task, the vErrorChecks task will enter in an
//! infinite loop flashing the LED at this rate. * infinite loop flashing the LED at this rate. */
#define mainERROR_FLASH_RATE ( (TickType_t) 500 / portTICK_PERIOD_MS ) #define mainERROR_FLASH_RATE ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
/*! \name Constants used by the vMemCheckTask() task. /* Constants used by the vMemCheckTask() task. */
*/
//! @{
#define mainCOUNT_INITIAL_VALUE ( ( unsigned long ) 0 ) #define mainCOUNT_INITIAL_VALUE ( ( unsigned long ) 0 )
#define mainNO_TASK ( 0 ) #define mainNO_TASK ( 0 )
//! @}
/*! \name The size of the memory blocks allocated by the vMemCheckTask() task. /* The size of the memory blocks allocated by the vMemCheckTask() task. */
*/
//! @{
#define mainMEM_CHECK_SIZE_1 ( ( size_t ) 51 ) #define mainMEM_CHECK_SIZE_1 ( ( size_t ) 51 )
#define mainMEM_CHECK_SIZE_2 ( ( size_t ) 52 ) #define mainMEM_CHECK_SIZE_2 ( ( size_t ) 52 )
#define mainMEM_CHECK_SIZE_3 ( ( size_t ) 15 ) #define mainMEM_CHECK_SIZE_3 ( ( size_t ) 15 )
//! @}
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -137,7 +130,7 @@
* prvCheckOtherTasksAreStillRunning(). See the description at the top * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks that all the demo application tasks are still executing without error * Checks that all the demo application tasks are still executing without error
@ -148,7 +141,7 @@ static portBASE_TYPE prvCheckOtherTasksAreStillRunning( void );
/* /*
* A task that exercises the memory allocator. * A task that exercises the memory allocator.
*/ */
static void vMemCheckTask( void *pvParameters ); static void vMemCheckTask( void * pvParameters );
/* /*
* Called by the check task following the detection of an error to set the * Called by the check task following the detection of an error to set the
@ -161,15 +154,15 @@ static void prvIndicateError( void );
int main( void ) int main( void )
{ {
/* Start the crystal oscillator 0 and switch the main clock to it. */ /* Start the crystal oscillator 0 and switch the main clock to it. */
pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP); pm_switch_to_osc0( &AVR32_PM, FOSC0, OSC0_STARTUP );
portDBG_TRACE("Starting the FreeRTOS AVR32 UC3 Demo..."); portDBG_TRACE( "Starting the FreeRTOS AVR32 UC3 Demo..." );
/* Setup the LED's for output. */ /* Setup the LED's for output. */
vParTestInitialise(); vParTestInitialise();
/* Start the standard demo tasks. See the WEB documentation for more /* Start the standard demo tasks. See the WEB documentation for more
information. */ * information. */
vStartLEDFlashTasks( mainLED_TASK_PRIORITY ); vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
@ -180,7 +173,7 @@ int main( void )
vStartMathTasks( tskIDLE_PRIORITY ); vStartMathTasks( tskIDLE_PRIORITY );
/* Start the demo tasks defined within this file, specifically the check /* Start the demo tasks defined within this file, specifically the check
task as described at the top of this file. */ * task as described at the top of this file. */
xTaskCreate( xTaskCreate(
vErrorChecks vErrorChecks
, "ErrCheck" , "ErrCheck"
@ -193,35 +186,35 @@ int main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle /* Will only get here if there was insufficient memory to create the idle
task. */ * task. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*! /*
* \brief The task function for the "Check" task. * @brief The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
static volatile unsigned long ulDummyVariable = 3UL; static volatile unsigned long ulDummyVariable = 3UL;
unsigned long ulMemCheckTaskRunningCount; unsigned long ulMemCheckTaskRunningCount;
TaskHandle_t xCreatedTask; TaskHandle_t xCreatedTask;
portBASE_TYPE bSuicidalTask = 0; portBASE_TYPE bSuicidalTask = 0;
/* The parameters are not used. Prevent compiler warnings. */ /* The parameters are not used. Prevent compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. * operating without error.
*
* In addition to the standard tests the memory allocator is tested through
* the dynamic creation and deletion of a task each cycle. Each time the
* task is created memory must be allocated for its stack. When the task is
* deleted this memory is returned to the heap. If the task cannot be created
* then it is likely that the memory allocation failed. */
In addition to the standard tests the memory allocator is tested through for( ; ; )
the dynamic creation and deletion of a task each cycle. Each time the
task is created memory must be allocated for its stack. When the task is
deleted this memory is returned to the heap. If the task cannot be created
then it is likely that the memory allocation failed. */
for( ;; )
{ {
/* Do this only once. */ /* Do this only once. */
if( bSuicidalTask == 0 ) if( bSuicidalTask == 0 )
@ -229,22 +222,22 @@ portBASE_TYPE bSuicidalTask = 0;
bSuicidalTask++; bSuicidalTask++;
/* This task has to be created last as it keeps account of the number of /* This task has to be created last as it keeps account of the number of
tasks it expects to see running. However its implementation expects * tasks it expects to see running. However its implementation expects
to be called before vTaskStartScheduler(). We're in the case here where * to be called before vTaskStartScheduler(). We're in the case here where
vTaskStartScheduler() has already been called (thus the hidden IDLE task * vTaskStartScheduler() has already been called (thus the hidden IDLE task
has already been spawned). Since vCreateSuicidalTask() supposes that the * has already been spawned). Since vCreateSuicidalTask() supposes that the
IDLE task isn't included in the response from uxTaskGetNumberOfTasks(), * IDLE task isn't included in the response from uxTaskGetNumberOfTasks(),
let the MEM_CHECK task play that role. => this is why vCreateSuicidalTasks() * let the MEM_CHECK task play that role. => this is why vCreateSuicidalTasks()
is not called as the last task. */ * is not called as the last task. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
} }
/* Reset xCreatedTask. This is modified by the task about to be /* Reset xCreatedTask. This is modified by the task about to be
created so we can tell if it is executing correctly or not. */ * created so we can tell if it is executing correctly or not. */
xCreatedTask = mainNO_TASK; xCreatedTask = mainNO_TASK;
/* Dynamically create a task - passing ulMemCheckTaskRunningCount as a /* Dynamically create a task - passing ulMemCheckTaskRunningCount as a
parameter. */ * parameter. */
ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE; ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;
if( xTaskCreate( vMemCheckTask, if( xTaskCreate( vMemCheckTask,
@ -254,8 +247,8 @@ portBASE_TYPE bSuicidalTask = 0;
tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS ) tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )
{ {
/* Could not create the task - we have probably run out of heap. /* Could not create the task - we have probably run out of heap.
Don't go any further and flash the LED faster to provide visual * Don't go any further and flash the LED faster to provide visual
feedback of the error. */ * feedback of the error. */
prvIndicateError(); prvIndicateError();
} }
@ -269,18 +262,18 @@ portBASE_TYPE bSuicidalTask = 0;
} }
/* Perform a bit of 32bit maths to ensure the registers used by the /* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important - * integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */ * see the demo application documentation for more info. */
ulDummyVariable *= 3; ulDummyVariable *= 3;
/* Check all other tasks are still operating without error. /* Check all other tasks are still operating without error.
Check that vMemCheckTask did increment the counter. */ * Check that vMemCheckTask did increment the counter. */
if( ( prvCheckOtherTasksAreStillRunning() != pdFALSE ) if( ( prvCheckOtherTasksAreStillRunning() != pdFALSE ) ||
|| ( ulMemCheckTaskRunningCount == mainCOUNT_INITIAL_VALUE ) ) ( ulMemCheckTaskRunningCount == mainCOUNT_INITIAL_VALUE ) )
{ {
/* An error has occurred in one of the tasks. /* An error has occurred in one of the tasks.
Don't go any further and flash the LED faster to give visual * Don't go any further and flash the LED faster to give visual
feedback of the error. */ * feedback of the error. */
prvIndicateError(); prvIndicateError();
} }
else else
@ -293,12 +286,12 @@ portBASE_TYPE bSuicidalTask = 0;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*! /*
* \brief Checks that all the demo application tasks are still executing without error. * @brief Checks that all the demo application tasks are still executing without error.
*/ */
static portBASE_TYPE prvCheckOtherTasksAreStillRunning( void ) static portBASE_TYPE prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreComTestTasksStillRunning() != pdTRUE )
{ {
@ -340,38 +333,38 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
return ( xErrorHasOccurred ); return( xErrorHasOccurred );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*! /*
* \brief Dynamically created and deleted during each cycle of the vErrorChecks() * @brief Dynamically created and deleted during each cycle of the vErrorChecks()
* task. This is done to check the operation of the memory allocator. * task. This is done to check the operation of the memory allocator.
* See the top of vErrorChecks for more details. * See the top of vErrorChecks for more details.
* *
* \param *pvParameters Parameters for the task (can be of any kind) * @param pvParameters Parameters for the task (can be of any kind)
*/ */
static void vMemCheckTask( void *pvParameters ) static void vMemCheckTask( void * pvParameters )
{ {
unsigned long *pulMemCheckTaskRunningCounter; unsigned long * pulMemCheckTaskRunningCounter;
void *pvMem1, *pvMem2, *pvMem3; void * pvMem1, * pvMem2, * pvMem3;
static long lErrorOccurred = pdFALSE; static long lErrorOccurred = pdFALSE;
/* This task is dynamically created then deleted during each cycle of the /* This task is dynamically created then deleted during each cycle of the
vErrorChecks task to check the operation of the memory allocator. Each time * vErrorChecks task to check the operation of the memory allocator. Each time
the task is created memory is allocated for the stack and TCB. Each time * the task is created memory is allocated for the stack and TCB. Each time
the task is deleted this memory is returned to the heap. This task itself * the task is deleted this memory is returned to the heap. This task itself
exercises the allocator by allocating and freeing blocks. * exercises the allocator by allocating and freeing blocks.
*
The task executes at the idle priority so does not require a delay. * The task executes at the idle priority so does not require a delay.
*
pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the * pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the
vErrorChecks() task that this task is still executing without error. */ * vErrorChecks() task that this task is still executing without error. */
pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters; pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters;
for( ;; ) for( ; ; )
{ {
if( lErrorOccurred == pdFALSE ) if( lErrorOccurred == pdFALSE )
{ {
@ -381,13 +374,13 @@ static long lErrorOccurred = pdFALSE;
else else
{ {
/* There has been an error so reset the counter so the check task /* There has been an error so reset the counter so the check task
can tell that an error occurred. */ * can tell that an error occurred. */
*pulMemCheckTaskRunningCounter = mainCOUNT_INITIAL_VALUE; *pulMemCheckTaskRunningCounter = mainCOUNT_INITIAL_VALUE;
} }
/* Allocate some memory - just to give the allocator some extra /* Allocate some memory - just to give the allocator some extra
exercise. This has to be in a critical section to ensure the * exercise. This has to be in a critical section to ensure the
task does not get deleted while it has memory allocated. */ * task does not get deleted while it has memory allocated. */
vTaskSuspendAll(); vTaskSuspendAll();
{ {
@ -426,6 +419,7 @@ static long lErrorOccurred = pdFALSE;
vTaskSuspendAll(); vTaskSuspendAll();
{ {
pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 ); pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );
if( pvMem3 == NULL ) if( pvMem3 == NULL )
{ {
lErrorOccurred = pdTRUE; lErrorOccurred = pdTRUE;
@ -444,16 +438,16 @@ static long lErrorOccurred = pdFALSE;
static void prvIndicateError( void ) static void prvIndicateError( void )
{ {
/* The check task has found an error in one of the other tasks. /* The check task has found an error in one of the other tasks.
Set the LEDs to a state that indicates this. */ * Set the LEDs to a state that indicates this. */
vParTestSetLED(mainERROR_LED,pdTRUE); vParTestSetLED( mainERROR_LED, pdTRUE );
for(;;) for( ; ; )
{ {
#if( BOARD==EVK1100 ) #if ( BOARD == EVK1100 )
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
vTaskDelay( mainERROR_FLASH_RATE ); vTaskDelay( mainERROR_FLASH_RATE );
#endif #endif
#if ( BOARD==EVK1101 ) #if ( BOARD == EVK1101 )
vParTestSetLED( 0, pdTRUE ); vParTestSetLED( 0, pdTRUE );
vParTestSetLED( 1, pdTRUE ); vParTestSetLED( 1, pdTRUE );
vParTestSetLED( 2, pdTRUE ); vParTestSetLED( 2, pdTRUE );
@ -461,4 +455,3 @@ static void prvIndicateError( void )
#endif #endif
} }
} }

View file

@ -44,38 +44,38 @@
*/ */
/* /*
Changes from V1.2.0 * Changes from V1.2.0
*
+ Changed the baud rate for the serial test from 19200 to 57600. + Changed the baud rate for the serial test from 19200 to 57600.
+
Changes from V1.2.3 + Changes from V1.2.3
+
+ The integer and comtest tasks are now used when the cooperative scheduler + The integer and comtest tasks are now used when the cooperative scheduler
is being used. Previously they were only used with the preemptive + is being used. Previously they were only used with the preemptive
scheduler. + scheduler.
+
Changes from V1.2.5 + Changes from V1.2.5
+
+ Set the baud rate to 38400. This has a smaller error percentage with an + Set the baud rate to 38400. This has a smaller error percentage with an
8MHz clock (according to the manual). + 8MHz clock (according to the manual).
+
Changes from V2.0.0 + Changes from V2.0.0
+
+ Delay periods are now specified using variables and constants of + Delay periods are now specified using variables and constants of
TickType_t rather than unsigned long. + TickType_t rather than unsigned long.
+
Changes from V2.2.0 + Changes from V2.2.0
+
+ File can now be built using either the IAR or WinAVR compiler. + File can now be built using either the IAR or WinAVR compiler.
+
Changes from V2.6.1 + Changes from V2.6.1
+
+ The IAR and WinAVR AVR ports are now maintained separately. + The IAR and WinAVR AVR ports are now maintained separately.
+
Changes from V4.0.5 + Changes from V4.0.5
+
+ Modified to demonstrate the use of co-routines. + Modified to demonstrate the use of co-routines.
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -101,7 +101,7 @@ Changes from V4.0.5
#include "regtest.h" #include "regtest.h"
/* Priority definitions for most of the tasks in the demo application. Some /* Priority definitions for most of the tasks in the demo application. Some
tasks just use the idle priority. */ * tasks just use the idle priority. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
@ -111,20 +111,20 @@ tasks just use the idle priority. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 38400 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 38400 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 4 ) #define mainCOM_TEST_LED ( 4 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 7 ) #define mainCHECK_TASK_LED ( 7 )
/* The period between executions of the check task. */ /* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
/* An address in the EEPROM used to count resets. This is used to check that /* An address in the EEPROM used to count resets. This is used to check that
the demo application is not unexpectedly resetting. */ * the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 ) #define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 )
/* The number of coroutines to create. */ /* The number of coroutines to create. */
@ -133,7 +133,7 @@ the demo application is not unexpectedly resetting. */
/* /*
* The task function for the "Check" task. * The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks the unique counts of other tasks to ensure they are still operational. * Checks the unique counts of other tasks to ensure they are still operational.
@ -172,30 +172,30 @@ short main( void )
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION /* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define * as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */ * configUSE_PREEMPTION as 0. */
vTaskStartScheduler(); vTaskStartScheduler();
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
static volatile unsigned long ulDummyVariable = 3UL; static volatile unsigned long ulDummyVariable = 3UL;
/* The parameters are not used. */ /* The parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */ * operating without error. */
for( ;; ) for( ; ; )
{ {
vTaskDelay( mainCHECK_PERIOD ); vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the /* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important - * integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */ * see the demo application documentation for more info. */
ulDummyVariable *= 3; ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning(); prvCheckOtherTasksAreStillRunning();
@ -205,7 +205,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void ) static void prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -230,7 +230,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xErrorHasOccurred == pdFALSE ) if( xErrorHasOccurred == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
@ -238,14 +238,14 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void ) static void prvIncrementResetCount( void )
{ {
unsigned char ucCount; unsigned char ucCount;
const unsigned char ucReadBit = ( unsigned char ) 0x01; const unsigned char ucReadBit = ( unsigned char ) 0x01;
const unsigned char ucWrite1 = ( unsigned char ) 0x04; const unsigned char ucWrite1 = ( unsigned char ) 0x04;
const unsigned char ucWrite2 = ( unsigned char ) 0x02; const unsigned char ucWrite2 = ( unsigned char ) 0x02;
/* Increment the EEPROM value at 0x00. /* Increment the EEPROM value at 0x00.
*
Setup the EEPROM address. */ * Setup the EEPROM address. */
EEARH = 0x00; EEARH = 0x00;
EEARL = 0x00; EEARL = 0x00;
@ -253,7 +253,9 @@ const unsigned char ucWrite2 = ( unsigned char ) 0x02;
EECR |= ucReadBit; EECR |= ucReadBit;
/* Wait for the read. */ /* Wait for the read. */
while( EECR & ucReadBit ); while( EECR & ucReadBit )
{
}
/* The byte is ready. */ /* The byte is ready. */
ucCount = EEDR; ucCount = EEDR;
@ -270,4 +272,3 @@ void vApplicationIdleHook( void )
{ {
vCoRoutineSchedule(); vCoRoutineSchedule();
} }

View file

@ -44,35 +44,35 @@
*/ */
/* /*
Changes from V1.2.0 * Changes from V1.2.0
*
+ Changed the baud rate for the serial test from 19200 to 57600. + Changed the baud rate for the serial test from 19200 to 57600.
+
Changes from V1.2.3 + Changes from V1.2.3
+
+ The integer and comtest tasks are now used when the cooperative scheduler + The integer and comtest tasks are now used when the cooperative scheduler
is being used. Previously they were only used with the preemptive + is being used. Previously they were only used with the preemptive
scheduler. + scheduler.
+
Changes from V1.2.5 + Changes from V1.2.5
+
+ Set the baud rate to 38400. This has a smaller error percentage with an + Set the baud rate to 38400. This has a smaller error percentage with an
8MHz clock (according to the manual). + 8MHz clock (according to the manual).
+
Changes from V2.0.0 + Changes from V2.0.0
+
+ Delay periods are now specified using variables and constants of + Delay periods are now specified using variables and constants of
TickType_t rather than unsigned long. + TickType_t rather than unsigned long.
+
Changes from V2.6.1 + Changes from V2.6.1
+
+ The IAR and WinAVR AVR ports are now maintained separately. + The IAR and WinAVR AVR ports are now maintained separately.
+
Changes from V4.0.5 + Changes from V4.0.5
+
+ Modified to demonstrate the use of co-routines. + Modified to demonstrate the use of co-routines.
+
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -98,7 +98,7 @@ Changes from V4.0.5
#include "regtest.h" #include "regtest.h"
/* Priority definitions for most of the tasks in the demo application. Some /* Priority definitions for most of the tasks in the demo application. Some
tasks just use the idle priority. */ * tasks just use the idle priority. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
@ -108,20 +108,20 @@ tasks just use the idle priority. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 38400 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 38400 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 4 ) #define mainCOM_TEST_LED ( 4 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 7 ) #define mainCHECK_TASK_LED ( 7 )
/* The period between executions of the check task. */ /* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
/* An address in the EEPROM used to count resets. This is used to check that /* An address in the EEPROM used to count resets. This is used to check that
the demo application is not unexpectedly resetting. */ * the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 ) #define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 )
/* The number of coroutines to create. */ /* The number of coroutines to create. */
@ -130,7 +130,7 @@ the demo application is not unexpectedly resetting. */
/* /*
* The task function for the "Check" task. * The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks the unique counts of other tasks to ensure they are still operational. * Checks the unique counts of other tasks to ensure they are still operational.
@ -171,30 +171,30 @@ short main( void )
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION /* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define * as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */ * configUSE_PREEMPTION as 0. */
vTaskStartScheduler(); vTaskStartScheduler();
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
static volatile unsigned long ulDummyVariable = 3UL; static volatile unsigned long ulDummyVariable = 3UL;
/* The parameters are not used. */ /* The parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */ * operating without error. */
for( ;; ) for( ; ; )
{ {
vTaskDelay( mainCHECK_PERIOD ); vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the /* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important - * integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */ * see the demo application documentation for more info. */
ulDummyVariable *= 3; ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning(); prvCheckOtherTasksAreStillRunning();
@ -204,7 +204,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void ) static void prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -229,7 +229,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xErrorHasOccurred == pdFALSE ) if( xErrorHasOccurred == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
@ -237,7 +237,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void ) static void prvIncrementResetCount( void )
{ {
unsigned char ucCount; unsigned char ucCount;
eeprom_read_block( &ucCount, mainRESET_COUNT_ADDRESS, sizeof( ucCount ) ); eeprom_read_block( &ucCount, mainRESET_COUNT_ADDRESS, sizeof( ucCount ) );
ucCount++; ucCount++;
@ -249,4 +249,3 @@ void vApplicationIdleHook( void )
{ {
vCoRoutineSchedule(); vCoRoutineSchedule();
} }

View file

@ -1,22 +1,22 @@
/* /*
(C) 2020 Microchip Technology Inc. and its subsidiaries. * (C) 2020 Microchip Technology Inc. and its subsidiaries.
*
Subject to your compliance with these terms, you may use Microchip software and * Subject to your compliance with these terms, you may use Microchip software and
any derivatives exclusively with Microchip products. It is your responsibility * any derivatives exclusively with Microchip products. It is your responsibility
to comply with third party license terms applicable to your use of third party * to comply with third party license terms applicable to your use of third party
software (including open source software) that may accompany Microchip software. * software (including open source software) that may accompany Microchip software.
*
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS, * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS,
IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES * IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES
OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. * OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER
RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF * RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF
THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWED * THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWED
BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS * BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS
SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY * SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY
TO MICROCHIP FOR THIS SOFTWARE. * TO MICROCHIP FOR THIS SOFTWARE.
*/ */
#include <ioavr.h> #include <ioavr.h>
#include "FreeRTOS.h" #include "FreeRTOS.h"
@ -28,29 +28,29 @@ TO MICROCHIP FOR THIS SOFTWARE.
static void prvSetupHardware( void ); static void prvSetupHardware( void );
#if ( mainSELECTED_APPLICATION == 0 ) #if ( mainSELECTED_APPLICATION == 0 )
extern void main_blinky( void ); extern void main_blinky( void );
extern void init_blinky( void ); extern void init_blinky( void );
#elif ( mainSELECTED_APPLICATION == 1 ) #elif ( mainSELECTED_APPLICATION == 1 )
extern void main_minimal( void ); extern void main_minimal( void );
extern void init_minimal( void ); extern void init_minimal( void );
#elif ( mainSELECTED_APPLICATION == 2 ) #elif ( mainSELECTED_APPLICATION == 2 )
extern void main_full( void ); extern void main_full( void );
extern void init_full( void ); extern void init_full( void );
#else #else
#error Invalid mainSELECTED_APPLICATION setting. See the comments at the top of this file and above the mainSELECTED_APPLICATION definition. #error Invalid mainSELECTED_APPLICATION setting. See the comments at the top of this file and above the mainSELECTED_APPLICATION definition.
#endif #endif
int main( void ) int main( void )
{ {
prvSetupHardware(); prvSetupHardware();
#if ( mainSELECTED_APPLICATION == 0 ) #if ( mainSELECTED_APPLICATION == 0 )
main_blinky(); main_blinky();
#elif ( mainSELECTED_APPLICATION == 1 ) #elif ( mainSELECTED_APPLICATION == 1 )
main_minimal(); main_minimal();
#elif ( mainSELECTED_APPLICATION == 2 ) #elif ( mainSELECTED_APPLICATION == 2 )
main_full(); main_full();
#endif #endif
return 0; return 0;
} }
@ -58,37 +58,37 @@ int main( void )
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Ensure no interrupts execute while the scheduler is in an inconsistent /* Ensure no interrupts execute while the scheduler is in an inconsistent
state. Interrupts are automatically enabled when the scheduler is * state. Interrupts are automatically enabled when the scheduler is
started. */ * started. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
CLK_init(); CLK_init();
#if ( mainSELECTED_APPLICATION == 0 ) #if ( mainSELECTED_APPLICATION == 0 )
init_blinky(); init_blinky();
#elif ( mainSELECTED_APPLICATION == 1 ) #elif ( mainSELECTED_APPLICATION == 1 )
init_minimal(); init_minimal();
#elif ( mainSELECTED_APPLICATION == 2 ) #elif ( mainSELECTED_APPLICATION == 2 )
init_full(); init_full();
#endif #endif
} }
/* vApplicationStackOverflowHook is called when a stack overflow occurs. /* vApplicationStackOverflowHook is called when a stack overflow occurs.
This is usefull in application development, for debugging. To use this * This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in * hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in
"FreeRTOSConfig.h" header file. */ * "FreeRTOSConfig.h" header file. */
// void vApplicationStackOverflowHook(TaskHandle_t *pxTask, char *pcTaskName ) /* void vApplicationStackOverflowHook(TaskHandle_t *pxTask, char *pcTaskName ) */
// { /* { */
// for( ;; ); /* for( ;; ); */
// } /* } */
/* vApplicationMallocFailedHook is called when memorry allocation fails. /* vApplicationMallocFailedHook is called when memorry allocation fails.
This is usefull in application development, for debugging. To use this * This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in * hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in
"FreeRTOSConfig.h" header file. */ * "FreeRTOSConfig.h" header file. */
// void vApplicationMallocFailedHook( void ) /* void vApplicationMallocFailedHook( void ) */
// { /* { */
// for( ;; ); /* for( ;; ); */
// } /* } */

View file

@ -63,12 +63,12 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -76,8 +76,8 @@ the queue empty. */
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -92,7 +92,7 @@ void main_blinky( void )
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
@ -107,14 +107,16 @@ void main_blinky( void )
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle * there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from * and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for * User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The * more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be * mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */ * a privileged mode (not user mode). */
for( ;; ); for( ; ; )
{
}
} }
void init_blinky( void ) void init_blinky( void )
@ -123,10 +125,10 @@ void init_blinky( void )
PORTF.DIRSET = PIN5_bm; PORTF.DIRSET = PIN5_bm;
} }
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
@ -134,37 +136,37 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. */ /* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL; const unsigned long ulExpectedValue = 100UL;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == ulExpectedValue ) if( ulReceivedValue == ulExpectedValue )
{ {
/* Toggle LED on pin PF5. */ /* Toggle LED on pin PF5. */
@ -173,4 +175,3 @@ const unsigned long ulExpectedValue = 100UL;
} }
} }
} }

View file

@ -14,39 +14,40 @@
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 5 ) #define mainCHECK_TASK_LED ( 5 )
/* /*
* The check task, as described at the top of this file. * The check task, as described at the top of this file.
*/ */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
void main_full( void ) void main_full( void )
{ {
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartSemaphoreTasks(mainSEM_TEST_PRIORITY);
vStartTaskNotifyTask(); vStartTaskNotifyTask();
vStartRegTestTasks(); vStartRegTestTasks();
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
/* Create the task that performs the 'check' functionality, as described at /* Create the task that performs the 'check' functionality, as described at
the top of this file. */ * the top of this file. */
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle * there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from * and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for * User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The * more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be * mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */ * a privileged mode (not user mode). */
for( ;; ); for( ; ; )
{
}
} }
void init_full( void ) void init_full( void )
@ -54,28 +55,28 @@ void init_full( void )
vParTestInitialise(); vParTestInitialise();
} }
static void prvCheckTask( void *pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Just to stop compiler warnings. */ /* Just to stop compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration * operating without error. The onboard LED is toggled on each iteration
unless an error occurred. */ * unless an error occurred. */
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. */ /* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_PERIOD ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_PERIOD );
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
ulErrorFound |= 1UL << 0UL; ulErrorFound |= 1UL << 0UL;
@ -91,7 +92,7 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound |= 1UL << 2UL; ulErrorFound |= 1UL << 2UL;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound |= 1UL << 3UL; ulErrorFound |= 1UL << 3UL;
} }
@ -99,7 +100,7 @@ unsigned long ulErrorFound = pdFALSE;
if( ulErrorFound == pdFALSE ) if( ulErrorFound == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }

View file

@ -37,7 +37,7 @@
#include "regtest.h" #include "regtest.h"
/* Priority definitions for most of the tasks in the demo application. Some /* Priority definitions for most of the tasks in the demo application. Some
tasks just use the idle priority. */ * tasks just use the idle priority. */
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
@ -46,20 +46,20 @@ tasks just use the idle priority. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 6 ) #define mainCOM_TEST_LED ( 6 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 5 ) #define mainCHECK_TASK_LED ( 5 )
/* The period between executions of the check task. */ /* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS )
/* An address in the EEPROM used to count resets. This is used to check that /* An address in the EEPROM used to count resets. This is used to check that
the demo application is not unexpectedly resetting. */ * the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( 0x1400 ) #define mainRESET_COUNT_ADDRESS ( 0x1400 )
/* The number of coroutines to create. */ /* The number of coroutines to create. */
@ -68,7 +68,7 @@ the demo application is not unexpectedly resetting. */
/* /*
* The task function for the "Check" task. * The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks the unique counts of other tasks to ensure they are still operational. * Checks the unique counts of other tasks to ensure they are still operational.
@ -99,8 +99,8 @@ void main_minimal( void )
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION /* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define * as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */ * configUSE_PREEMPTION as 0. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
@ -113,22 +113,22 @@ void init_minimal( void )
vParTestInitialise(); vParTestInitialise();
} }
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
static volatile unsigned long ulDummyVariable = 3UL; static volatile unsigned long ulDummyVariable = 3UL;
/* The parameters are not used. */ /* The parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */ * operating without error. */
for( ;; ) for( ; ; )
{ {
vTaskDelay( mainCHECK_PERIOD ); vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the /* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important - * integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */ * see the demo application documentation for more info. */
ulDummyVariable *= 3; ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning(); prvCheckOtherTasksAreStillRunning();
@ -138,7 +138,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void ) static void prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -163,7 +163,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xErrorHasOccurred == pdFALSE ) if( xErrorHasOccurred == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
@ -171,7 +171,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void ) static void prvIncrementResetCount( void )
{ {
static unsigned char __eeprom ucResetCount @ mainRESET_COUNT_ADDRESS; static unsigned char __eeprom ucResetCount @ mainRESET_COUNT_ADDRESS;
ucResetCount++; ucResetCount++;
} }

View file

@ -1,22 +1,22 @@
/* /*
(C) 2020 Microchip Technology Inc. and its subsidiaries. * (C) 2020 Microchip Technology Inc. and its subsidiaries.
*
Subject to your compliance with these terms, you may use Microchip software and * Subject to your compliance with these terms, you may use Microchip software and
any derivatives exclusively with Microchip products. It is your responsibility * any derivatives exclusively with Microchip products. It is your responsibility
to comply with third party license terms applicable to your use of third party * to comply with third party license terms applicable to your use of third party
software (including open source software) that may accompany Microchip software. * software (including open source software) that may accompany Microchip software.
*
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS, * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS,
IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES * IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES
OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. * OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER
RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF * RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF
THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWED * THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWED
BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS * BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS
SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY * SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY
TO MICROCHIP FOR THIS SOFTWARE. * TO MICROCHIP FOR THIS SOFTWARE.
*/ */
#include <avr/io.h> #include <avr/io.h>
#include "FreeRTOS.h" #include "FreeRTOS.h"
@ -28,29 +28,29 @@ TO MICROCHIP FOR THIS SOFTWARE.
static void prvSetupHardware( void ); static void prvSetupHardware( void );
#if ( mainSELECTED_APPLICATION == 0 ) #if ( mainSELECTED_APPLICATION == 0 )
extern void main_blinky( void ); extern void main_blinky( void );
extern void init_blinky( void ); extern void init_blinky( void );
#elif ( mainSELECTED_APPLICATION == 1 ) #elif ( mainSELECTED_APPLICATION == 1 )
extern void main_minimal( void ); extern void main_minimal( void );
extern void init_minimal( void ); extern void init_minimal( void );
#elif ( mainSELECTED_APPLICATION == 2 ) #elif ( mainSELECTED_APPLICATION == 2 )
extern void main_full( void ); extern void main_full( void );
extern void init_full( void ); extern void init_full( void );
#else #else
#error Invalid mainSELECTED_APPLICATION setting. See the comments at the top of this file and above the mainSELECTED_APPLICATION definition. #error Invalid mainSELECTED_APPLICATION setting. See the comments at the top of this file and above the mainSELECTED_APPLICATION definition.
#endif #endif
int main( void ) int main( void )
{ {
prvSetupHardware(); prvSetupHardware();
#if ( mainSELECTED_APPLICATION == 0 ) #if ( mainSELECTED_APPLICATION == 0 )
main_blinky(); main_blinky();
#elif ( mainSELECTED_APPLICATION == 1 ) #elif ( mainSELECTED_APPLICATION == 1 )
main_minimal(); main_minimal();
#elif ( mainSELECTED_APPLICATION == 2 ) #elif ( mainSELECTED_APPLICATION == 2 )
main_full(); main_full();
#endif #endif
return 0; return 0;
} }
@ -58,37 +58,58 @@ int main( void )
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Ensure no interrupts execute while the scheduler is in an inconsistent /* Ensure no interrupts execute while the scheduler is in an inconsistent
state. Interrupts are automatically enabled when the scheduler is * state. Interrupts are automatically enabled when the scheduler is
started. */ * started. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
CLK_init(); CLK_init();
#if ( mainSELECTED_APPLICATION == 0 ) #if ( mainSELECTED_APPLICATION == 0 )
init_blinky(); init_blinky();
#elif ( mainSELECTED_APPLICATION == 1 ) #elif ( mainSELECTED_APPLICATION == 1 )
init_minimal(); init_minimal();
#elif ( mainSELECTED_APPLICATION == 2 ) #elif ( mainSELECTED_APPLICATION == 2 )
init_full(); init_full();
#endif #endif
} }
/* vApplicationStackOverflowHook is called when a stack overflow occurs. /* vApplicationStackOverflowHook is called when a stack overflow occurs.
This is usefull in application development, for debugging. To use this * This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in * hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in
"FreeRTOSConfig.h" header file. */ * "FreeRTOSConfig.h" header file. */
// void vApplicationStackOverflowHook(TaskHandle_t *pxTask, char *pcTaskName ) #if ( portHAS_STACK_OVERFLOW_CHECKING != 0 ) && ( configCHECK_FOR_STACK_OVERFLOW != 0 )
// { void vApplicationStackOverflowHook( void )
// for( ;; ); {
// } volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
taskENTER_CRITICAL();
/* To debug this failure set ulSetToNonZeroInDebuggerToContinue
* to a non-zero value using a debugger. */
while( ulSetToNonZeroInDebuggerToContinue == 0 )
{
portNOP();
}
taskEXIT_CRITICAL();
}
#endif /* ( portHAS_STACK_OVERFLOW_CHECKING != 0 ) && ( configCHECK_FOR_STACK_OVERFLOW != 0 ) */
/* vApplicationMallocFailedHook is called when memorry allocation fails. /* vApplicationMallocFailedHook is called when memorry allocation fails.
This is usefull in application development, for debugging. To use this * This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in * hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in
"FreeRTOSConfig.h" header file. */ * "FreeRTOSConfig.h" header file. */
// void vApplicationMallocFailedHook( void ) #if ( configUSE_MALLOC_FAILED_HOOK != 0 )
// { void vApplicationMallocFailedHook( void )
// for( ;; ); {
// } volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
taskENTER_CRITICAL();
/* To debug this failure set ulSetToNonZeroInDebuggerToContinue
* to a non-zero value using a debugger. */
while( ulSetToNonZeroInDebuggerToContinue == 0 )
{
/* No-Op */
portNOP();
}
taskEXIT_CRITICAL();
}
#endif /* configUSE_MALLOC_FAILED_HOOK */

View file

@ -63,12 +63,12 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -76,8 +76,8 @@ the queue empty. */
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -92,7 +92,7 @@ void main_blinky( void )
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
@ -107,14 +107,16 @@ void main_blinky( void )
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle * there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from * and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for * User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The * more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be * mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */ * a privileged mode (not user mode). */
for( ;; ); for( ; ; )
{
}
} }
void init_blinky( void ) void init_blinky( void )
@ -123,10 +125,10 @@ void init_blinky( void )
PORTF.DIRSET = PIN5_bm; PORTF.DIRSET = PIN5_bm;
} }
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
@ -134,37 +136,37 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. */ /* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL; const unsigned long ulExpectedValue = 100UL;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == ulExpectedValue ) if( ulReceivedValue == ulExpectedValue )
{ {
/* Toggle LED on pin PF5. */ /* Toggle LED on pin PF5. */

View file

@ -13,36 +13,38 @@
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 5 ) #define mainCHECK_TASK_LED ( 5 )
/* The check task, as described at the top of this file. */ /* The check task, as described at the top of this file. */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
void main_full( void ) void main_full( void )
{ {
vStartSemaphoreTasks(mainSEM_TEST_PRIORITY); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartTaskNotifyTask(); vStartTaskNotifyTask();
vStartRegTestTasks(); vStartRegTestTasks();
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
/* Create the task that performs the 'check' functionality, as described at /* Create the task that performs the 'check' functionality, as described at
the top of this file. */ * the top of this file. */
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle * there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from * and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for * User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The * more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be * mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */ * a privileged mode (not user mode). */
for( ;; ); for( ; ; )
{
}
} }
void init_full( void ) void init_full( void )
@ -50,28 +52,28 @@ void init_full( void )
vParTestInitialise(); vParTestInitialise();
} }
static void prvCheckTask( void *pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Just to stop compiler warnings. */ /* Just to stop compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration * operating without error. The onboard LED is toggled on each iteration
unless an error occurred. */ * unless an error occurred. */
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. */ /* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_PERIOD ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_PERIOD );
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
ulErrorFound |= 1UL << 0UL; ulErrorFound |= 1UL << 0UL;
@ -87,7 +89,7 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound |= 1UL << 2UL; ulErrorFound |= 1UL << 2UL;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound |= 1UL << 3UL; ulErrorFound |= 1UL << 3UL;
} }
@ -95,7 +97,7 @@ unsigned long ulErrorFound = pdFALSE;
if( ulErrorFound == pdFALSE ) if( ulErrorFound == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }

View file

@ -38,7 +38,7 @@
#include "regtest.h" #include "regtest.h"
/* Priority definitions for most of the tasks in the demo application. Some /* Priority definitions for most of the tasks in the demo application. Some
tasks just use the idle priority. */ * tasks just use the idle priority. */
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
@ -47,20 +47,20 @@ tasks just use the idle priority. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 6 ) #define mainCOM_TEST_LED ( 6 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 5 ) #define mainCHECK_TASK_LED ( 5 )
/* The period between executions of the check task. */ /* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS )
/* An address in the EEPROM used to count resets. This is used to check that /* An address in the EEPROM used to count resets. This is used to check that
the demo application is not unexpectedly resetting. */ * the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( 0x1400 ) #define mainRESET_COUNT_ADDRESS ( 0x1400 )
/* The number of coroutines to create. */ /* The number of coroutines to create. */
@ -69,7 +69,7 @@ the demo application is not unexpectedly resetting. */
/* /*
* The task function for the "Check" task. * The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks the unique counts of other tasks to ensure they are still operational. * Checks the unique counts of other tasks to ensure they are still operational.
@ -100,8 +100,8 @@ void main_minimal( void )
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION /* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define * as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */ * configUSE_PREEMPTION as 0. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
@ -114,22 +114,22 @@ void init_minimal( void )
vParTestInitialise(); vParTestInitialise();
} }
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
static volatile unsigned long ulDummyVariable = 3UL; static volatile unsigned long ulDummyVariable = 3UL;
/* The parameters are not used. */ /* The parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */ * operating without error. */
for( ;; ) for( ; ; )
{ {
vTaskDelay( mainCHECK_PERIOD ); vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the /* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important - * integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */ * see the demo application documentation for more info. */
ulDummyVariable *= 3; ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning(); prvCheckOtherTasksAreStillRunning();
@ -139,7 +139,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void ) static void prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -164,7 +164,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xErrorHasOccurred == pdFALSE ) if( xErrorHasOccurred == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
@ -172,7 +172,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void ) static void prvIncrementResetCount( void )
{ {
unsigned char ucResetCount; unsigned char ucResetCount;
eeprom_read_block( &ucResetCount, ( void * ) mainRESET_COUNT_ADDRESS, sizeof( ucResetCount ) ); eeprom_read_block( &ucResetCount, ( void * ) mainRESET_COUNT_ADDRESS, sizeof( ucResetCount ) );
ucResetCount++; ucResetCount++;

View file

@ -1,22 +1,22 @@
/* /*
(C) 2020 Microchip Technology Inc. and its subsidiaries. * (C) 2020 Microchip Technology Inc. and its subsidiaries.
*
Subject to your compliance with these terms, you may use Microchip software and * Subject to your compliance with these terms, you may use Microchip software and
any derivatives exclusively with Microchip products. It is your responsibility * any derivatives exclusively with Microchip products. It is your responsibility
to comply with third party license terms applicable to your use of third party * to comply with third party license terms applicable to your use of third party
software (including open source software) that may accompany Microchip software. * software (including open source software) that may accompany Microchip software.
*
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS, * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS,
IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES * IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES
OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. * OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER
RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF * RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF
THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWED * THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWED
BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS * BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS
SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY * SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY
TO MICROCHIP FOR THIS SOFTWARE. * TO MICROCHIP FOR THIS SOFTWARE.
*/ */
#include <ioavr.h> #include <ioavr.h>
#include "FreeRTOS.h" #include "FreeRTOS.h"
@ -28,29 +28,29 @@ TO MICROCHIP FOR THIS SOFTWARE.
static void prvSetupHardware( void ); static void prvSetupHardware( void );
#if ( mainSELECTED_APPLICATION == 0 ) #if ( mainSELECTED_APPLICATION == 0 )
extern void main_blinky( void ); extern void main_blinky( void );
extern void init_blinky( void ); extern void init_blinky( void );
#elif ( mainSELECTED_APPLICATION == 1 ) #elif ( mainSELECTED_APPLICATION == 1 )
extern void main_minimal( void ); extern void main_minimal( void );
extern void init_minimal( void ); extern void init_minimal( void );
#elif ( mainSELECTED_APPLICATION == 2 ) #elif ( mainSELECTED_APPLICATION == 2 )
extern void main_full( void ); extern void main_full( void );
extern void init_full( void ); extern void init_full( void );
#else #else
#error Invalid mainSELECTED_APPLICATION setting. See the comments at the top of this file and above the mainSELECTED_APPLICATION definition. #error Invalid mainSELECTED_APPLICATION setting. See the comments at the top of this file and above the mainSELECTED_APPLICATION definition.
#endif #endif
int main( void ) int main( void )
{ {
prvSetupHardware(); prvSetupHardware();
#if ( mainSELECTED_APPLICATION == 0 ) #if ( mainSELECTED_APPLICATION == 0 )
main_blinky(); main_blinky();
#elif ( mainSELECTED_APPLICATION == 1 ) #elif ( mainSELECTED_APPLICATION == 1 )
main_minimal(); main_minimal();
#elif ( mainSELECTED_APPLICATION == 2 ) #elif ( mainSELECTED_APPLICATION == 2 )
main_full(); main_full();
#endif #endif
return 0; return 0;
} }
@ -58,37 +58,58 @@ int main( void )
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Ensure no interrupts execute while the scheduler is in an inconsistent /* Ensure no interrupts execute while the scheduler is in an inconsistent
state. Interrupts are automatically enabled when the scheduler is * state. Interrupts are automatically enabled when the scheduler is
started. */ * started. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
CLK_init(); CLK_init();
#if ( mainSELECTED_APPLICATION == 0 ) #if ( mainSELECTED_APPLICATION == 0 )
init_blinky(); init_blinky();
#elif ( mainSELECTED_APPLICATION == 1 ) #elif ( mainSELECTED_APPLICATION == 1 )
init_minimal(); init_minimal();
#elif ( mainSELECTED_APPLICATION == 2 ) #elif ( mainSELECTED_APPLICATION == 2 )
init_full(); init_full();
#endif #endif
} }
/* vApplicationStackOverflowHook is called when a stack overflow occurs. /* vApplicationStackOverflowHook is called when a stack overflow occurs.
This is usefull in application development, for debugging. To use this * This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in * hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in
"FreeRTOSConfig.h" header file. */ * "FreeRTOSConfig.h" header file. */
// void vApplicationStackOverflowHook(TaskHandle_t *pxTask, char *pcTaskName ) #if ( portHAS_STACK_OVERFLOW_CHECKING != 0 ) && ( configCHECK_FOR_STACK_OVERFLOW != 0 )
// { void vApplicationStackOverflowHook( void )
// for( ;; ); {
// } volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
taskENTER_CRITICAL();
/* To debug this failure set ulSetToNonZeroInDebuggerToContinue
* to a non-zero value using a debugger. */
while( ulSetToNonZeroInDebuggerToContinue == 0 )
{
portNOP();
}
taskEXIT_CRITICAL();
}
#endif /* ( portHAS_STACK_OVERFLOW_CHECKING != 0 ) && ( configCHECK_FOR_STACK_OVERFLOW != 0 ) */
/* vApplicationMallocFailedHook is called when memorry allocation fails. /* vApplicationMallocFailedHook is called when memorry allocation fails.
This is usefull in application development, for debugging. To use this * This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in * hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in
"FreeRTOSConfig.h" header file. */ * "FreeRTOSConfig.h" header file. */
// void vApplicationMallocFailedHook( void ) #if ( configUSE_MALLOC_FAILED_HOOK != 0 )
// { void vApplicationMallocFailedHook( void )
// for( ;; ); {
// } volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
taskENTER_CRITICAL();
/* To debug this failure set ulSetToNonZeroInDebuggerToContinue
* to a non-zero value using a debugger. */
while( ulSetToNonZeroInDebuggerToContinue == 0 )
{
/* No-Op */
portNOP();
}
taskEXIT_CRITICAL();
}
#endif /* configUSE_MALLOC_FAILED_HOOK */

View file

@ -63,12 +63,12 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -76,8 +76,8 @@ the queue empty. */
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -92,7 +92,7 @@ void main_blinky( void )
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
@ -107,14 +107,16 @@ void main_blinky( void )
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle * there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from * and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for * User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The * more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be * mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */ * a privileged mode (not user mode). */
for( ;; ); for( ; ; )
{
}
} }
void init_blinky( void ) void init_blinky( void )
@ -123,10 +125,10 @@ void init_blinky( void )
PORTC.DIRSET = PIN6_bm; PORTC.DIRSET = PIN6_bm;
} }
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
@ -134,37 +136,37 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. */ /* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL; const unsigned long ulExpectedValue = 100UL;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == ulExpectedValue ) if( ulReceivedValue == ulExpectedValue )
{ {
/* Toggle LED on pin PC6. */ /* Toggle LED on pin PC6. */
@ -173,4 +175,3 @@ const unsigned long ulExpectedValue = 100UL;
} }
} }
} }

View file

@ -14,39 +14,40 @@
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 6 ) #define mainCHECK_TASK_LED ( 6 )
/* /*
* The check task, as described at the top of this file. * The check task, as described at the top of this file.
*/ */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
void main_full( void ) void main_full( void )
{ {
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartSemaphoreTasks(mainSEM_TEST_PRIORITY);
vStartTaskNotifyTask(); vStartTaskNotifyTask();
vStartRegTestTasks(); vStartRegTestTasks();
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
/* Create the task that performs the 'check' functionality, as described at /* Create the task that performs the 'check' functionality, as described at
the top of this file. */ * the top of this file. */
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle * there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from * and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for * User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The * more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be * mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */ * a privileged mode (not user mode). */
for( ;; ); for( ; ; )
{
}
} }
void init_full( void ) void init_full( void )
@ -54,28 +55,28 @@ void init_full( void )
vParTestInitialise(); vParTestInitialise();
} }
static void prvCheckTask( void *pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Just to stop compiler warnings. */ /* Just to stop compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration * operating without error. The onboard LED is toggled on each iteration
unless an error occurred. */ * unless an error occurred. */
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. */ /* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_PERIOD ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_PERIOD );
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
ulErrorFound |= 1UL << 0UL; ulErrorFound |= 1UL << 0UL;
@ -91,7 +92,7 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound |= 1UL << 2UL; ulErrorFound |= 1UL << 2UL;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound |= 1UL << 3UL; ulErrorFound |= 1UL << 3UL;
} }
@ -99,7 +100,7 @@ unsigned long ulErrorFound = pdFALSE;
if( ulErrorFound == pdFALSE ) if( ulErrorFound == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }

View file

@ -37,7 +37,7 @@
#include "regtest.h" #include "regtest.h"
/* Priority definitions for most of the tasks in the demo application. Some /* Priority definitions for most of the tasks in the demo application. Some
tasks just use the idle priority. */ * tasks just use the idle priority. */
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
@ -46,20 +46,20 @@ tasks just use the idle priority. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 7 ) #define mainCOM_TEST_LED ( 7 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 6 ) #define mainCHECK_TASK_LED ( 6 )
/* The period between executions of the check task. */ /* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS )
/* An address in the EEPROM used to count resets. This is used to check that /* An address in the EEPROM used to count resets. This is used to check that
the demo application is not unexpectedly resetting. */ * the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( 0x1400 ) #define mainRESET_COUNT_ADDRESS ( 0x1400 )
/* The number of coroutines to create. */ /* The number of coroutines to create. */
@ -68,7 +68,7 @@ the demo application is not unexpectedly resetting. */
/* /*
* The task function for the "Check" task. * The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks the unique counts of other tasks to ensure they are still operational. * Checks the unique counts of other tasks to ensure they are still operational.
@ -99,8 +99,8 @@ void main_minimal( void )
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION /* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define * as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */ * configUSE_PREEMPTION as 0. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
@ -113,22 +113,22 @@ void init_minimal( void )
vParTestInitialise(); vParTestInitialise();
} }
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
static volatile unsigned long ulDummyVariable = 3UL; static volatile unsigned long ulDummyVariable = 3UL;
/* The parameters are not used. */ /* The parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */ * operating without error. */
for( ;; ) for( ; ; )
{ {
vTaskDelay( mainCHECK_PERIOD ); vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the /* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important - * integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */ * see the demo application documentation for more info. */
ulDummyVariable *= 3; ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning(); prvCheckOtherTasksAreStillRunning();
@ -138,7 +138,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void ) static void prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -163,7 +163,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xErrorHasOccurred == pdFALSE ) if( xErrorHasOccurred == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
@ -171,7 +171,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void ) static void prvIncrementResetCount( void )
{ {
static unsigned char __eeprom ucResetCount @ mainRESET_COUNT_ADDRESS; static unsigned char __eeprom ucResetCount @ mainRESET_COUNT_ADDRESS;
ucResetCount++; ucResetCount++;
} }

View file

@ -1,22 +1,22 @@
/* /*
(C) 2020 Microchip Technology Inc. and its subsidiaries. * (C) 2020 Microchip Technology Inc. and its subsidiaries.
*
Subject to your compliance with these terms, you may use Microchip software and * Subject to your compliance with these terms, you may use Microchip software and
any derivatives exclusively with Microchip products. It is your responsibility * any derivatives exclusively with Microchip products. It is your responsibility
to comply with third party license terms applicable to your use of third party * to comply with third party license terms applicable to your use of third party
software (including open source software) that may accompany Microchip software. * software (including open source software) that may accompany Microchip software.
*
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS, * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS,
IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES * IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES
OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. * OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER
RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF * RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF
THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWED * THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWED
BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS * BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS
SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY * SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY
TO MICROCHIP FOR THIS SOFTWARE. * TO MICROCHIP FOR THIS SOFTWARE.
*/ */
#include <avr/io.h> #include <avr/io.h>
#include "FreeRTOS.h" #include "FreeRTOS.h"
@ -28,29 +28,29 @@ TO MICROCHIP FOR THIS SOFTWARE.
static void prvSetupHardware( void ); static void prvSetupHardware( void );
#if ( mainSELECTED_APPLICATION == 0 ) #if ( mainSELECTED_APPLICATION == 0 )
extern void main_blinky( void ); extern void main_blinky( void );
extern void init_blinky( void ); extern void init_blinky( void );
#elif ( mainSELECTED_APPLICATION == 1 ) #elif ( mainSELECTED_APPLICATION == 1 )
extern void main_minimal( void ); extern void main_minimal( void );
extern void init_minimal( void ); extern void init_minimal( void );
#elif ( mainSELECTED_APPLICATION == 2 ) #elif ( mainSELECTED_APPLICATION == 2 )
extern void main_full( void ); extern void main_full( void );
extern void init_full( void ); extern void init_full( void );
#else #else
#error Invalid mainSELECTED_APPLICATION setting. See the comments at the top of this file and above the mainSELECTED_APPLICATION definition. #error Invalid mainSELECTED_APPLICATION setting. See the comments at the top of this file and above the mainSELECTED_APPLICATION definition.
#endif #endif
int main( void ) int main( void )
{ {
prvSetupHardware(); prvSetupHardware();
#if ( mainSELECTED_APPLICATION == 0 ) #if ( mainSELECTED_APPLICATION == 0 )
main_blinky(); main_blinky();
#elif ( mainSELECTED_APPLICATION == 1 ) #elif ( mainSELECTED_APPLICATION == 1 )
main_minimal(); main_minimal();
#elif ( mainSELECTED_APPLICATION == 2 ) #elif ( mainSELECTED_APPLICATION == 2 )
main_full(); main_full();
#endif #endif
return 0; return 0;
} }
@ -58,37 +58,58 @@ int main( void )
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Ensure no interrupts execute while the scheduler is in an inconsistent /* Ensure no interrupts execute while the scheduler is in an inconsistent
state. Interrupts are automatically enabled when the scheduler is * state. Interrupts are automatically enabled when the scheduler is
started. */ * started. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
CLK_init(); CLK_init();
#if ( mainSELECTED_APPLICATION == 0 ) #if ( mainSELECTED_APPLICATION == 0 )
init_blinky(); init_blinky();
#elif ( mainSELECTED_APPLICATION == 1 ) #elif ( mainSELECTED_APPLICATION == 1 )
init_minimal(); init_minimal();
#elif ( mainSELECTED_APPLICATION == 2 ) #elif ( mainSELECTED_APPLICATION == 2 )
init_full(); init_full();
#endif #endif
} }
/* vApplicationStackOverflowHook is called when a stack overflow occurs. /* vApplicationStackOverflowHook is called when a stack overflow occurs.
This is usefull in application development, for debugging. To use this * This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in * hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in
"FreeRTOSConfig.h" header file. */ * "FreeRTOSConfig.h" header file. */
// void vApplicationStackOverflowHook(TaskHandle_t *pxTask, char *pcTaskName ) #if ( portHAS_STACK_OVERFLOW_CHECKING != 0 ) && ( configCHECK_FOR_STACK_OVERFLOW != 0 )
// { void vApplicationStackOverflowHook( void )
// for( ;; ); {
// } volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
taskENTER_CRITICAL();
/* To debug this failure set ulSetToNonZeroInDebuggerToContinue
* to a non-zero value using a debugger. */
while( ulSetToNonZeroInDebuggerToContinue == 0 )
{
portNOP();
}
taskEXIT_CRITICAL();
}
#endif /* ( portHAS_STACK_OVERFLOW_CHECKING != 0 ) && ( configCHECK_FOR_STACK_OVERFLOW != 0 ) */
/* vApplicationMallocFailedHook is called when memorry allocation fails. /* vApplicationMallocFailedHook is called when memorry allocation fails.
This is usefull in application development, for debugging. To use this * This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in * hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in
"FreeRTOSConfig.h" header file. */ * "FreeRTOSConfig.h" header file. */
// void vApplicationMallocFailedHook( void ) #if ( configUSE_MALLOC_FAILED_HOOK != 0 )
// { void vApplicationMallocFailedHook( void )
// for( ;; ); {
// } volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
taskENTER_CRITICAL();
/* To debug this failure set ulSetToNonZeroInDebuggerToContinue
* to a non-zero value using a debugger. */
while( ulSetToNonZeroInDebuggerToContinue == 0 )
{
/* No-Op */
portNOP();
}
taskEXIT_CRITICAL();
}
#endif /* configUSE_MALLOC_FAILED_HOOK */

View file

@ -63,12 +63,12 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -76,8 +76,8 @@ the queue empty. */
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -92,7 +92,7 @@ void main_blinky( void )
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
@ -107,14 +107,16 @@ void main_blinky( void )
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle * there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from * and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for * User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The * more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be * mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */ * a privileged mode (not user mode). */
for( ;; ); for( ; ; )
{
}
} }
void init_blinky( void ) void init_blinky( void )
@ -123,10 +125,10 @@ void init_blinky( void )
PORTC.DIRSET = PIN6_bm; PORTC.DIRSET = PIN6_bm;
} }
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
@ -134,37 +136,37 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. */ /* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL; const unsigned long ulExpectedValue = 100UL;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == ulExpectedValue ) if( ulReceivedValue == ulExpectedValue )
{ {
/* Toggle LED on pin PC6. */ /* Toggle LED on pin PC6. */

View file

@ -13,36 +13,38 @@
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 6 ) #define mainCHECK_TASK_LED ( 6 )
/* The check task, as described at the top of this file. */ /* The check task, as described at the top of this file. */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
void main_full( void ) void main_full( void )
{ {
vStartSemaphoreTasks(mainSEM_TEST_PRIORITY); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartTaskNotifyTask(); vStartTaskNotifyTask();
vStartRegTestTasks(); vStartRegTestTasks();
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
/* Create the task that performs the 'check' functionality, as described at /* Create the task that performs the 'check' functionality, as described at
the top of this file. */ * the top of this file. */
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle * there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from * and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for * User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The * more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be * mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */ * a privileged mode (not user mode). */
for( ;; ); for( ; ; )
{
}
} }
void init_full( void ) void init_full( void )
@ -50,28 +52,28 @@ void init_full( void )
vParTestInitialise(); vParTestInitialise();
} }
static void prvCheckTask( void *pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Just to stop compiler warnings. */ /* Just to stop compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration * operating without error. The onboard LED is toggled on each iteration
unless an error occurred. */ * unless an error occurred. */
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. */ /* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_PERIOD ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_PERIOD );
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
ulErrorFound |= 1UL << 0UL; ulErrorFound |= 1UL << 0UL;
@ -87,7 +89,7 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound |= 1UL << 2UL; ulErrorFound |= 1UL << 2UL;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound |= 1UL << 3UL; ulErrorFound |= 1UL << 3UL;
} }
@ -95,7 +97,7 @@ unsigned long ulErrorFound = pdFALSE;
if( ulErrorFound == pdFALSE ) if( ulErrorFound == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }

View file

@ -37,7 +37,7 @@
#include "regtest.h" #include "regtest.h"
/* Priority definitions for most of the tasks in the demo application. Some /* Priority definitions for most of the tasks in the demo application. Some
tasks just use the idle priority. */ * tasks just use the idle priority. */
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
@ -46,20 +46,20 @@ tasks just use the idle priority. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 7 ) #define mainCOM_TEST_LED ( 7 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 6 ) #define mainCHECK_TASK_LED ( 6 )
/* The period between executions of the check task. */ /* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS )
/* An address in the EEPROM used to count resets. This is used to check that /* An address in the EEPROM used to count resets. This is used to check that
the demo application is not unexpectedly resetting. */ * the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( 0x1400 ) #define mainRESET_COUNT_ADDRESS ( 0x1400 )
/* The number of coroutines to create. */ /* The number of coroutines to create. */
@ -68,7 +68,7 @@ the demo application is not unexpectedly resetting. */
/* /*
* The task function for the "Check" task. * The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks the unique counts of other tasks to ensure they are still operational. * Checks the unique counts of other tasks to ensure they are still operational.
@ -99,8 +99,8 @@ void main_minimal( void )
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION /* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define * as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */ * configUSE_PREEMPTION as 0. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
@ -113,22 +113,22 @@ void init_minimal( void )
vParTestInitialise(); vParTestInitialise();
} }
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
static volatile unsigned long ulDummyVariable = 3UL; static volatile unsigned long ulDummyVariable = 3UL;
/* The parameters are not used. */ /* The parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */ * operating without error. */
for( ;; ) for( ; ; )
{ {
vTaskDelay( mainCHECK_PERIOD ); vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the /* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important - * integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */ * see the demo application documentation for more info. */
ulDummyVariable *= 3; ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning(); prvCheckOtherTasksAreStillRunning();
@ -138,7 +138,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void ) static void prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -163,7 +163,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xErrorHasOccurred == pdFALSE ) if( xErrorHasOccurred == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
@ -171,7 +171,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void ) static void prvIncrementResetCount( void )
{ {
unsigned char ucResetCount; unsigned char ucResetCount;
eeprom_read_block( &ucResetCount, ( void * ) mainRESET_COUNT_ADDRESS, sizeof( ucResetCount ) ); eeprom_read_block( &ucResetCount, ( void * ) mainRESET_COUNT_ADDRESS, sizeof( ucResetCount ) );
ucResetCount++; ucResetCount++;

View file

@ -82,7 +82,7 @@
#include "chip.h" #include "chip.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -103,14 +103,15 @@ static void prvSetupHardware( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port /* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port
layer. */ * layer. */
void vApplicationIRQHandler( void ); void vApplicationIRQHandler( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -121,8 +122,8 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
@ -139,7 +140,7 @@ int main( void )
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Disable watchdog */ /* Disable watchdog */
wdt_disable( ); wdt_disable();
/* Set protect mode in the AIC for easier debugging. */ /* Set protect mode in the AIC for easier debugging. */
AIC->AIC_DCR |= AIC_DCR_PROT; AIC->AIC_DCR |= AIC_DCR_PROT;
@ -147,7 +148,7 @@ static void prvSetupHardware( void )
/* Configure ports used by LEDs. */ /* Configure ports used by LEDs. */
vParTestInitialise(); vParTestInitialise();
#if defined (ddram) #if defined( ddram )
MMU_Initialize( ( uint32_t * ) 0x30C000 ); MMU_Initialize( ( uint32_t * ) 0x30C000 );
CP15_EnableMMU(); CP15_EnableMMU();
CP15_EnableDcache(); CP15_EnableDcache();
@ -159,24 +160,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
@ -185,15 +187,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -201,9 +203,10 @@ volatile size_t xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( const char * pcFile, unsigned long ulLine ) void vAssertCalled( const char * pcFile,
unsigned long ulLine )
{ {
volatile unsigned long ul = 0; volatile unsigned long ul = 0;
( void ) pcFile; ( void ) pcFile;
( void ) ulLine; ( void ) ulLine;
@ -211,7 +214,7 @@ volatile unsigned long ul = 0;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Set ul to a non-zero value using the debugger to step out of this /* Set ul to a non-zero value using the debugger to step out of this
function. */ * function. */
while( ul == 0 ) while( ul == 0 )
{ {
portNOP(); portNOP();
@ -226,7 +229,7 @@ void vApplicationTickHook( void )
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
@ -235,24 +238,24 @@ void vApplicationTickHook( void )
/* Call the periodic event group from ISR demo. */ /* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing(); vPeriodicEventGroupsProcessing();
} }
#endif #endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The function called by the RTOS port layer after it has managed interrupt /* The function called by the RTOS port layer after it has managed interrupt
entry. */ * entry. */
void vApplicationIRQHandler( void ) void vApplicationIRQHandler( void )
{ {
typedef void (*ISRFunction_t)( void ); typedef void (* ISRFunction_t)( void );
ISRFunction_t pxISRFunction; ISRFunction_t pxISRFunction;
volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS; volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
/* Obtain the address of the interrupt handler from the AIR. */ /* Obtain the address of the interrupt handler from the AIR. */
pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR; pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR;
/* Write back to the SAMA5's interrupt controller's IVR register in case the /* Write back to the SAMA5's interrupt controller's IVR register in case the
CPU is in protect mode. If the interrupt controller is not in protect mode * CPU is in protect mode. If the interrupt controller is not in protect mode
then this write is not necessary. */ * then this write is not necessary. */
*pulAIC_IVR = ( uint32_t ) pxISRFunction; *pulAIC_IVR = ( uint32_t ) pxISRFunction;
/* Ensure the write takes before re-enabling interrupts. */ /* Ensure the write takes before re-enabling interrupts. */
@ -265,14 +268,15 @@ volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
} }
/* Keep the linker quiet. */ /* Keep the linker quiet. */
size_t __write(int, const unsigned char *, size_t); size_t __write( int,
size_t __write(int f, const unsigned char *p, size_t s) const unsigned char *,
size_t );
size_t __write( int f,
const unsigned char * p,
size_t s )
{ {
(void) f; ( void ) f;
(void) p; ( void ) p;
(void) s; ( void ) s;
return 0; return 0;
} }

View file

@ -57,7 +57,7 @@
#include "chip.h" #include "chip.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -78,14 +78,15 @@ static void prvSetupHardware( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port /* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port
layer. */ * layer. */
void vApplicationIRQHandler( void ); void vApplicationIRQHandler( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -96,8 +97,8 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
@ -122,7 +123,7 @@ static void prvSetupHardware( void )
/* Configure ports used by LEDs. */ /* Configure ports used by LEDs. */
vParTestInitialise(); vParTestInitialise();
#if defined (ddram) #if defined( ddram )
MMU_Initialize( ( uint32_t * ) 0x30C000 ); MMU_Initialize( ( uint32_t * ) 0x30C000 );
CP15_EnableMMU(); CP15_EnableMMU();
CP15_EnableDcache(); CP15_EnableDcache();
@ -134,24 +135,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
@ -160,15 +162,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -176,9 +178,10 @@ volatile size_t xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( const char * pcFile, unsigned long ulLine ) void vAssertCalled( const char * pcFile,
unsigned long ulLine )
{ {
volatile unsigned long ul = 0; volatile unsigned long ul = 0;
( void ) pcFile; ( void ) pcFile;
( void ) ulLine; ( void ) ulLine;
@ -186,7 +189,7 @@ volatile unsigned long ul = 0;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Set ul to a non-zero value using the debugger to step out of this /* Set ul to a non-zero value using the debugger to step out of this
function. */ * function. */
while( ul == 0 ) while( ul == 0 )
{ {
portNOP(); portNOP();
@ -201,7 +204,7 @@ void vApplicationTickHook( void )
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
@ -210,24 +213,24 @@ void vApplicationTickHook( void )
/* Call the periodic event group from ISR demo. */ /* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing(); vPeriodicEventGroupsProcessing();
} }
#endif #endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The function called by the RTOS port layer after it has managed interrupt /* The function called by the RTOS port layer after it has managed interrupt
entry. */ * entry. */
void vApplicationIRQHandler( void ) void vApplicationIRQHandler( void )
{ {
typedef void (*ISRFunction_t)( void ); typedef void (* ISRFunction_t)( void );
ISRFunction_t pxISRFunction; ISRFunction_t pxISRFunction;
volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS; volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
/* Obtain the address of the interrupt handler from the AIR. */ /* Obtain the address of the interrupt handler from the AIR. */
pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR; pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR;
/* Write back to the SAMA5's interrupt controller's IVR register in case the /* Write back to the SAMA5's interrupt controller's IVR register in case the
CPU is in protect mode. If the interrupt controller is not in protect mode * CPU is in protect mode. If the interrupt controller is not in protect mode
then this write is not necessary. */ * then this write is not necessary. */
*pulAIC_IVR = ( uint32_t ) pxISRFunction; *pulAIC_IVR = ( uint32_t ) pxISRFunction;
/* Ensure the write takes before re-enabling interrupts. */ /* Ensure the write takes before re-enabling interrupts. */
@ -238,5 +241,3 @@ volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
/* Call the installed ISR. */ /* Call the installed ISR. */
pxISRFunction(); pxISRFunction();
} }

View file

@ -57,7 +57,7 @@
#include "chip.h" #include "chip.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -71,21 +71,22 @@ static void prvSetupHardware( void );
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
*/ */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
extern void main_blinky( void ); extern void main_blinky( void );
#else #else
extern void main_full( void ); extern void main_full( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port /* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port
layer. */ * layer. */
void vApplicationIRQHandler( void ); void vApplicationIRQHandler( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -96,8 +97,8 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
@ -117,13 +118,13 @@ static void prvSetupHardware( void )
WDT_Disable( WDT ); WDT_Disable( WDT );
/* Set protect mode in the AIC for easier debugging. THIS IS COMMENTED OUT /* Set protect mode in the AIC for easier debugging. THIS IS COMMENTED OUT
AS IT RESULTS IN SPURIOUS INTERRUPTS. * AS IT RESULTS IN SPURIOUS INTERRUPTS.
AIC->AIC_DCR |= AIC_DCR_PROT; */ * AIC->AIC_DCR |= AIC_DCR_PROT; */
/* Configure ports used by LEDs. */ /* Configure ports used by LEDs. */
vParTestInitialise(); vParTestInitialise();
#if defined (ddram) #if defined( ddram )
{ {
MMU_Initialize( ( uint32_t * ) 0x20C000 ); MMU_Initialize( ( uint32_t * ) 0x20C000 );
CP15_EnableMMU(); CP15_EnableMMU();
@ -137,24 +138,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
@ -163,15 +165,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -179,9 +181,10 @@ volatile size_t xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( const char * pcFile, unsigned long ulLine ) void vAssertCalled( const char * pcFile,
unsigned long ulLine )
{ {
volatile unsigned long ul = 0; volatile unsigned long ul = 0;
( void ) pcFile; ( void ) pcFile;
( void ) ulLine; ( void ) ulLine;
@ -189,7 +192,7 @@ volatile unsigned long ul = 0;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Set ul to a non-zero value using the debugger to step out of this /* Set ul to a non-zero value using the debugger to step out of this
function. */ * function. */
while( ul == 0 ) while( ul == 0 )
{ {
portNOP(); portNOP();
@ -204,7 +207,7 @@ void vApplicationTickHook( void )
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
@ -213,24 +216,24 @@ void vApplicationTickHook( void )
/* Call the periodic event group from ISR demo. */ /* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing(); vPeriodicEventGroupsProcessing();
} }
#endif #endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The function called by the RTOS port layer after it has managed interrupt /* The function called by the RTOS port layer after it has managed interrupt
entry. */ * entry. */
void vApplicationIRQHandler( void ) void vApplicationIRQHandler( void )
{ {
typedef void (*ISRFunction_t)( void ); typedef void (* ISRFunction_t)( void );
ISRFunction_t pxISRFunction; ISRFunction_t pxISRFunction;
volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS; volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
/* Obtain the address of the interrupt handler from the AIR. */ /* Obtain the address of the interrupt handler from the AIR. */
pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR; pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR;
/* Write back to the SAMA5's interrupt controller's IVR register in case the /* Write back to the SAMA5's interrupt controller's IVR register in case the
CPU is in protect mode. If the interrupt controller is not in protect mode * CPU is in protect mode. If the interrupt controller is not in protect mode
then this write is not necessary. */ * then this write is not necessary. */
*pulAIC_IVR = ( uint32_t ) pxISRFunction; *pulAIC_IVR = ( uint32_t ) pxISRFunction;
/* Ensure the write takes before re-enabling interrupts. */ /* Ensure the write takes before re-enabling interrupts. */
@ -241,4 +244,3 @@ volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
/* Call the installed ISR. */ /* Call the installed ISR. */
pxISRFunction(); pxISRFunction();
} }

View file

@ -95,25 +95,26 @@ static void prvSetupHardware( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configAPPLICATION_ALLOCATED_HEAP is set to 1 in FreeRTOSConfig.h so the /* configAPPLICATION_ALLOCATED_HEAP is set to 1 in FreeRTOSConfig.h so the
application can define the array used as the FreeRTOS heap. This is done so the * application can define the array used as the FreeRTOS heap. This is done so the
heap can be forced into fast internal RAM - useful because the stacks used by * heap can be forced into fast internal RAM - useful because the stacks used by
the tasks come from this space. */ * the tasks come from this space. */
uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__ ( ( section( ".oc_ram" ) ) ); uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__( ( section( ".oc_ram" ) ) );
/* FreeRTOS uses its own interrupt handler code. This code cannot use the array /* FreeRTOS uses its own interrupt handler code. This code cannot use the array
of handlers defined by the Altera drivers because the array is declared static, * of handlers defined by the Altera drivers because the array is declared static,
and so not accessible outside of the dirver's source file. Instead declare an * and so not accessible outside of the dirver's source file. Instead declare an
array for use by the FreeRTOS handler. See: * array for use by the FreeRTOS handler. See:
http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html. */ * http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html. */
static INT_DISPATCH_t xISRHandlers[ ALT_INT_PROVISION_INT_COUNT ]; static INT_DISPATCH_t xISRHandlers[ ALT_INT_PROVISION_INT_COUNT ];
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -124,8 +125,8 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainSELECTED_APPLICATION setting is described at the top /* The mainSELECTED_APPLICATION setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
@ -142,15 +143,15 @@ int main( void )
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
extern uint8_t __cs3_interrupt_vector; extern uint8_t __cs3_interrupt_vector;
uint32_t ulSCTLR, ulVectorTable = ( uint32_t ) &__cs3_interrupt_vector; uint32_t ulSCTLR, ulVectorTable = ( uint32_t ) &__cs3_interrupt_vector;
const uint32_t ulVBit = 13U; const uint32_t ulVBit = 13U;
alt_int_global_init(); alt_int_global_init();
alt_int_cpu_binary_point_set( 0 ); alt_int_cpu_binary_point_set( 0 );
/* Clear SCTLR.V for low vectors and map the vector table to the beginning /* Clear SCTLR.V for low vectors and map the vector table to the beginning
of the code. */ * of the code. */
__asm( "MRC p15, 0, %0, c1, c0, 0" : "=r" ( ulSCTLR ) ); __asm( "MRC p15, 0, %0, c1, c0, 0" : "=r" ( ulSCTLR ) );
ulSCTLR &= ~( 1 << ulVBit ); ulSCTLR &= ~( 1 << ulVBit );
__asm( "MCR p15, 0, %0, c1, c0, 0" : : "r" ( ulSCTLR ) ); __asm( "MCR p15, 0, %0, c1, c0, 0" : : "r" ( ulSCTLR ) );
@ -160,7 +161,7 @@ const uint32_t ulVBit = 13U;
mmu_init(); mmu_init();
/* GPIO for LEDs. ParTest is a historic name which used to stand for /* GPIO for LEDs. ParTest is a historic name which used to stand for
parallel port test. */ * parallel port test. */
vParTestInitialise(); vParTestInitialise();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -168,39 +169,46 @@ const uint32_t ulVBit = 13U;
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -208,9 +216,10 @@ volatile size_t xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( const char * pcFile, unsigned long ulLine ) void vAssertCalled( const char * pcFile,
unsigned long ulLine )
{ {
volatile unsigned long ul = 0; volatile unsigned long ul = 0;
( void ) pcFile; ( void ) pcFile;
( void ) ulLine; ( void ) ulLine;
@ -218,7 +227,7 @@ volatile unsigned long ul = 0;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Set ul to a non-zero value using the debugger to step out of this /* Set ul to a non-zero value using the debugger to step out of this
function. */ * function. */
while( ul == 0 ) while( ul == 0 )
{ {
portNOP(); portNOP();
@ -230,10 +239,10 @@ volatile unsigned long ul = 0;
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 )
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
@ -245,15 +254,16 @@ void vApplicationTickHook( void )
/* Call the periodic test that uses mutexes form an interrupt. */ /* Call the periodic test that uses mutexes form an interrupt. */
vInterruptSemaphorePeriodicTest(); vInterruptSemaphorePeriodicTest();
} }
#endif #endif /* if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vConfigureTickInterrupt( void ) void vConfigureTickInterrupt( void )
{ {
alt_freq_t ulTempFrequency; alt_freq_t ulTempFrequency;
const alt_freq_t ulMicroSecondsPerSecond = 1000000UL; const alt_freq_t ulMicroSecondsPerSecond = 1000000UL;
void FreeRTOS_Tick_Handler( void );
void FreeRTOS_Tick_Handler( void );
/* Interrupts are disabled when this function is called. */ /* Interrupts are disabled when this function is called. */
@ -276,8 +286,8 @@ void FreeRTOS_Tick_Handler( void );
alt_gpt_tmr_start( ALT_GPT_CPU_PRIVATE_TMR ); alt_gpt_tmr_start( ALT_GPT_CPU_PRIVATE_TMR );
/* Register the standard FreeRTOS Cortex-A tick handler as the timer's /* Register the standard FreeRTOS Cortex-A tick handler as the timer's
interrupt handler. The handler clears the interrupt using the * interrupt handler. The handler clears the interrupt using the
configCLEAR_TICK_INTERRUPT() macro, which is defined in FreeRTOSConfig.h. */ * configCLEAR_TICK_INTERRUPT() macro, which is defined in FreeRTOSConfig.h. */
vRegisterIRQHandler( ALT_INT_INTERRUPT_PPI_TIMER_PRIVATE, ( alt_int_callback_t ) FreeRTOS_Tick_Handler, NULL ); vRegisterIRQHandler( ALT_INT_INTERRUPT_PPI_TIMER_PRIVATE, ( alt_int_callback_t ) FreeRTOS_Tick_Handler, NULL );
/* This tick interrupt must run at the lowest priority. */ /* This tick interrupt must run at the lowest priority. */
@ -289,11 +299,12 @@ void FreeRTOS_Tick_Handler( void );
/* Finally, enable the interrupt. */ /* Finally, enable the interrupt. */
alt_gpt_int_clear_pending( ALT_GPT_CPU_PRIVATE_TMR ); alt_gpt_int_clear_pending( ALT_GPT_CPU_PRIVATE_TMR );
alt_gpt_int_enable( ALT_GPT_CPU_PRIVATE_TMR ); alt_gpt_int_enable( ALT_GPT_CPU_PRIVATE_TMR );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vRegisterIRQHandler( uint32_t ulID, alt_int_callback_t pxHandlerFunction, void *pvContext ) void vRegisterIRQHandler( uint32_t ulID,
alt_int_callback_t pxHandlerFunction,
void * pvContext )
{ {
if( ulID < ALT_INT_PROVISION_INT_COUNT ) if( ulID < ALT_INT_PROVISION_INT_COUNT )
{ {
@ -305,24 +316,23 @@ void vRegisterIRQHandler( uint32_t ulID, alt_int_callback_t pxHandlerFunction, v
void vApplicationIRQHandler( uint32_t ulICCIAR ) void vApplicationIRQHandler( uint32_t ulICCIAR )
{ {
uint32_t ulInterruptID; uint32_t ulInterruptID;
void *pvContext; void * pvContext;
alt_int_callback_t pxISR; alt_int_callback_t pxISR;
/* Re-enable interrupts. */ /* Re-enable interrupts. */
__asm ( "cpsie i" ); __asm( "cpsie i" );
/* The ID of the interrupt is obtained by bitwise anding the ICCIAR value /* The ID of the interrupt is obtained by bitwise anding the ICCIAR value
with 0x3FF. */ * with 0x3FF. */
ulInterruptID = ulICCIAR & 0x3FFUL; ulInterruptID = ulICCIAR & 0x3FFUL;
if( ulInterruptID < ALT_INT_PROVISION_INT_COUNT ) if( ulInterruptID < ALT_INT_PROVISION_INT_COUNT )
{ {
/* Call the function installed in the array of installed handler /* Call the function installed in the array of installed handler
functions. */ * functions. */
pxISR = xISRHandlers[ ulInterruptID ].pxISR; pxISR = xISRHandlers[ ulInterruptID ].pxISR;
pvContext = xISRHandlers[ ulInterruptID ].pvContext; pvContext = xISRHandlers[ ulInterruptID ].pvContext;
pxISR( ulICCIAR, pvContext ); pxISR( ulICCIAR, pvContext );
} }
} }

View file

@ -74,12 +74,12 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* The LED toggled by the Rx task. */ /* The LED toggled by the Rx task. */
@ -90,8 +90,8 @@ the queue empty. */
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -108,7 +108,7 @@ void main_blinky( void )
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
@ -123,21 +123,23 @@ void main_blinky( void )
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle * there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from * and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for * User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The * more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be * mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */ * a privileged mode (not user mode). */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
@ -145,37 +147,37 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. */ /* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL; const unsigned long ulExpectedValue = 100UL;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == ulExpectedValue ) if( ulReceivedValue == ulExpectedValue )
{ {
vParTestToggleLED( mainTASK_LED ); vParTestToggleLED( mainTASK_LED );
@ -184,4 +186,3 @@ const unsigned long ulExpectedValue = 100UL;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -102,7 +102,7 @@
#define mainQUEUE_OVERWRITE_PRIORITY ( tskIDLE_PRIORITY ) #define mainQUEUE_OVERWRITE_PRIORITY ( tskIDLE_PRIORITY )
/* The priority used by the UART command console task. This is very basic and /* The priority used by the UART command console task. This is very basic and
uses the Altera polling UART driver - so *must* run at the idle priority. */ * uses the Altera polling UART driver - so *must* run at the idle priority. */
#define mainUART_COMMAND_CONSOLE_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainUART_COMMAND_CONSOLE_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* The LED used by the check task. */ /* The LED used by the check task. */
@ -112,17 +112,17 @@ uses the Altera polling UART driver - so *must* run at the idle priority. */
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The period of the check task, in ms, provided no errors have been reported by /* The period of the check task, in ms, provided no errors have been reported by
any of the standard demo tasks. ms are converted to the equivalent in ticks * any of the standard demo tasks. ms are converted to the equivalent in ticks
using the pdMS_TO_TICKS() macro constant. */ * using the pdMS_TO_TICKS() macro constant. */
#define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 3000UL ) #define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 3000UL )
/* The period of the check task, in ms, if an error has been reported in one of /* The period of the check task, in ms, if an error has been reported in one of
the standard demo tasks. ms are converted to the equivalent in ticks using the * the standard demo tasks. ms are converted to the equivalent in ticks using the
pdMS_TO_TICKS() macro. */ * pdMS_TO_TICKS() macro. */
#define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 200UL ) #define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 200UL )
/* Parameters that are passed into the register check tasks solely for the /* Parameters that are passed into the register check tasks solely for the
purpose of ensuring parameters are passed into tasks correctly. */ * purpose of ensuring parameters are passed into tasks correctly. */
#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 ) #define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 )
#define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 ) #define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 )
@ -135,7 +135,7 @@ purpose of ensuring parameters are passed into tasks correctly. */
/* /*
* The check task, as described at the top of this file. * The check task, as described at the top of this file.
*/ */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
/* /*
* Register check tasks, and the tasks used to write over and check the contents * Register check tasks, and the tasks used to write over and check the contents
@ -144,9 +144,9 @@ static void prvCheckTask( void *pvParameters );
* entry points are kept in the C file for the convenience of checking the task * entry points are kept in the C file for the convenience of checking the task
* parameter. * parameter.
*/ */
static void prvRegTestTaskEntry1( void *pvParameters ); static void prvRegTestTaskEntry1( void * pvParameters );
extern void vRegTest1Implementation( void ); extern void vRegTest1Implementation( void );
static void prvRegTestTaskEntry2( void *pvParameters ); static void prvRegTestTaskEntry2( void * pvParameters );
extern void vRegTest2Implementation( void ); extern void vRegTest2Implementation( void );
/* /*
@ -158,21 +158,22 @@ extern void vRegisterSampleCLICommands( void );
/* /*
* The task that manages the FreeRTOS+CLI input and output. * The task that manages the FreeRTOS+CLI input and output.
*/ */
extern void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriority ); extern void vUARTCommandConsoleStart( uint16_t usStackSize,
UBaseType_t uxPriority );
/* /*
* A high priority task that does nothing other than execute at a pseudo random * A high priority task that does nothing other than execute at a pseudo random
* time to ensure the other test tasks don't just execute in a repeating * time to ensure the other test tasks don't just execute in a repeating
* pattern. * pattern.
*/ */
static void prvPseudoRandomiser( void *pvParameters ); static void prvPseudoRandomiser( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check task. If the variables keep incrementing, * register check tasks to the check task. If the variables keep incrementing,
then the register check tasks have not discovered any errors. If a variable * then the register check tasks have not discovered any errors. If a variable
stops incrementing, then an error has been found. */ * stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -180,8 +181,8 @@ volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
void main_full( void ) void main_full( void )
{ {
/* Start all the other standard demo/test tasks. They have no particular /* Start all the other standard demo/test tasks. They have no particular
functionality, but do demonstrate how to use the FreeRTOS API and test the * functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */ * kernel port. */
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
@ -196,7 +197,7 @@ void main_full( void )
vStartInterruptSemaphoreTasks(); vStartInterruptSemaphoreTasks();
/* Start the tasks that implements the command console on the UART, as /* Start the tasks that implements the command console on the UART, as
described above. */ * described above. */
vUARTCommandConsoleStart( mainUART_COMMAND_CONSOLE_STACK_SIZE, mainUART_COMMAND_CONSOLE_TASK_PRIORITY ); vUARTCommandConsoleStart( mainUART_COMMAND_CONSOLE_STACK_SIZE, mainUART_COMMAND_CONSOLE_TASK_PRIORITY );
/* Register the standard CLI commands. */ /* Register the standard CLI commands. */
@ -210,56 +211,58 @@ void main_full( void )
xTaskCreate( prvPseudoRandomiser, "Rnd", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL ); xTaskCreate( prvPseudoRandomiser, "Rnd", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
/* Create the task that performs the 'check' functionality, as described at /* Create the task that performs the 'check' functionality, as described at
the top of this file. */ * the top of this file. */
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* The set of tasks created by the following function call have to be /* The set of tasks created by the following function call have to be
created last as they keep account of the number of tasks they expect to see * created last as they keep account of the number of tasks they expect to see
running. */ * running. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle * there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from * and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for * User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The * more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be * mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */ * a privileged mode (not user mode). */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTask( void *pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Just to stop compiler warnings. */ /* Just to stop compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration. * operating without error. The onboard LED is toggled on each iteration.
If an error is detected then the delay period is decreased from * If an error is detected then the delay period is decreased from
mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the * mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the
effect of increasing the rate at which the onboard LED toggles, and in so * effect of increasing the rate at which the onboard LED toggles, and in so
doing gives visual feedback of the system status. */ * doing gives visual feedback of the system status. */
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. */ /* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod ); vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod );
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
ulErrorFound = 1 << 1; ulErrorFound = 1 << 1;
@ -275,17 +278,17 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound = 1 << 3; ulErrorFound = 1 << 3;
} }
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = 1 << 4; ulErrorFound = 1 << 4;
} }
if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = 1 << 5; ulErrorFound = 1 << 5;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = 1 << 6; ulErrorFound = 1 << 6;
} }
@ -330,6 +333,7 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound = 1 << 14; ulErrorFound = 1 << 14;
} }
ulLastRegTest1Value = ulRegTest1LoopCounter; ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ /* Check that the register test 2 task is still running. */
@ -337,35 +341,36 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound = 1 << 15; ulErrorFound = 1 << 15;
} }
ulLastRegTest2Value = ulRegTest2LoopCounter; ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If /* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainNO_ERROR_CHECK_TASK_PERIOD milliseconds then * the LED toggles every mainNO_ERROR_CHECK_TASK_PERIOD milliseconds then
everything is ok. A faster toggle indicates an error. */ * everything is ok. A faster toggle indicates an error. */
vParTestToggleLED( mainCHECK_LED ); vParTestToggleLED( mainCHECK_LED );
if( ulErrorFound != pdFALSE ) if( ulErrorFound != pdFALSE )
{ {
/* An error has been detected in one of the tasks - flash the LED /* An error has been detected in one of the tasks - flash the LED
at a higher frequency to give visible feedback that something has * at a higher frequency to give visible feedback that something has
gone wrong (it might just be that the loop back connector required * gone wrong (it might just be that the loop back connector required
by the comtest tasks has not been fitted). */ * by the comtest tasks has not been fitted). */
xDelayPeriod = mainERROR_CHECK_TASK_PERIOD; xDelayPeriod = mainERROR_CHECK_TASK_PERIOD;
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvRegTestTaskEntry1( void *pvParameters ) static void prvRegTestTaskEntry1( void * pvParameters )
{ {
/* Although the regtest task is written in assembler, its entry point is /* Although the regtest task is written in assembler, its entry point is
written in C for convenience of checking the task parameter is being passed * written in C for convenience of checking the task parameter is being passed
in correctly. */ * in correctly. */
if( pvParameters == mainREG_TEST_TASK_1_PARAMETER ) if( pvParameters == mainREG_TEST_TASK_1_PARAMETER )
{ {
/* The reg test task also tests the floating point registers. Tasks /* The reg test task also tests the floating point registers. Tasks
that use the floating point unit must call vPortTaskUsesFPU() before * that use the floating point unit must call vPortTaskUsesFPU() before
any floating point instructions are executed. */ * any floating point instructions are executed. */
vPortTaskUsesFPU(); vPortTaskUsesFPU();
/* Start the part of the test that is written in assembler. */ /* Start the part of the test that is written in assembler. */
@ -373,22 +378,22 @@ static void prvRegTestTaskEntry1( void *pvParameters )
} }
/* The following line will only execute if the task parameter is found to /* The following line will only execute if the task parameter is found to
be incorrect. The check task will detect that the regtest loop counter is * be incorrect. The check task will detect that the regtest loop counter is
not being incremented and flag an error. */ * not being incremented and flag an error. */
vTaskDelete( NULL ); vTaskDelete( NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvRegTestTaskEntry2( void *pvParameters ) static void prvRegTestTaskEntry2( void * pvParameters )
{ {
/* Although the regtest task is written in assembler, its entry point is /* Although the regtest task is written in assembler, its entry point is
written in C for convenience of checking the task parameter is being passed * written in C for convenience of checking the task parameter is being passed
in correctly. */ * in correctly. */
if( pvParameters == mainREG_TEST_TASK_2_PARAMETER ) if( pvParameters == mainREG_TEST_TASK_2_PARAMETER )
{ {
/* The reg test task also tests the floating point registers. Tasks /* The reg test task also tests the floating point registers. Tasks
that use the floating point unit must call vPortTaskUsesFPU() before * that use the floating point unit must call vPortTaskUsesFPU() before
any floating point instructions are executed. */ * any floating point instructions are executed. */
vPortTaskUsesFPU(); vPortTaskUsesFPU();
/* Start the part of the test that is written in assembler. */ /* Start the part of the test that is written in assembler. */
@ -396,22 +401,22 @@ static void prvRegTestTaskEntry2( void *pvParameters )
} }
/* The following line will only execute if the task parameter is found to /* The following line will only execute if the task parameter is found to
be incorrect. The check task will detect that the regtest loop counter is * be incorrect. The check task will detect that the regtest loop counter is
not being incremented and flag an error. */ * not being incremented and flag an error. */
vTaskDelete( NULL ); vTaskDelete( NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvPseudoRandomiser( void *pvParameters ) static void prvPseudoRandomiser( void * pvParameters )
{ {
const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL, ulMinDelay = ( 35 / portTICK_PERIOD_MS ); const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL, ulMinDelay = ( 35 / portTICK_PERIOD_MS );
volatile uint32_t ulNextRand = ( uint32_t ) &pvParameters, ulValue; volatile uint32_t ulNextRand = ( uint32_t ) &pvParameters, ulValue;
/* This task does nothing other than ensure there is a little bit of /* This task does nothing other than ensure there is a little bit of
disruption in the scheduling pattern of the other tasks. Normally this is * disruption in the scheduling pattern of the other tasks. Normally this is
done by generating interrupts at pseudo random times. */ * done by generating interrupts at pseudo random times. */
for( ;; ) for( ; ; )
{ {
ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement; ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
ulValue = ( ulNextRand >> 16UL ) & 0xffUL; ulValue = ( ulNextRand >> 16UL ) & 0xffUL;
@ -425,18 +430,12 @@ volatile uint32_t ulNextRand = ( uint32_t ) &pvParameters, ulValue;
while( ulValue > 0 ) while( ulValue > 0 )
{ {
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
ulValue--; ulValue--;
} }
} }
} }

View file

@ -83,7 +83,7 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The time between cycles of the 'check' functionality (defined within the /* The time between cycles of the 'check' functionality (defined within the
tick hook). */ * tick hook). */
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* The LCD task uses the sprintf function so requires a little more stack too. */ /* The LCD task uses the sprintf function so requires a little more stack too. */
@ -99,11 +99,11 @@ tick hook). */
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* The maximum number of message that can be waiting for display at any one /* The maximum number of message that can be waiting for display at any one
time. */ * time. */
#define mainLCD_QUEUE_SIZE ( 3 ) #define mainLCD_QUEUE_SIZE ( 3 )
/* Constants used by the comtest tasks. There isn't a spare LED so an invalid /* Constants used by the comtest tasks. There isn't a spare LED so an invalid
LED is specified. */ * LED is specified. */
#define mainBAUD_RATE ( 115200 ) #define mainBAUD_RATE ( 115200 )
#define mainCOM_TEST_LED ( 10 ) #define mainCOM_TEST_LED ( 10 )
@ -118,13 +118,14 @@ static void prvSetupHardware( void );
* The LCD gatekeeper task. Tasks wishing to write to the LCD do not access * The LCD gatekeeper task. Tasks wishing to write to the LCD do not access
* the LCD directly, but instead send the message to the LCD gatekeeper task. * the LCD directly, but instead send the message to the LCD gatekeeper task.
*/ */
static void prvLCDTask( void *pvParameters ); static void prvLCDTask( void * pvParameters );
/* /*
* Hook functions that can get called by the kernel. The 'check' functionality * Hook functions that can get called by the kernel. The 'check' functionality
* is implemented within the tick hook. * is implemented within the tick hook.
*/ */
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
/* /*
* The tick hook function as described in the comments at the top of this file. * The tick hook function as described in the comments at the top of this file.
@ -148,11 +149,11 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* Create the queue used by the LCD task. Messages for display on the LCD /* Create the queue used by the LCD task. Messages for display on the LCD
are received via this queue. */ * are received via this queue. */
xLCDQueue = xQueueCreate( mainLCD_QUEUE_SIZE, sizeof( xLCDMessage ) ); xLCDQueue = xQueueCreate( mainLCD_QUEUE_SIZE, sizeof( xLCDMessage ) );
/* Start the standard demo tasks. These do nothing other than test the /* Start the standard demo tasks. These do nothing other than test the
port and provide some APU usage examples. */ * port and provide some APU usage examples. */
vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY ); vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY ); vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
@ -171,7 +172,7 @@ int main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle /* Will only get here if there was insufficient memory to create the idle
task. */ * task. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -185,13 +186,14 @@ void prvSetupHardware( void )
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
static xLCDMessage xMessage = { "PASS" }; static xLCDMessage xMessage = { "PASS" };
static unsigned long ulTicksSinceLastDisplay = 0; static unsigned long ulTicksSinceLastDisplay = 0;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Called from every tick interrupt. Have enough ticks passed to make it /* Called from every tick interrupt. Have enough ticks passed to make it
time to perform our health status check again? */ * time to perform our health status check again? */
ulTicksSinceLastDisplay++; ulTicksSinceLastDisplay++;
if( ulTicksSinceLastDisplay >= mainCHECK_DELAY ) if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
{ {
ulTicksSinceLastDisplay = 0; ulTicksSinceLastDisplay = 0;
@ -201,6 +203,7 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
{ {
xMessage.pcMessage = "ERROR IN GEN Q"; xMessage.pcMessage = "ERROR IN GEN Q";
} }
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
xMessage.pcMessage = "ERROR IN MATH"; xMessage.pcMessage = "ERROR IN MATH";
@ -241,23 +244,26 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pxTask; ( void ) pxTask;
( void ) pcTaskName; ( void ) pcTaskName;
/* If the parameters have been corrupted then inspect pxCurrentTCB to /* If the parameters have been corrupted then inspect pxCurrentTCB to
identify which task has overflowed its stack. */ * identify which task has overflowed its stack. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvLCDTask( void *pvParameters ) static void prvLCDTask( void * pvParameters )
{ {
xLCDMessage xMessage; xLCDMessage xMessage;
unsigned long ulY = 0; unsigned long ulY = 0;
const unsigned long ulX = 5; const unsigned long ulX = 5;
const unsigned long ulMaxY = 250, ulYIncrement = 22, ulWidth = 250, ulHeight = 20;; const unsigned long ulMaxY = 250, ulYIncrement = 22, ulWidth = 250, ulHeight = 20;
/* Initialize LCD. */ /* Initialize LCD. */
LCDD_Initialize(); LCDD_Initialize();
@ -265,10 +271,10 @@ const unsigned long ulMaxY = 250, ulYIncrement = 22, ulWidth = 250, ulHeight = 2
LCDD_Fill( ( void * ) BOARD_LCD_BASE, COLOR_WHITE ); LCDD_Fill( ( void * ) BOARD_LCD_BASE, COLOR_WHITE );
LCDD_DrawString( ( void * ) BOARD_LCD_BASE, 1, ulY + 3, " www.FreeRTOS.org", COLOR_BLACK ); LCDD_DrawString( ( void * ) BOARD_LCD_BASE, 1, ulY + 3, " www.FreeRTOS.org", COLOR_BLACK );
for( ;; ) for( ; ; )
{ {
/* Wait for a message from the check function (which is executed in /* Wait for a message from the check function (which is executed in
the tick hook). */ * the tick hook). */
xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ); xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY );
/* Clear the space where the old message was. */ /* Clear the space where the old message was. */

View file

@ -67,17 +67,18 @@ static void prvSetupHardware( void );
* main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1. * main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1.
* main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0. * main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0.
*/ */
#if( configCREATE_LOW_POWER_DEMO != 0 ) #if ( configCREATE_LOW_POWER_DEMO != 0 )
extern void main_low_power( void ); extern void main_low_power( void );
#else #else
extern void main_full( void ); extern void main_full( void );
#endif /* #if configCREATE_LOW_POWER_DEMO == 1 */ #endif /* #if configCREATE_LOW_POWER_DEMO == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -93,8 +94,8 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_LOW_POWER_DEMO setting is described at the top /* The mainCREATE_LOW_POWER_DEMO setting is described at the top
of this file. */ * of this file. */
#if( configCREATE_LOW_POWER_DEMO != 0 ) #if ( configCREATE_LOW_POWER_DEMO != 0 )
{ {
main_low_power(); main_low_power();
} }
@ -124,24 +125,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
@ -150,15 +152,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -169,13 +171,13 @@ volatile size_t xFreeHeapSpace;
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* The full demo includes tests that run from the tick hook. */ /* The full demo includes tests that run from the tick hook. */
#if( configCREATE_LOW_POWER_DEMO == 0 ) #if ( configCREATE_LOW_POWER_DEMO == 0 )
{ {
extern void vFullDemoTickHook( void ); extern void vFullDemoTickHook( void );
/* Some of the tests and demo tasks executed by the full demo include /* Some of the tests and demo tasks executed by the full demo include
interaction from an interrupt - for which the tick interrupt is used * interaction from an interrupt - for which the tick interrupt is used
via the tick hook function. */ * via the tick hook function. */
vFullDemoTickHook(); vFullDemoTickHook();
} }
#endif #endif
@ -183,51 +185,54 @@ void vApplicationTickHook( void )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */ * used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{ {
/* If the buffers to be provided to the Idle task are declared inside this /* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB; static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */ * state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB; *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */ /* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack; *ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory() * application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */ * to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
uint32_t * pulTimerTaskStackSize )
{ {
/* If the buffers to be provided to the Timer task are declared inside this /* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB; static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer /* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */ * task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB; *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */ /* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack; *ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
} }

View file

@ -67,17 +67,18 @@ static void prvSetupHardware( void );
* main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1. * main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1.
* main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0. * main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0.
*/ */
#if( configCREATE_LOW_POWER_DEMO != 0 ) #if ( configCREATE_LOW_POWER_DEMO != 0 )
extern void main_low_power( void ); extern void main_low_power( void );
#else #else
extern void main_full( void ); extern void main_full( void );
#endif /* #if configCREATE_LOW_POWER_DEMO == 1 */ #endif /* #if configCREATE_LOW_POWER_DEMO == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -93,8 +94,8 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_LOW_POWER_DEMO setting is described at the top /* The mainCREATE_LOW_POWER_DEMO setting is described at the top
of this file. */ * of this file. */
#if( configCREATE_LOW_POWER_DEMO != 0 ) #if ( configCREATE_LOW_POWER_DEMO != 0 )
{ {
main_low_power(); main_low_power();
} }
@ -111,8 +112,8 @@ int main( void )
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
EMU_DCDCInit_TypeDef xDCDInit = EMU_DCDCINIT_STK_DEFAULT; EMU_DCDCInit_TypeDef xDCDInit = EMU_DCDCINIT_STK_DEFAULT;
CMU_HFXOInit_TypeDef xHFXOInit = CMU_HFXOINIT_STK_DEFAULT; CMU_HFXOInit_TypeDef xHFXOInit = CMU_HFXOINIT_STK_DEFAULT;
/* Chip errata */ /* Chip errata */
CHIP_Init(); CHIP_Init();
@ -135,24 +136,25 @@ CMU_HFXOInit_TypeDef xHFXOInit = CMU_HFXOINIT_STK_DEFAULT;
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
@ -161,15 +163,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -180,13 +182,13 @@ volatile size_t xFreeHeapSpace;
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* The full demo includes tests that run from the tick hook. */ /* The full demo includes tests that run from the tick hook. */
#if( configCREATE_LOW_POWER_DEMO == 0 ) #if ( configCREATE_LOW_POWER_DEMO == 0 )
{ {
extern void vFullDemoTickHook( void ); extern void vFullDemoTickHook( void );
/* Some of the tests and demo tasks executed by the full demo include /* Some of the tests and demo tasks executed by the full demo include
interaction from an interrupt - for which the tick interrupt is used * interaction from an interrupt - for which the tick interrupt is used
via the tick hook function. */ * via the tick hook function. */
vFullDemoTickHook(); vFullDemoTickHook();
} }
#endif #endif
@ -194,50 +196,54 @@ void vApplicationTickHook( void )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */ * used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{ {
/* If the buffers to be provided to the Idle task are declared inside this /* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB; static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */ * state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB; *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */ /* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack; *ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory() * application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */ * to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
uint32_t * pulTimerTaskStackSize )
{ {
/* If the buffers to be provided to the Timer task are declared inside this /* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB; static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer /* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */ * task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB; *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */ /* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack; *ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
} }

View file

@ -89,26 +89,26 @@
#define mainNUM_FLASH_CO_ROUTINES ( 5 ) #define mainNUM_FLASH_CO_ROUTINES ( 5 )
/* The length of the queue used to pass received characters to the Comms Rx /* The length of the queue used to pass received characters to the Comms Rx
task. */ * task. */
#define mainRX_QUEUE_LEN ( 5 ) #define mainRX_QUEUE_LEN ( 5 )
/* The priority of the co-routine used to initiate the transmission of the /* The priority of the co-routine used to initiate the transmission of the
string on UART 0. */ * string on UART 0. */
#define mainTX_CO_ROUTINE_PRIORITY ( 1 ) #define mainTX_CO_ROUTINE_PRIORITY ( 1 )
/* Only one co-routine is created so its index is not important. */ /* Only one co-routine is created so its index is not important. */
#define mainTX_CO_ROUTINE_INDEX ( 0 ) #define mainTX_CO_ROUTINE_INDEX ( 0 )
/* The time between transmissions of the string on UART 0. This is pseudo /* The time between transmissions of the string on UART 0. This is pseudo
random in order to generate a bit or randomness to when the interrupts occur.*/ * random in order to generate a bit or randomness to when the interrupts occur.*/
#define mainMIN_TX_DELAY ( 40 / portTICK_PERIOD_MS ) #define mainMIN_TX_DELAY ( 40 / portTICK_PERIOD_MS )
#define mainMAX_TX_DELAY ( ( TickType_t ) 0x7f ) #define mainMAX_TX_DELAY ( ( TickType_t ) 0x7f )
#define mainOFFSET_TIME ( ( TickType_t ) 3 ) #define mainOFFSET_TIME ( ( TickType_t ) 3 )
/* The time the Comms Rx task should wait to receive a character. This should /* The time the Comms Rx task should wait to receive a character. This should
be slightly longer than the time between transmissions. If we do not receive * be slightly longer than the time between transmissions. If we do not receive
a character after this time then there must be an error in the transmission or * a character after this time then there must be an error in the transmission or
the timing of the transmission. */ * the timing of the transmission. */
#define mainCOMMS_RX_DELAY ( mainMAX_TX_DELAY + 20 ) #define mainCOMMS_RX_DELAY ( mainMAX_TX_DELAY + 20 )
/* The task priorities. */ /* The task priorities. */
@ -127,21 +127,21 @@ the timing of the transmission. */
#define mainFIFO_SET ( 0x10 ) #define mainFIFO_SET ( 0x10 )
/* The string that is transmitted on the UART contains sequentially the /* The string that is transmitted on the UART contains sequentially the
characters from mainFIRST_TX_CHAR to mainLAST_TX_CHAR. */ * characters from mainFIRST_TX_CHAR to mainLAST_TX_CHAR. */
#define mainFIRST_TX_CHAR '0' #define mainFIRST_TX_CHAR '0'
#define mainLAST_TX_CHAR 'z' #define mainLAST_TX_CHAR 'z'
/* Just used to walk through the program memory in order that some random data /* Just used to walk through the program memory in order that some random data
can be generated. */ * can be generated. */
#define mainTOTAL_PROGRAM_MEMORY ( ( unsigned long * ) ( 8 * 1024 ) ) #define mainTOTAL_PROGRAM_MEMORY ( ( unsigned long * ) ( 8 * 1024 ) )
#define mainFIRST_PROGRAM_BYTES ( ( unsigned long * ) 4 ) #define mainFIRST_PROGRAM_BYTES ( ( unsigned long * ) 4 )
/* The error routine that is called if the driver library encounters an error. */ /* The error routine that is called if the driver library encounters an error. */
#ifdef DEBUG #ifdef DEBUG
void void __error__( char * pcFilename,
__error__(char *pcFilename, unsigned long ulLine) unsigned long ulLine )
{ {
} }
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -160,12 +160,13 @@ static void vCommsRxTask( void * pvParameters );
* The co-routine that periodically initiates the transmission of the string on * The co-routine that periodically initiates the transmission of the string on
* the UART. * the UART.
*/ */
static void vSerialTxCoRoutine( CoRoutineHandle_t xHandle, unsigned portBASE_TYPE uxIndex ); static void vSerialTxCoRoutine( CoRoutineHandle_t xHandle,
unsigned portBASE_TYPE uxIndex );
/* /*
* Writes a string the the LCD. * Writes a string the the LCD.
*/ */
static void prvWriteString( const char *pcString ); static void prvWriteString( const char * pcString );
/* /*
* Initialisation routine for the UART. * Initialisation routine for the UART.
@ -175,7 +176,8 @@ static void vSerialInit( void );
/* /*
* Thread safe write to the PDC. * Thread safe write to the PDC.
*/ */
static void prvPDCWrite( char cAddress, char cData ); static void prvPDCWrite( char cAddress,
char cData );
/* /*
* Function to simply set a known value into the general purpose registers * Function to simply set a known value into the general purpose registers
@ -197,14 +199,14 @@ static void prvSetupHardware( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Error flag set to pdFAIL if an error is encountered in the tasks/co-routines /* Error flag set to pdFAIL if an error is encountered in the tasks/co-routines
defined within this file. */ * defined within this file. */
unsigned portBASE_TYPE uxErrorStatus = pdPASS; unsigned portBASE_TYPE uxErrorStatus = pdPASS;
/* The next character to transmit. */ /* The next character to transmit. */
static char cNextChar; static char cNextChar;
/* The queue used to transmit characters from the interrupt to the Comms Rx /* The queue used to transmit characters from the interrupt to the Comms Rx
task. */ * task. */
static QueueHandle_t xCommsQueue; static QueueHandle_t xCommsQueue;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -212,7 +214,7 @@ static QueueHandle_t xCommsQueue;
void Main( void ) void Main( void )
{ {
/* Create the queue used to communicate between the UART ISR and the Comms /* Create the queue used to communicate between the UART ISR and the Comms
Rx task. */ * Rx task. */
xCommsQueue = xQueueCreate( mainRX_QUEUE_LEN, sizeof( char ) ); xCommsQueue = xQueueCreate( mainRX_QUEUE_LEN, sizeof( char ) );
/* Setup the ports used by the demo and the clock. */ /* Setup the ports used by the demo and the clock. */
@ -222,7 +224,7 @@ void Main( void )
vStartFlashCoRoutines( mainNUM_FLASH_CO_ROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_CO_ROUTINES );
/* Create the co-routine that initiates the transmission of characters /* Create the co-routine that initiates the transmission of characters
on the UART. */ * on the UART. */
xCoRoutineCreate( vSerialTxCoRoutine, mainTX_CO_ROUTINE_PRIORITY, mainTX_CO_ROUTINE_INDEX ); xCoRoutineCreate( vSerialTxCoRoutine, mainTX_CO_ROUTINE_PRIORITY, mainTX_CO_ROUTINE_INDEX );
/* Create the LCD and Comms Rx tasks. */ /* Create the LCD and Comms Rx tasks. */
@ -233,8 +235,10 @@ void Main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Should not get here unless we did not have enough memory to start the /* Should not get here unless we did not have enough memory to start the
scheduler. */ * scheduler. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -253,8 +257,8 @@ static void prvSetupHardware( void )
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* The co-routines are executed in the idle task using the idle task /* The co-routines are executed in the idle task using the idle task
hook. */ * hook. */
for( ;; ) for( ; ; )
{ {
/* Schedule the co-routines. */ /* Schedule the co-routines. */
vCoRoutineSchedule(); vCoRoutineSchedule();
@ -265,10 +269,11 @@ void vApplicationIdleHook( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvWriteString( const char *pcString ) static void prvWriteString( const char * pcString )
{ {
/* Write pcString to the LED, pausing between each character. */ /* Write pcString to the LED, pausing between each character. */
prvPDCWrite(PDC_LCD_CSR, LCD_CLEAR); prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR );
while( *pcString ) while( *pcString )
{ {
vTaskDelay( mainCHAR_WRITE_DELAY ); vTaskDelay( mainCHAR_WRITE_DELAY );
@ -280,8 +285,9 @@ static void prvWriteString( const char *pcString )
void vLCDTask( void * pvParameters ) void vLCDTask( void * pvParameters )
{ {
unsigned portBASE_TYPE uxIndex; unsigned portBASE_TYPE uxIndex;
const unsigned char ucCFGData[] = { const unsigned char ucCFGData[] =
{
0x30, /* Set data bus to 8-bits. */ 0x30, /* Set data bus to 8-bits. */
0x30, 0x30,
0x30, 0x30,
@ -293,7 +299,8 @@ const unsigned char ucCFGData[] = {
}; };
/* The strings that are written to the LCD. */ /* The strings that are written to the LCD. */
const char *pcStringsToDisplay[] = { const char * pcStringsToDisplay[] =
{
"Stellaris", "Stellaris",
"Demo", "Demo",
"One", "One",
@ -303,6 +310,7 @@ const char *pcStringsToDisplay[] = {
/* Configure the LCD. */ /* Configure the LCD. */
uxIndex = 0; uxIndex = 0;
while( uxIndex < sizeof( ucCFGData ) ) while( uxIndex < sizeof( ucCFGData ) )
{ {
prvPDCWrite( PDC_LCD_CSR, ucCFGData[ uxIndex ] ); prvPDCWrite( PDC_LCD_CSR, ucCFGData[ uxIndex ] );
@ -318,13 +326,15 @@ const char *pcStringsToDisplay[] = {
prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR ); prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR );
uxIndex = 0; uxIndex = 0;
for( ;; )
for( ; ; )
{ {
/* Display the string on the LCD. */ /* Display the string on the LCD. */
prvWriteString( pcStringsToDisplay[ uxIndex ] ); prvWriteString( pcStringsToDisplay[ uxIndex ] );
/* Move on to the next string - wrapping if necessary. */ /* Move on to the next string - wrapping if necessary. */
uxIndex++; uxIndex++;
if( *( pcStringsToDisplay[ uxIndex ] ) == 0x00 ) if( *( pcStringsToDisplay[ uxIndex ] ) == 0x00 )
{ {
uxIndex = 0; uxIndex = 0;
@ -340,12 +350,12 @@ const char *pcStringsToDisplay[] = {
static void vCommsRxTask( void * pvParameters ) static void vCommsRxTask( void * pvParameters )
{ {
static char cRxedChar, cExpectedChar; static char cRxedChar, cExpectedChar;
/* Set the char we expect to receive to the start of the string. */ /* Set the char we expect to receive to the start of the string. */
cExpectedChar = mainFIRST_TX_CHAR; cExpectedChar = mainFIRST_TX_CHAR;
for( ;; ) for( ; ; )
{ {
/* Wait for a character to be received. */ /* Wait for a character to be received. */
xQueueReceive( xCommsQueue, ( void * ) &cRxedChar, mainCOMMS_RX_DELAY ); xQueueReceive( xCommsQueue, ( void * ) &cRxedChar, mainCOMMS_RX_DELAY );
@ -354,14 +364,16 @@ static char cRxedChar, cExpectedChar;
if( cRxedChar != cExpectedChar ) if( cRxedChar != cExpectedChar )
{ {
/* Got an unexpected character. This can sometimes occur when /* Got an unexpected character. This can sometimes occur when
reseting the system using the debugger leaving characters already * reseting the system using the debugger leaving characters already
in the UART registers. */ * in the UART registers. */
uxErrorStatus = pdFAIL; uxErrorStatus = pdFAIL;
/* Resync by waiting for the end of the current string. */ /* Resync by waiting for the end of the current string. */
while( cRxedChar != mainLAST_TX_CHAR ) while( cRxedChar != mainLAST_TX_CHAR )
{ {
while( !xQueueReceive( xCommsQueue, ( void * ) &cRxedChar, portMAX_DELAY ) ); while( !xQueueReceive( xCommsQueue, ( void * ) &cRxedChar, portMAX_DELAY ) )
{
}
} }
/* The next expected character is the start of the string again. */ /* The next expected character is the start of the string again. */
@ -372,16 +384,16 @@ static char cRxedChar, cExpectedChar;
if( cExpectedChar == mainLAST_TX_CHAR ) if( cExpectedChar == mainLAST_TX_CHAR )
{ {
/* We have reached the end of the string - we now expect to /* We have reached the end of the string - we now expect to
receive the first character in the string again. The LED is * receive the first character in the string again. The LED is
toggled to indicate that the entire string was received without * toggled to indicate that the entire string was received without
error. */ * error. */
vParTestToggleLED( mainCOMMS_RX_LED ); vParTestToggleLED( mainCOMMS_RX_LED );
cExpectedChar = mainFIRST_TX_CHAR; cExpectedChar = mainFIRST_TX_CHAR;
} }
else else
{ {
/* We got the expected character, we now expect to receive the /* We got the expected character, we now expect to receive the
next character in the string. */ * next character in the string. */
cExpectedChar++; cExpectedChar++;
} }
} }
@ -389,15 +401,16 @@ static char cRxedChar, cExpectedChar;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vSerialTxCoRoutine( CoRoutineHandle_t xHandle, unsigned portBASE_TYPE uxIndex ) static void vSerialTxCoRoutine( CoRoutineHandle_t xHandle,
unsigned portBASE_TYPE uxIndex )
{ {
TickType_t xDelayPeriod; TickType_t xDelayPeriod;
static unsigned long *pulRandomBytes = mainFIRST_PROGRAM_BYTES; static unsigned long * pulRandomBytes = mainFIRST_PROGRAM_BYTES;
/* Co-routine MUST start with a call to crSTART. */ /* Co-routine MUST start with a call to crSTART. */
crSTART( xHandle ); crSTART( xHandle );
for(;;) for( ; ; )
{ {
/* Was the previously transmitted string received correctly? */ /* Was the previously transmitted string received correctly? */
if( uxErrorStatus != pdPASS ) if( uxErrorStatus != pdPASS )
@ -418,19 +431,20 @@ static unsigned long *pulRandomBytes = mainFIRST_PROGRAM_BYTES;
} }
/* Move the variable to the char to Tx on so the ISR transmits /* Move the variable to the char to Tx on so the ISR transmits
the next character in the string once this one has completed. */ * the next character in the string once this one has completed. */
cNextChar++; cNextChar++;
} }
UARTIntEnable(UART0_BASE, UART_INT_TX); UARTIntEnable( UART0_BASE, UART_INT_TX );
/* Toggle the LED to show a new string is being transmitted. */ /* Toggle the LED to show a new string is being transmitted. */
vParTestToggleLED( mainCOMMS_TX_LED ); vParTestToggleLED( mainCOMMS_TX_LED );
/* Delay before we start the string off again. A pseudo-random delay /* Delay before we start the string off again. A pseudo-random delay
is used as this will provide a better test. */ * is used as this will provide a better test. */
xDelayPeriod = xTaskGetTickCount() + ( *pulRandomBytes ); xDelayPeriod = xTaskGetTickCount() + ( *pulRandomBytes );
pulRandomBytes++; pulRandomBytes++;
if( pulRandomBytes > mainTOTAL_PROGRAM_MEMORY ) if( pulRandomBytes > mainTOTAL_PROGRAM_MEMORY )
{ {
pulRandomBytes = mainFIRST_PROGRAM_BYTES; pulRandomBytes = mainFIRST_PROGRAM_BYTES;
@ -457,17 +471,17 @@ static unsigned long *pulRandomBytes = mainFIRST_PROGRAM_BYTES;
static void vSerialInit( void ) static void vSerialInit( void )
{ {
/* Enable the UART. GPIOA has already been initialised. */ /* Enable the UART. GPIOA has already been initialised. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
/* Set GPIO A0 and A1 as peripheral function. They are used to output the /* Set GPIO A0 and A1 as peripheral function. They are used to output the
UART signals. */ * UART signals. */
GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW ); GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW );
/* Configure the UART for 8-N-1 operation. */ /* Configure the UART for 8-N-1 operation. */
UARTConfigSet( UART0_BASE, mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE ); UARTConfigSet( UART0_BASE, mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE );
/* We dont want to use the fifo. This is for test purposes to generate /* We dont want to use the fifo. This is for test purposes to generate
as many interrupts as possible. */ * as many interrupts as possible. */
HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET; HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET;
/* Enable both Rx and Tx interrupts. */ /* Enable both Rx and Tx interrupts. */
@ -476,11 +490,11 @@ static void vSerialInit( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vUART_ISR(void) void vUART_ISR( void )
{ {
unsigned long ulStatus; unsigned long ulStatus;
char cRxedChar; char cRxedChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* What caused the interrupt. */ /* What caused the interrupt. */
ulStatus = UARTIntStatus( UART0_BASE, pdTRUE ); ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
@ -491,11 +505,11 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Was an Rx interrupt pending? */ /* Was an Rx interrupt pending? */
if( ulStatus & UART_INT_RX ) if( ulStatus & UART_INT_RX )
{ {
if( ( HWREG(UART0_BASE + UART_O_FR ) & UART_FR_RXFF ) ) if( ( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_RXFF ) )
{ {
/* Get the char from the buffer and post it onto the queue of /* Get the char from the buffer and post it onto the queue of
Rxed chars. Posting the character should wake the task that is * Rxed chars. Posting the character should wake the task that is
blocked on the queue waiting for characters. */ * blocked on the queue waiting for characters. */
cRxedChar = ( char ) HWREG( UART0_BASE + UART_O_DR ); cRxedChar = ( char ) HWREG( UART0_BASE + UART_O_DR );
xQueueSendFromISR( xCommsQueue, &cRxedChar, &xHigherPriorityTaskWoken ); xQueueSendFromISR( xCommsQueue, &cRxedChar, &xHigherPriorityTaskWoken );
} }
@ -511,19 +525,21 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
{ {
HWREG( UART0_BASE + UART_O_DR ) = cNextChar; HWREG( UART0_BASE + UART_O_DR ) = cNextChar;
} }
cNextChar++; cNextChar++;
} }
} }
/* If a task was woken by the character being received then we force /* If a task was woken by the character being received then we force
a context switch to occur in case the task is of higher priority than * a context switch to occur in case the task is of higher priority than
the currently executing task (i.e. the task that this interrupt * the currently executing task (i.e. the task that this interrupt
interrupted.) */ * interrupted.) */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvPDCWrite( char cAddress, char cData ) static void prvPDCWrite( char cAddress,
char cData )
{ {
vTaskSuspendAll(); vTaskSuspendAll();
{ {
@ -542,7 +558,7 @@ void vSetErrorLED( void )
void prvSetAndCheckRegisters( void ) void prvSetAndCheckRegisters( void )
{ {
/* Fill the general purpose registers with known values. */ /* Fill the general purpose registers with known values. */
__asm volatile( " mov r11, #10\n" __asm volatile ( " mov r11, #10\n"
" add r0, r11, #1\n" " add r0, r11, #1\n"
" add r1, r11, #2\n" " add r1, r11, #2\n"
" add r2, r11, #3\n" " add r2, r11, #3\n"
@ -557,7 +573,7 @@ void prvSetAndCheckRegisters( void )
" add r12, r11, #12" ); " add r12, r11, #12" );
/* Check the values are as expected. */ /* Check the values are as expected. */
__asm volatile( " cmp r11, #10\n" __asm volatile ( " cmp r11, #10\n"
" bne set_error_led\n" " bne set_error_led\n"
" cmp r0, #11\n" " cmp r0, #11\n"
" bne set_error_led\n" " bne set_error_led\n"
@ -585,7 +601,7 @@ void prvSetAndCheckRegisters( void )
" bne set_error_led\n" " bne set_error_led\n"
" bx lr" ); " bx lr" );
__asm volatile( "set_error_led:\n" __asm volatile ( "set_error_led:\n"
" push {r14}\n" " push {r14}\n"
" ldr r1, =vSetErrorLED\n" " ldr r1, =vSetErrorLED\n"
" blx r1\n" " blx r1\n"

View file

@ -109,7 +109,7 @@
#define mainLCD_QUEUE_LEN ( 3 ) #define mainLCD_QUEUE_LEN ( 3 )
/* The priority of the co-routine used to initiate the transmission of the /* The priority of the co-routine used to initiate the transmission of the
string on UART 0. */ * string on UART 0. */
#define mainTX_CO_ROUTINE_PRIORITY ( 1 ) #define mainTX_CO_ROUTINE_PRIORITY ( 1 )
#define mainADC_CO_ROUTINE_PRIORITY ( 2 ) #define mainADC_CO_ROUTINE_PRIORITY ( 2 )
@ -130,7 +130,7 @@ string on UART 0. */
#define mainMAX_ADC_STRING_LEN 20 #define mainMAX_ADC_STRING_LEN 20
/* The LED that is lit should an error be detected in any of the tasks or /* The LED that is lit should an error be detected in any of the tasks or
co-routines. */ * co-routines. */
#define mainFAIL_LED ( 7 ) #define mainFAIL_LED ( 7 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -149,7 +149,8 @@ static void prvLCDMessageTask( void * pvParameters );
* The co-routine that reads the ADC and sends messages for display on the * The co-routine that reads the ADC and sends messages for display on the
* bottom row of the LCD. * bottom row of the LCD.
*/ */
static void prvADCCoRoutine( CoRoutineHandle_t xHandle, unsigned portBASE_TYPE uxIndex ); static void prvADCCoRoutine( CoRoutineHandle_t xHandle,
unsigned portBASE_TYPE uxIndex );
/* /*
* Function to simply set a known value into the general purpose registers * Function to simply set a known value into the general purpose registers
@ -166,7 +167,8 @@ void vSetErrorLED( void );
/* /*
* Thread safe write to the PDC. * Thread safe write to the PDC.
*/ */
static void prvPDCWrite( char cAddress, char cData ); static void prvPDCWrite( char cAddress,
char cData );
/* /*
* Sets up the hardware used by the demo. * Sets up the hardware used by the demo.
@ -179,12 +181,12 @@ static void prvSetupHardware( void );
/* The structure that is passed on the LCD message queue. */ /* The structure that is passed on the LCD message queue. */
typedef struct typedef struct
{ {
char **ppcMessageToDisplay; /*<< Points to a char* pointing to the message to display. */ char ** ppcMessageToDisplay; /*<< Points to a char* pointing to the message to display. */
portBASE_TYPE xRow; /*<< The row on which the message should be displayed. */ portBASE_TYPE xRow; /*<< The row on which the message should be displayed. */
} xLCDMessage; } xLCDMessage;
/* Error flag set to pdFAIL if an error is encountered in the tasks/co-routines /* Error flag set to pdFAIL if an error is encountered in the tasks/co-routines
defined within this file. */ * defined within this file. */
unsigned portBASE_TYPE uxErrorStatus = pdPASS; unsigned portBASE_TYPE uxErrorStatus = pdPASS;
/* The queue used to transmit messages to the LCD task. */ /* The queue used to transmit messages to the LCD task. */
@ -207,14 +209,14 @@ void main( void )
vStartFlashCoRoutines( mainNUM_FLASH_CO_ROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_CO_ROUTINES );
/* Create the co-routine that initiates the transmission of characters /* Create the co-routine that initiates the transmission of characters
on the UART and the task that receives them, as described at the top of * on the UART and the task that receives them, as described at the top of
this file. */ * this file. */
xCoRoutineCreate( vSerialTxCoRoutine, mainTX_CO_ROUTINE_PRIORITY, mainTX_CO_ROUTINE_INDEX ); xCoRoutineCreate( vSerialTxCoRoutine, mainTX_CO_ROUTINE_PRIORITY, mainTX_CO_ROUTINE_INDEX );
xTaskCreate( vCommsRxTask, "CMS", configMINIMAL_STACK_SIZE, NULL, mainCOMMS_RX_TASK_PRIORITY, NULL ); xTaskCreate( vCommsRxTask, "CMS", configMINIMAL_STACK_SIZE, NULL, mainCOMMS_RX_TASK_PRIORITY, NULL );
/* Create the task that waits for messages to display on the LCD, plus the /* Create the task that waits for messages to display on the LCD, plus the
task and co-routine that send messages for display (as described at the top * task and co-routine that send messages for display (as described at the top
of this file. */ * of this file. */
xTaskCreate( prvLCDTask, "LCD", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainLCD_TASK_PRIORITY, NULL ); xTaskCreate( prvLCDTask, "LCD", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainLCD_TASK_PRIORITY, NULL );
xTaskCreate( prvLCDMessageTask, "MSG", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainMSG_TASK_PRIORITY, NULL ); xTaskCreate( prvLCDMessageTask, "MSG", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainMSG_TASK_PRIORITY, NULL );
xCoRoutineCreate( prvADCCoRoutine, mainADC_CO_ROUTINE_PRIORITY, mainADC_CO_ROUTINE_INDEX ); xCoRoutineCreate( prvADCCoRoutine, mainADC_CO_ROUTINE_PRIORITY, mainADC_CO_ROUTINE_INDEX );
@ -223,15 +225,18 @@ void main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Should not get here unless we did not have enough memory to start the /* Should not get here unless we did not have enough memory to start the
scheduler. */ * scheduler. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvLCDMessageTask( void * pvParameters ) static void prvLCDMessageTask( void * pvParameters )
{ {
/* The strings that are written to the LCD. */ /* The strings that are written to the LCD. */
char *pcStringsToDisplay[] = { char * pcStringsToDisplay[] =
{
"IAR ", "IAR ",
"Stellaris ", "Stellaris ",
"Demo ", "Demo ",
@ -239,16 +244,16 @@ char *pcStringsToDisplay[] = {
"" ""
}; };
QueueHandle_t *pxLCDQueue; QueueHandle_t * pxLCDQueue;
xLCDMessage xMessageToSend; xLCDMessage xMessageToSend;
portBASE_TYPE xIndex = 0; portBASE_TYPE xIndex = 0;
/* To test the parameter passing mechanism, the queue on which messages are /* To test the parameter passing mechanism, the queue on which messages are
posted is passed in as a parameter even though it is available as a file * posted is passed in as a parameter even though it is available as a file
scope variable anyway. */ * scope variable anyway. */
pxLCDQueue = ( QueueHandle_t * ) pvParameters; pxLCDQueue = ( QueueHandle_t * ) pvParameters;
for( ;; ) for( ; ; )
{ {
/* Wait until it is time to move onto the next string. */ /* Wait until it is time to move onto the next string. */
vTaskDelay( mainSTRING_WRITE_DELAY ); vTaskDelay( mainSTRING_WRITE_DELAY );
@ -265,6 +270,7 @@ portBASE_TYPE xIndex = 0;
/* Move onto the next message, wrapping when necessary. */ /* Move onto the next message, wrapping when necessary. */
xIndex++; xIndex++;
if( *( pcStringsToDisplay[ xIndex ] ) == 0x00 ) if( *( pcStringsToDisplay[ xIndex ] ) == 0x00 )
{ {
xIndex = 0; xIndex = 0;
@ -278,11 +284,12 @@ portBASE_TYPE xIndex = 0;
void prvLCDTask( void * pvParameters ) void prvLCDTask( void * pvParameters )
{ {
unsigned portBASE_TYPE uxIndex; unsigned portBASE_TYPE uxIndex;
QueueHandle_t *pxLCDQueue; QueueHandle_t * pxLCDQueue;
xLCDMessage xReceivedMessage; xLCDMessage xReceivedMessage;
char *pcString; char * pcString;
const unsigned char ucCFGData[] = { const unsigned char ucCFGData[] =
{
0x30, /* Set data bus to 8-bits. */ 0x30, /* Set data bus to 8-bits. */
0x30, 0x30,
0x30, 0x30,
@ -294,12 +301,13 @@ const unsigned char ucCFGData[] = {
}; };
/* To test the parameter passing mechanism, the queue on which messages are /* To test the parameter passing mechanism, the queue on which messages are
received is passed in as a parameter even though it is available as a file * received is passed in as a parameter even though it is available as a file
scope variable anyway. */ * scope variable anyway. */
pxLCDQueue = ( QueueHandle_t * ) pvParameters; pxLCDQueue = ( QueueHandle_t * ) pvParameters;
/* Configure the LCD. */ /* Configure the LCD. */
uxIndex = 0; uxIndex = 0;
while( uxIndex < sizeof( ucCFGData ) ) while( uxIndex < sizeof( ucCFGData ) )
{ {
prvPDCWrite( PDC_LCD_CSR, ucCFGData[ uxIndex ] ); prvPDCWrite( PDC_LCD_CSR, ucCFGData[ uxIndex ] );
@ -315,7 +323,8 @@ const unsigned char ucCFGData[] = {
prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR ); prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR );
uxIndex = 0; uxIndex = 0;
for( ;; )
for( ; ; )
{ {
/* Wait for a message to arrive. */ /* Wait for a message to arrive. */
if( xQueueReceive( *pxLCDQueue, &xReceivedMessage, portMAX_DELAY ) ) if( xQueueReceive( *pxLCDQueue, &xReceivedMessage, portMAX_DELAY ) )
@ -329,7 +338,7 @@ const unsigned char ucCFGData[] = {
while( *pcString ) while( *pcString )
{ {
/* Don't write out the string too quickly as LCD's are usually /* Don't write out the string too quickly as LCD's are usually
pretty slow devices. */ * pretty slow devices. */
vTaskDelay( mainCHAR_WRITE_DELAY ); vTaskDelay( mainCHAR_WRITE_DELAY );
prvPDCWrite( PDC_LCD_RAM, *pcString ); prvPDCWrite( PDC_LCD_RAM, *pcString );
pcString++; pcString++;
@ -339,17 +348,18 @@ const unsigned char ucCFGData[] = {
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvADCCoRoutine( CoRoutineHandle_t xHandle, unsigned portBASE_TYPE uxIndex ) static void prvADCCoRoutine( CoRoutineHandle_t xHandle,
unsigned portBASE_TYPE uxIndex )
{ {
static unsigned long ulADCValue; static unsigned long ulADCValue;
static char cMessageBuffer[ mainMAX_ADC_STRING_LEN ]; static char cMessageBuffer[ mainMAX_ADC_STRING_LEN ];
static char *pcMessage; static char * pcMessage;
static xLCDMessage xMessageToSend; static xLCDMessage xMessageToSend;
/* Co-routines MUST start with a call to crSTART(). */ /* Co-routines MUST start with a call to crSTART(). */
crSTART( xHandle ); crSTART( xHandle );
for( ;; ) for( ; ; )
{ {
/* Start an ADC conversion. */ /* Start an ADC conversion. */
ADCProcessorTrigger( ADC_BASE, 0 ); ADCProcessorTrigger( ADC_BASE, 0 );
@ -365,11 +375,11 @@ static xLCDMessage xMessageToSend;
pcMessage = cMessageBuffer; pcMessage = cMessageBuffer;
/* Configure the message we are going to send for display. */ /* Configure the message we are going to send for display. */
xMessageToSend.ppcMessageToDisplay = ( char** ) &pcMessage; xMessageToSend.ppcMessageToDisplay = ( char ** ) &pcMessage;
xMessageToSend.xRow = mainBOTTOM_ROW; xMessageToSend.xRow = mainBOTTOM_ROW;
/* Send the string to the LCD task for display. We are sending /* Send the string to the LCD task for display. We are sending
on a task queue so do not have the option to block. */ * on a task queue so do not have the option to block. */
if( !xQueueSend( xLCDQueue, ( void * ) &xMessageToSend, 0 ) ) if( !xQueueSend( xLCDQueue, ( void * ) &xMessageToSend, 0 ) )
{ {
uxErrorStatus = pdFAIL; uxErrorStatus = pdFAIL;
@ -393,14 +403,14 @@ static void prvSetupHardware( void )
/* The ADC is used to read the light sensor. */ /* The ADC is used to read the light sensor. */
SysCtlPeripheralEnable( SYSCTL_PERIPH_ADC ); SysCtlPeripheralEnable( SYSCTL_PERIPH_ADC );
ADCSequenceConfigure( ADC_BASE, 3, ADC_TRIGGER_PROCESSOR, 0); ADCSequenceConfigure( ADC_BASE, 3, ADC_TRIGGER_PROCESSOR, 0 );
ADCSequenceStepConfigure( ADC_BASE, 0, 0, ADC_CTL_CH0 | ADC_CTL_END ); ADCSequenceStepConfigure( ADC_BASE, 0, 0, ADC_CTL_CH0 | ADC_CTL_END );
ADCSequenceEnable( ADC_BASE, 0 ); ADCSequenceEnable( ADC_BASE, 0 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvPDCWrite( char cAddress, char cData ) static void prvPDCWrite( char cAddress,
char cData )
{ {
vTaskSuspendAll(); vTaskSuspendAll();
{ {
@ -419,8 +429,8 @@ void vSetErrorLED( void )
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* The co-routines are executed in the idle task using the idle task /* The co-routines are executed in the idle task using the idle task
hook. */ * hook. */
for( ;; ) for( ; ; )
{ {
/* Schedule the co-routines. */ /* Schedule the co-routines. */
vCoRoutineSchedule(); vCoRoutineSchedule();

View file

@ -60,10 +60,10 @@
*/ */
/************************************************************************* /*************************************************************************
* Please ensure to read http://www.freertos.org/portlm3sx965.html * Please ensure to read http://www.freertos.org/portlm3sx965.html
* which provides information on configuring and running this demo for the * which provides information on configuring and running this demo for the
* various Luminary Micro EKs. * various Luminary Micro EKs.
*************************************************************************/ *************************************************************************/
/* Standard includes. */ /* Standard includes. */
#include <stdio.h> #include <stdio.h>
@ -101,7 +101,7 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The time between cycles of the 'check' functionality (defined within the /* The time between cycles of the 'check' functionality (defined within the
tick hook. */ * tick hook. */
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* Task stack sizes. */ /* Task stack sizes. */
@ -115,14 +115,14 @@ tick hook. */
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* The maximum number of message that can be waiting for display at any one /* The maximum number of message that can be waiting for display at any one
time. */ * time. */
#define mainOLED_QUEUE_SIZE ( 3 ) #define mainOLED_QUEUE_SIZE ( 3 )
/* Dimensions the buffer into which the jitter time is written. */ /* Dimensions the buffer into which the jitter time is written. */
#define mainMAX_MSG_LEN 25 #define mainMAX_MSG_LEN 25
/* The period of the system clock in nano seconds. This is used to calculate /* The period of the system clock in nano seconds. This is used to calculate
the jitter time in nano seconds. */ * the jitter time in nano seconds. */
#define mainNS_PER_CLOCK ( ( uint32_t ) ( ( 1.0 / ( double ) configCPU_CLOCK_HZ ) * 1000000000.0 ) ) #define mainNS_PER_CLOCK ( ( uint32_t ) ( ( 1.0 / ( double ) configCPU_CLOCK_HZ ) * 1000000000.0 ) )
/* Constants used when writing strings to the display. */ /* Constants used when writing strings to the display. */
@ -141,7 +141,7 @@ the jitter time in nano seconds. */
* access the display directly. Other tasks wanting to display a message send * access the display directly. Other tasks wanting to display a message send
* the message to the gatekeeper. * the message to the gatekeeper.
*/ */
static void prvOLEDTask( void *pvParameters ); static void prvOLEDTask( void * pvParameters );
/* /*
* Configure the hardware for the demo. * Configure the hardware for the demo.
@ -157,7 +157,8 @@ extern void vSetupHighFrequencyTimer( void );
/* /*
* Hook functions that can get called by the kernel. * Hook functions that can get called by the kernel.
*/ */
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/* /*
@ -176,21 +177,21 @@ const char * const pcWelcomeMessage = " www.FreeRTOS.org";
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/************************************************************************* /*************************************************************************
* Please ensure to read http://www.freertos.org/portlm3sx965.html * Please ensure to read http://www.freertos.org/portlm3sx965.html
* which provides information on configuring and running this demo for the * which provides information on configuring and running this demo for the
* various Luminary Micro EKs. * various Luminary Micro EKs.
*************************************************************************/ *************************************************************************/
int main( void ) int main( void )
{ {
/* Initialise the trace recorder. Use of the trace recorder is optional. /* Initialise the trace recorder. Use of the trace recorder is optional.
See http://www.FreeRTOS.org/trace for more information and the comments at * See http://www.FreeRTOS.org/trace for more information and the comments at
the top of this file regarding enabling trace in this demo. * the top of this file regarding enabling trace in this demo.
vTraceEnable( TRC_START ); */ * vTraceEnable( TRC_START ); */
prvSetupHardware(); prvSetupHardware();
/* Create the queue used by the OLED task. Messages for display on the OLED /* Create the queue used by the OLED task. Messages for display on the OLED
are received via this queue. */ * are received via this queue. */
xOLEDQueue = xQueueCreate( mainOLED_QUEUE_SIZE, sizeof( char * ) ); xOLEDQueue = xQueueCreate( mainOLED_QUEUE_SIZE, sizeof( char * ) );
/* Start the standard demo tasks. */ /* Start the standard demo tasks. */
@ -207,27 +208,29 @@ int main( void )
xTaskCreate( prvOLEDTask, "OLED", mainOLED_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( prvOLEDTask, "OLED", mainOLED_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
/* The suicide tasks must be created last as they need to know how many /* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation in order to ascertain whether * tasks were running prior to their creation in order to ascertain whether
or not the correct/expected number of tasks are running at any given time. */ * or not the correct/expected number of tasks are running at any given time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Uncomment the following line to configure the high frequency interrupt /* Uncomment the following line to configure the high frequency interrupt
used to measure the interrupt jitter time. * used to measure the interrupt jitter time.
vSetupHighFrequencyTimer(); */ * vSetupHighFrequencyTimer(); */
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle /* Will only get here if there was insufficient memory to create the idle
task. */ * task. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void prvSetupHardware( void ) void prvSetupHardware( void )
{ {
/* If running on Rev A2 silicon, turn the LDO voltage up to 2.75V. This is /* If running on Rev A2 silicon, turn the LDO voltage up to 2.75V. This is
a workaround to allow the PLL to operate reliably. */ * a workaround to allow the PLL to operate reliably. */
if( DEVICE_IS_REVA2 ) if( DEVICE_IS_REVA2 )
{ {
SysCtlLDOSet( SYSCTL_LDO_2_75V ); SysCtlLDOSet( SYSCTL_LDO_2_75V );
@ -237,7 +240,7 @@ void prvSetupHardware( void )
SysCtlClockSet( SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ ); SysCtlClockSet( SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ );
/* Initialise the UART - QEMU usage does not seem to require this /* Initialise the UART - QEMU usage does not seem to require this
initialisation. */ * initialisation. */
SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 ); SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
UARTEnable( UART0_BASE ); UARTEnable( UART0_BASE );
} }
@ -245,13 +248,14 @@ void prvSetupHardware( void )
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
static const char * pcMessage = "PASS"; static const char * pcMessage = "PASS";
static uint32_t ulTicksSinceLastDisplay = 0; static uint32_t ulTicksSinceLastDisplay = 0;
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* Called from every tick interrupt. Have enough ticks passed to make it /* Called from every tick interrupt. Have enough ticks passed to make it
time to perform our health status check again? */ * time to perform our health status check again? */
ulTicksSinceLastDisplay++; ulTicksSinceLastDisplay++;
if( ulTicksSinceLastDisplay >= mainCHECK_DELAY ) if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
{ {
ulTicksSinceLastDisplay = 0; ulTicksSinceLastDisplay = 0;
@ -300,7 +304,7 @@ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
} }
/* Write to a queue that is in use as part of the queue set demo to /* Write to a queue that is in use as part of the queue set demo to
demonstrate using queue sets from an ISR. */ * demonstrate using queue sets from an ISR. */
vQueueSetAccessQueueSetFromISR(); vQueueSetAccessQueueSetFromISR();
/* Call the event group ISR tests. */ /* Call the event group ISR tests. */
@ -321,25 +325,32 @@ static void prvPrintString( const char * pcString )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void prvOLEDTask( void *pvParameters ) void prvOLEDTask( void * pvParameters )
{ {
const char *pcMessage; const char * pcMessage;
uint32_t ulY, ulMaxY; uint32_t ulY, ulMaxY;
static char cMessage[ mainMAX_MSG_LEN ]; static char cMessage[ mainMAX_MSG_LEN ];
const unsigned char *pucImage; const unsigned char * pucImage;
/* Functions to access the OLED. The one used depends on the dev kit /* Functions to access the OLED. The one used depends on the dev kit
being used. */ * being used. */
void ( *vOLEDInit )( uint32_t ) = NULL; void ( * vOLEDInit )( uint32_t ) = NULL;
void ( *vOLEDStringDraw )( const char *, uint32_t, uint32_t, unsigned char ) = NULL; void ( * vOLEDStringDraw )( const char *,
void ( *vOLEDImageDraw )( const unsigned char *, uint32_t, uint32_t, uint32_t, uint32_t ) = NULL; uint32_t,
void ( *vOLEDClear )( void ) = NULL; uint32_t,
unsigned char ) = NULL;
void ( * vOLEDImageDraw )( const unsigned char *,
uint32_t,
uint32_t,
uint32_t,
uint32_t ) = NULL;
void ( * vOLEDClear )( void ) = NULL;
/* Prevent warnings about unused parameters. */ /* Prevent warnings about unused parameters. */
( void ) pvParameters; ( void ) pvParameters;
/* Map the OLED access functions to the driver functions that are appropriate /* Map the OLED access functions to the driver functions that are appropriate
for the evaluation kit being used. */ * for the evaluation kit being used. */
configASSERT( ( HWREG( SYSCTL_DID1 ) & SYSCTL_DID1_PRTNO_MASK ) == SYSCTL_DID1_PRTNO_6965 ); configASSERT( ( HWREG( SYSCTL_DID1 ) & SYSCTL_DID1_PRTNO_MASK ) == SYSCTL_DID1_PRTNO_6965 );
vOLEDInit = OSRAM128x64x4Init; vOLEDInit = OSRAM128x64x4Init;
vOLEDStringDraw = OSRAM128x64x4StringDraw; vOLEDStringDraw = OSRAM128x64x4StringDraw;
@ -354,13 +365,14 @@ void ( *vOLEDClear )( void ) = NULL;
vOLEDStringDraw( "POWERED BY FreeRTOS", 0, 0, mainFULL_SCALE ); vOLEDStringDraw( "POWERED BY FreeRTOS", 0, 0, mainFULL_SCALE );
vOLEDImageDraw( pucImage, 0, mainCHARACTER_HEIGHT + 1, bmpBITMAP_WIDTH, bmpBITMAP_HEIGHT ); vOLEDImageDraw( pucImage, 0, mainCHARACTER_HEIGHT + 1, bmpBITMAP_WIDTH, bmpBITMAP_HEIGHT );
for( ;; ) for( ; ; )
{ {
/* Wait for a message to arrive that requires displaying. */ /* Wait for a message to arrive that requires displaying. */
xQueueReceive( xOLEDQueue, &pcMessage, portMAX_DELAY ); xQueueReceive( xOLEDQueue, &pcMessage, portMAX_DELAY );
/* Write the message on the next available row. */ /* Write the message on the next available row. */
ulY += mainCHARACTER_HEIGHT; ulY += mainCHARACTER_HEIGHT;
if( ulY >= ulMaxY ) if( ulY >= ulMaxY )
{ {
ulY = mainCHARACTER_HEIGHT; ulY = mainCHARACTER_HEIGHT;
@ -369,7 +381,7 @@ void ( *vOLEDClear )( void ) = NULL;
} }
/* Display the message along with the maximum jitter time from the /* Display the message along with the maximum jitter time from the
high priority time test. */ * high priority time test. */
sprintf( cMessage, "%s %u", pcMessage, ( unsigned int ) xTaskGetTickCount() ); sprintf( cMessage, "%s %u", pcMessage, ( unsigned int ) xTaskGetTickCount() );
vOLEDStringDraw( cMessage, 0, ulY, mainFULL_SCALE ); vOLEDStringDraw( cMessage, 0, ulY, mainFULL_SCALE );
prvPrintString( cMessage ); prvPrintString( cMessage );
@ -378,27 +390,32 @@ void ( *vOLEDClear )( void ) = NULL;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
volatile char *pcOverflowedTask = NULL; /* Prevent task name being optimised away. */ volatile char * pcOverflowedTask = NULL; /* Prevent task name being optimised away. */
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pxTask; ( void ) pxTask;
pcOverflowedTask = pcTaskName; pcOverflowedTask = pcTaskName;
vAssertCalled( __FILE__, __LINE__ ); vAssertCalled( __FILE__, __LINE__ );
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( const char *pcFile, uint32_t ulLine ) void vAssertCalled( const char * pcFile,
uint32_t ulLine )
{ {
volatile uint32_t ulSetTo1InDebuggerToExit = 0; volatile uint32_t ulSetTo1InDebuggerToExit = 0;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
while( ulSetTo1InDebuggerToExit == 0 ) while( ulSetTo1InDebuggerToExit == 0 )
{ {
/* Nothing to do here. Set the loop variable to a non zero value in /* Nothing to do here. Set the loop variable to a non zero value in
the debugger to step out of this function to the point that caused * the debugger to step out of this function to the point that caused
the assertion. */ * the assertion. */
( void ) pcFile; ( void ) pcFile;
( void ) ulLine; ( void ) ulLine;
} }
@ -407,56 +424,61 @@ volatile uint32_t ulSetTo1InDebuggerToExit = 0;
} }
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */ * used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{ {
/* If the buffers to be provided to the Idle task are declared inside this /* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB; static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */ * state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB; *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */ /* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack; *ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory() * application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */ * to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
uint32_t * pulTimerTaskStackSize )
{ {
/* If the buffers to be provided to the Timer task are declared inside this /* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB; static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer /* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */ * task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB; *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */ /* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack; *ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
char * _sbrk_r (struct _reent *r, int incr) char * _sbrk_r( struct _reent * r,
int incr )
{ {
/* Just to keep the linker quiet. */ /* Just to keep the linker quiet. */
( void ) r; ( void ) r;

View file

@ -83,7 +83,7 @@
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* UART configuration - note this does not use the FIFO so is not very /* UART configuration - note this does not use the FIFO so is not very
efficient. */ * efficient. */
#define mainBAUD_RATE ( 19200 ) #define mainBAUD_RATE ( 19200 )
#define mainFIFO_SET ( 0x10 ) #define mainFIFO_SET ( 0x10 )
@ -100,6 +100,7 @@ efficient. */
#define mainQUEUE_SIZE ( 3 ) #define mainQUEUE_SIZE ( 3 )
#define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS ) #define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS )
#define mainNO_DELAY ( ( TickType_t ) 0 ) #define mainNO_DELAY ( ( TickType_t ) 0 )
/* /*
* Configure the processor and peripherals for this demo. * Configure the processor and peripherals for this demo.
*/ */
@ -108,25 +109,25 @@ static void prvSetupHardware( void );
/* /*
* The 'check' task, as described at the top of this file. * The 'check' task, as described at the top of this file.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* The task that is woken by the ISR that processes GPIO interrupts originating * The task that is woken by the ISR that processes GPIO interrupts originating
* from the push button. * from the push button.
*/ */
static void vButtonHandlerTask( void *pvParameters ); static void vButtonHandlerTask( void * pvParameters );
/* /*
* The task that controls access to the LCD. * The task that controls access to the LCD.
*/ */
static void vPrintTask( void *pvParameter ); static void vPrintTask( void * pvParameter );
/* String that is transmitted on the UART. */ /* String that is transmitted on the UART. */
static char *cMessage = "Task woken by button interrupt! --- "; static char * cMessage = "Task woken by button interrupt! --- ";
static volatile char *pcNextChar; static volatile char * pcNextChar;
/* The semaphore used to wake the button handler task from within the GPIO /* The semaphore used to wake the button handler task from within the GPIO
interrupt handler. */ * interrupt handler. */
SemaphoreHandle_t xButtonSemaphore; SemaphoreHandle_t xButtonSemaphore;
/* The queue used to send strings to the print task for display on the LCD. */ /* The queue used to send strings to the print task for display on the LCD. */
@ -140,7 +141,7 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* Create the semaphore used to wake the button handler task from the GPIO /* Create the semaphore used to wake the button handler task from the GPIO
ISR. */ * ISR. */
vSemaphoreCreateBinary( xButtonSemaphore ); vSemaphoreCreateBinary( xButtonSemaphore );
xSemaphoreTake( xButtonSemaphore, 0 ); xSemaphoreTake( xButtonSemaphore, 0 );
@ -162,24 +163,24 @@ int main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient heap to start the /* Will only get here if there was insufficient heap to start the
scheduler. */ * scheduler. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
portBASE_TYPE xErrorOccurred = pdFALSE; portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
const char *pcPassMessage = "PASS"; const char * pcPassMessage = "PASS";
const char *pcFailMessage = "FAIL"; const char * pcFailMessage = "FAIL";
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Perform this check every mainCHECK_DELAY milliseconds. */ /* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
@ -207,8 +208,8 @@ const char *pcFailMessage = "FAIL";
} }
/* Send either a pass or fail message. If an error is found it is /* Send either a pass or fail message. If an error is found it is
never cleared again. We do not write directly to the LCD, but instead * never cleared again. We do not write directly to the LCD, but instead
queue a message for display by the print task. */ * queue a message for display by the print task. */
if( xErrorOccurred == pdTRUE ) if( xErrorOccurred == pdTRUE )
{ {
xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY ); xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY );
@ -227,9 +228,9 @@ static void prvSetupHardware( void )
SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ ); SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ );
/* Setup the push button. */ /* Setup the push button. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOC );
GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN); GPIODirModeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN );
GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE ); GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_FALLING_EDGE );
IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY ); IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY );
GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON ); GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON );
IntEnable( INT_GPIOC ); IntEnable( INT_GPIOC );
@ -237,18 +238,18 @@ static void prvSetupHardware( void )
/* Enable the UART. */ /* Enable the UART. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOA );
/* Set GPIO A0 and A1 as peripheral function. They are used to output the /* Set GPIO A0 and A1 as peripheral function. They are used to output the
UART signals. */ * UART signals. */
GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW ); GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW );
/* Configure the UART for 8-N-1 operation. */ /* Configure the UART for 8-N-1 operation. */
UARTConfigSet( UART0_BASE, mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE ); UARTConfigSet( UART0_BASE, mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE );
/* We don't want to use the fifo. This is for test purposes to generate /* We don't want to use the fifo. This is for test purposes to generate
as many interrupts as possible. */ * as many interrupts as possible. */
HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET; HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET;
/* Enable Tx interrupts. */ /* Enable Tx interrupts. */
@ -259,19 +260,21 @@ static void prvSetupHardware( void )
/* Initialise the LCD> */ /* Initialise the LCD> */
OSRAMInit( false ); OSRAMInit( false );
OSRAMStringDraw("www.FreeRTOS.org", 0, 0); OSRAMStringDraw( "www.FreeRTOS.org", 0, 0 );
OSRAMStringDraw("LM3S811 demo", 16, 1); OSRAMStringDraw( "LM3S811 demo", 16, 1 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vButtonHandlerTask( void *pvParameters ) static void vButtonHandlerTask( void * pvParameters )
{ {
const char *pcInterruptMessage = "Int"; const char * pcInterruptMessage = "Int";
for( ;; ) for( ; ; )
{ {
/* Wait for a GPIO interrupt to wake this task. */ /* Wait for a GPIO interrupt to wake this task. */
while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS ); while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS )
{
}
/* Start the Tx of the message on the UART. */ /* Start the Tx of the message on the UART. */
UARTIntDisable( UART0_BASE, UART_INT_TX ); UARTIntDisable( UART0_BASE, UART_INT_TX );
@ -286,7 +289,7 @@ const char *pcInterruptMessage = "Int";
pcNextChar++; pcNextChar++;
} }
UARTIntEnable(UART0_BASE, UART_INT_TX); UARTIntEnable( UART0_BASE, UART_INT_TX );
/* Queue a message for the print task to display on the LCD. */ /* Queue a message for the print task to display on the LCD. */
xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY ); xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY );
@ -299,9 +302,9 @@ const char *pcInterruptMessage = "Int";
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vUART_ISR(void) void vUART_ISR( void )
{ {
unsigned long ulStatus; unsigned long ulStatus;
/* What caused the interrupt. */ /* What caused the interrupt. */
ulStatus = UARTIntStatus( UART0_BASE, pdTRUE ); ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
@ -319,6 +322,7 @@ unsigned long ulStatus;
{ {
HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar; HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
} }
pcNextChar++; pcNextChar++;
} }
} }
@ -327,10 +331,10 @@ unsigned long ulStatus;
void vGPIO_ISR( void ) void vGPIO_ISR( void )
{ {
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt. */ /* Clear the interrupt. */
GPIOPinIntClear(GPIO_PORTC_BASE, mainPUSH_BUTTON); GPIOPinIntClear( GPIO_PORTC_BASE, mainPUSH_BUTTON );
/* Wake the button handler task. */ /* Wake the button handler task. */
xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );
@ -339,12 +343,12 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters ) static void vPrintTask( void * pvParameters )
{ {
char *pcMessage; char * pcMessage;
unsigned portBASE_TYPE uxLine = 0, uxRow = 0; unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
for( ;; ) for( ; ; )
{ {
/* Wait for a message to arrive. */ /* Wait for a message to arrive. */
xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY ); xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY );
@ -353,7 +357,6 @@ unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
uxRow++; uxRow++;
uxLine++; uxLine++;
OSRAMClear(); OSRAMClear();
OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01); OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01 );
} }
} }

View file

@ -83,7 +83,7 @@
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* UART configuration - note this does not use the FIFO so is not very /* UART configuration - note this does not use the FIFO so is not very
efficient. */ * efficient. */
#define mainBAUD_RATE ( 19200 ) #define mainBAUD_RATE ( 19200 )
#define mainFIFO_SET ( 0x10 ) #define mainFIFO_SET ( 0x10 )
@ -100,6 +100,7 @@ efficient. */
#define mainQUEUE_SIZE ( 3 ) #define mainQUEUE_SIZE ( 3 )
#define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS ) #define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS )
#define mainNO_DELAY ( ( TickType_t ) 0 ) #define mainNO_DELAY ( ( TickType_t ) 0 )
/* /*
* Configure the processor and peripherals for this demo. * Configure the processor and peripherals for this demo.
*/ */
@ -108,25 +109,25 @@ static void prvSetupHardware( void );
/* /*
* The 'check' task, as described at the top of this file. * The 'check' task, as described at the top of this file.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* The task that is woken by the ISR that processes GPIO interrupts originating * The task that is woken by the ISR that processes GPIO interrupts originating
* from the push button. * from the push button.
*/ */
static void vButtonHandlerTask( void *pvParameters ); static void vButtonHandlerTask( void * pvParameters );
/* /*
* The task that controls access to the LCD. * The task that controls access to the LCD.
*/ */
static void vPrintTask( void *pvParameter ); static void vPrintTask( void * pvParameter );
/* String that is transmitted on the UART. */ /* String that is transmitted on the UART. */
static char *cMessage = "Task woken by button interrupt! --- "; static char * cMessage = "Task woken by button interrupt! --- ";
static volatile char *pcNextChar; static volatile char * pcNextChar;
/* The semaphore used to wake the button handler task from within the GPIO /* The semaphore used to wake the button handler task from within the GPIO
interrupt handler. */ * interrupt handler. */
SemaphoreHandle_t xButtonSemaphore; SemaphoreHandle_t xButtonSemaphore;
/* The queue used to send strings to the print task for display on the LCD. */ /* The queue used to send strings to the print task for display on the LCD. */
@ -140,7 +141,7 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* Create the semaphore used to wake the button handler task from the GPIO /* Create the semaphore used to wake the button handler task from the GPIO
ISR. */ * ISR. */
vSemaphoreCreateBinary( xButtonSemaphore ); vSemaphoreCreateBinary( xButtonSemaphore );
xSemaphoreTake( xButtonSemaphore, 0 ); xSemaphoreTake( xButtonSemaphore, 0 );
@ -162,24 +163,24 @@ int main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient heap to start the /* Will only get here if there was insufficient heap to start the
scheduler. */ * scheduler. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
portBASE_TYPE xErrorOccurred = pdFALSE; portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
const char *pcPassMessage = "PASS"; const char * pcPassMessage = "PASS";
const char *pcFailMessage = "FAIL"; const char * pcFailMessage = "FAIL";
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Perform this check every mainCHECK_DELAY milliseconds. */ /* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
@ -207,8 +208,8 @@ const char *pcFailMessage = "FAIL";
} }
/* Send either a pass or fail message. If an error is found it is /* Send either a pass or fail message. If an error is found it is
never cleared again. We do not write directly to the LCD, but instead * never cleared again. We do not write directly to the LCD, but instead
queue a message for display by the print task. */ * queue a message for display by the print task. */
if( xErrorOccurred == pdTRUE ) if( xErrorOccurred == pdTRUE )
{ {
xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY ); xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY );
@ -227,9 +228,9 @@ static void prvSetupHardware( void )
SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ ); SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ );
/* Setup the push button. */ /* Setup the push button. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOC );
GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN); GPIODirModeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN );
GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE ); GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_FALLING_EDGE );
IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY ); IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY );
GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON ); GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON );
IntEnable( INT_GPIOC ); IntEnable( INT_GPIOC );
@ -237,18 +238,18 @@ static void prvSetupHardware( void )
/* Enable the UART. */ /* Enable the UART. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOA );
/* Set GPIO A0 and A1 as peripheral function. They are used to output the /* Set GPIO A0 and A1 as peripheral function. They are used to output the
UART signals. */ * UART signals. */
GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW ); GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW );
/* Configure the UART for 8-N-1 operation. */ /* Configure the UART for 8-N-1 operation. */
UARTConfigSetExpClk( UART0_BASE, SysCtlClockGet(), mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE ); UARTConfigSetExpClk( UART0_BASE, SysCtlClockGet(), mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE );
/* We don't want to use the fifo. This is for test purposes to generate /* We don't want to use the fifo. This is for test purposes to generate
as many interrupts as possible. */ * as many interrupts as possible. */
HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET; HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET;
/* Enable Tx interrupts. */ /* Enable Tx interrupts. */
@ -259,19 +260,21 @@ static void prvSetupHardware( void )
/* Initialise the LCD> */ /* Initialise the LCD> */
OSRAMInit( false ); OSRAMInit( false );
OSRAMStringDraw("www.FreeRTOS.org", 0, 0); OSRAMStringDraw( "www.FreeRTOS.org", 0, 0 );
OSRAMStringDraw("LM3S811 demo", 16, 1); OSRAMStringDraw( "LM3S811 demo", 16, 1 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vButtonHandlerTask( void *pvParameters ) static void vButtonHandlerTask( void * pvParameters )
{ {
const char *pcInterruptMessage = "Int"; const char * pcInterruptMessage = "Int";
for( ;; ) for( ; ; )
{ {
/* Wait for a GPIO interrupt to wake this task. */ /* Wait for a GPIO interrupt to wake this task. */
while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS ); while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS )
{
}
/* Start the Tx of the message on the UART. */ /* Start the Tx of the message on the UART. */
UARTIntDisable( UART0_BASE, UART_INT_TX ); UARTIntDisable( UART0_BASE, UART_INT_TX );
@ -286,7 +289,7 @@ const char *pcInterruptMessage = "Int";
pcNextChar++; pcNextChar++;
} }
UARTIntEnable(UART0_BASE, UART_INT_TX); UARTIntEnable( UART0_BASE, UART_INT_TX );
/* Queue a message for the print task to display on the LCD. */ /* Queue a message for the print task to display on the LCD. */
xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY ); xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY );
@ -299,9 +302,9 @@ const char *pcInterruptMessage = "Int";
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vUART_ISR(void) void vUART_ISR( void )
{ {
unsigned long ulStatus; unsigned long ulStatus;
/* What caused the interrupt. */ /* What caused the interrupt. */
ulStatus = UARTIntStatus( UART0_BASE, pdTRUE ); ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
@ -319,6 +322,7 @@ unsigned long ulStatus;
{ {
HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar; HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
} }
pcNextChar++; pcNextChar++;
} }
} }
@ -327,10 +331,10 @@ unsigned long ulStatus;
void vGPIO_ISR( void ) void vGPIO_ISR( void )
{ {
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt. */ /* Clear the interrupt. */
GPIOPinIntClear(GPIO_PORTC_BASE, mainPUSH_BUTTON); GPIOPinIntClear( GPIO_PORTC_BASE, mainPUSH_BUTTON );
/* Wake the button handler task. */ /* Wake the button handler task. */
xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );
@ -338,12 +342,12 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters ) static void vPrintTask( void * pvParameters )
{ {
char *pcMessage; char * pcMessage;
unsigned portBASE_TYPE uxLine = 0, uxRow = 0; unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
for( ;; ) for( ; ; )
{ {
/* Wait for a message to arrive. */ /* Wait for a message to arrive. */
xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY ); xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY );
@ -352,7 +356,6 @@ unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
uxRow++; uxRow++;
uxLine++; uxLine++;
OSRAMClear(); OSRAMClear();
OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01); OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01 );
} }
} }

View file

@ -83,7 +83,7 @@
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* UART configuration - note this does not use the FIFO so is not very /* UART configuration - note this does not use the FIFO so is not very
efficient. */ * efficient. */
#define mainBAUD_RATE ( 19200 ) #define mainBAUD_RATE ( 19200 )
#define mainFIFO_SET ( 0x10 ) #define mainFIFO_SET ( 0x10 )
@ -100,6 +100,7 @@ efficient. */
#define mainQUEUE_SIZE ( 3 ) #define mainQUEUE_SIZE ( 3 )
#define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS ) #define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS )
#define mainNO_DELAY ( ( TickType_t ) 0 ) #define mainNO_DELAY ( ( TickType_t ) 0 )
/* /*
* Configure the processor and peripherals for this demo. * Configure the processor and peripherals for this demo.
*/ */
@ -108,32 +109,35 @@ static void prvSetupHardware( void );
/* /*
* The 'check' task, as described at the top of this file. * The 'check' task, as described at the top of this file.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* The task that is woken by the ISR that processes GPIO interrupts originating * The task that is woken by the ISR that processes GPIO interrupts originating
* from the push button. * from the push button.
*/ */
static void vButtonHandlerTask( void *pvParameters ); static void vButtonHandlerTask( void * pvParameters );
/* /*
* The task that controls access to the LCD. * The task that controls access to the LCD.
*/ */
static void vPrintTask( void *pvParameter ); static void vPrintTask( void * pvParameter );
/* String that is transmitted on the UART. */ /* String that is transmitted on the UART. */
static char *cMessage = "Task woken by button interrupt! --- "; static char * cMessage = "Task woken by button interrupt! --- ";
static volatile char *pcNextChar; static volatile char * pcNextChar;
/* The semaphore used to wake the button handler task from within the GPIO /* The semaphore used to wake the button handler task from within the GPIO
interrupt handler. */ * interrupt handler. */
SemaphoreHandle_t xButtonSemaphore; SemaphoreHandle_t xButtonSemaphore;
/* The queue used to send strings to the print task for display on the LCD. */ /* The queue used to send strings to the print task for display on the LCD. */
QueueHandle_t xPrintQueue; QueueHandle_t xPrintQueue;
/* Newer library version. */ /* Newer library version. */
extern void UARTConfigSetExpClk(unsigned long ulBase, unsigned long ulUARTClk, unsigned long ulBaud, unsigned long ulConfig); extern void UARTConfigSetExpClk( unsigned long ulBase,
unsigned long ulUARTClk,
unsigned long ulBaud,
unsigned long ulConfig );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
@ -142,7 +146,7 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* Create the semaphore used to wake the button handler task from the GPIO /* Create the semaphore used to wake the button handler task from the GPIO
ISR. */ * ISR. */
vSemaphoreCreateBinary( xButtonSemaphore ); vSemaphoreCreateBinary( xButtonSemaphore );
xSemaphoreTake( xButtonSemaphore, 0 ); xSemaphoreTake( xButtonSemaphore, 0 );
@ -164,24 +168,24 @@ int main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient heap to start the /* Will only get here if there was insufficient heap to start the
scheduler. */ * scheduler. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
portBASE_TYPE xErrorOccurred = pdFALSE; portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
const char *pcPassMessage = "PASS"; const char * pcPassMessage = "PASS";
const char *pcFailMessage = "FAIL"; const char * pcFailMessage = "FAIL";
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Perform this check every mainCHECK_DELAY milliseconds. */ /* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
@ -209,8 +213,8 @@ const char *pcFailMessage = "FAIL";
} }
/* Send either a pass or fail message. If an error is found it is /* Send either a pass or fail message. If an error is found it is
never cleared again. We do not write directly to the LCD, but instead * never cleared again. We do not write directly to the LCD, but instead
queue a message for display by the print task. */ * queue a message for display by the print task. */
if( xErrorOccurred == pdTRUE ) if( xErrorOccurred == pdTRUE )
{ {
xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY ); xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY );
@ -229,9 +233,9 @@ static void prvSetupHardware( void )
SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ ); SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ );
/* Setup the push button. */ /* Setup the push button. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOC );
GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN); GPIODirModeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN );
GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE ); GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_FALLING_EDGE );
IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY ); IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY );
GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON ); GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON );
IntEnable( INT_GPIOC ); IntEnable( INT_GPIOC );
@ -239,18 +243,18 @@ static void prvSetupHardware( void )
/* Enable the UART. */ /* Enable the UART. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOA );
/* Set GPIO A0 and A1 as peripheral function. They are used to output the /* Set GPIO A0 and A1 as peripheral function. They are used to output the
UART signals. */ * UART signals. */
GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW ); GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW );
/* Configure the UART for 8-N-1 operation. */ /* Configure the UART for 8-N-1 operation. */
UARTConfigSetExpClk( UART0_BASE, SysCtlClockGet(), mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE ); UARTConfigSetExpClk( UART0_BASE, SysCtlClockGet(), mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE );
/* We don't want to use the fifo. This is for test purposes to generate /* We don't want to use the fifo. This is for test purposes to generate
as many interrupts as possible. */ * as many interrupts as possible. */
HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET; HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET;
/* Enable Tx interrupts. */ /* Enable Tx interrupts. */
@ -261,19 +265,21 @@ static void prvSetupHardware( void )
/* Initialise the LCD> */ /* Initialise the LCD> */
OSRAMInit( false ); OSRAMInit( false );
OSRAMStringDraw("www.FreeRTOS.org", 0, 0); OSRAMStringDraw( "www.FreeRTOS.org", 0, 0 );
OSRAMStringDraw("LM3S811 demo", 16, 1); OSRAMStringDraw( "LM3S811 demo", 16, 1 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vButtonHandlerTask( void *pvParameters ) static void vButtonHandlerTask( void * pvParameters )
{ {
const char *pcInterruptMessage = "Int"; const char * pcInterruptMessage = "Int";
for( ;; ) for( ; ; )
{ {
/* Wait for a GPIO interrupt to wake this task. */ /* Wait for a GPIO interrupt to wake this task. */
while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS ); while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS )
{
}
/* Start the Tx of the message on the UART. */ /* Start the Tx of the message on the UART. */
UARTIntDisable( UART0_BASE, UART_INT_TX ); UARTIntDisable( UART0_BASE, UART_INT_TX );
@ -288,7 +294,7 @@ const char *pcInterruptMessage = "Int";
pcNextChar++; pcNextChar++;
} }
UARTIntEnable(UART0_BASE, UART_INT_TX); UARTIntEnable( UART0_BASE, UART_INT_TX );
/* Queue a message for the print task to display on the LCD. */ /* Queue a message for the print task to display on the LCD. */
xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY ); xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY );
@ -301,9 +307,9 @@ const char *pcInterruptMessage = "Int";
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vUART_ISR(void) void vUART_ISR( void )
{ {
unsigned long ulStatus; unsigned long ulStatus;
/* What caused the interrupt. */ /* What caused the interrupt. */
ulStatus = UARTIntStatus( UART0_BASE, pdTRUE ); ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
@ -321,6 +327,7 @@ unsigned long ulStatus;
{ {
HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar; HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
} }
pcNextChar++; pcNextChar++;
} }
} }
@ -329,7 +336,7 @@ unsigned long ulStatus;
void vGPIO_ISR( void ) void vGPIO_ISR( void )
{ {
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt. */ /* Clear the interrupt. */
GPIOPinIntClear( GPIO_PORTC_BASE, mainPUSH_BUTTON ); GPIOPinIntClear( GPIO_PORTC_BASE, mainPUSH_BUTTON );
@ -340,12 +347,12 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters ) static void vPrintTask( void * pvParameters )
{ {
char *pcMessage; char * pcMessage;
unsigned portBASE_TYPE uxLine = 0, uxRow = 0; unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
for( ;; ) for( ; ; )
{ {
/* Wait for a message to arrive. */ /* Wait for a message to arrive. */
xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY ); xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY );
@ -354,7 +361,6 @@ unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
uxRow++; uxRow++;
uxLine++; uxLine++;
OSRAMClear(); OSRAMClear();
OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01); OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01 );
} }
} }

View file

@ -74,16 +74,16 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
@ -94,8 +94,8 @@ functionality. */
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -123,7 +123,7 @@ void main_blinky( void )
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
@ -138,18 +138,20 @@ void main_blinky( void )
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
@ -157,39 +159,39 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
vParTestToggleLED( mainLED_TO_TOGGLE ); vParTestToggleLED( mainLED_TO_TOGGLE );
@ -198,4 +200,3 @@ unsigned long ulReceivedValue;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -91,27 +91,27 @@
#include "QueueSet.h" #include "QueueSet.h"
/* The period after which the check timer will expire provided no errors have /* The period after which the check timer will expire provided no errors have
been reported by any of the standard demo tasks. ms are converted to the * been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire if an error has been /* The period at which the check timer will expire if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/* A block time of zero simply means "don't block". */ /* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The base toggle rate used by the flash timers. Each toggle rate is a /* The base toggle rate used by the flash timers. Each toggle rate is a
multiple of this. */ * multiple of this. */
#define mainFLASH_TIMER_BASE_RATE ( 200UL / portTICK_PERIOD_MS ) #define mainFLASH_TIMER_BASE_RATE ( 200UL / portTICK_PERIOD_MS )
/* The LED toggle by the check timer. */ /* The LED toggle by the check timer. */
#define mainCHECK_LED ( 4 ) #define mainCHECK_LED ( 4 )
/* The LED toggled each time the task implemented by the prvSemaphoreTakeTask() /* The LED toggled each time the task implemented by the prvSemaphoreTakeTask()
function takes the semaphore that is given by the tick hook function. */ * function takes the semaphore that is given by the tick hook function. */
#define mainSEMAPHORE_LED ( 3 ) #define mainSEMAPHORE_LED ( 3 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -120,8 +120,8 @@ function takes the semaphore that is given by the tick hook function. */
* Register check tasks, as described at the top of this file. The nature of * Register check tasks, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly. * these files necessitates that they are written in an assembly.
*/ */
extern void vRegTest1Task( void *pvParameters ); extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void *pvParameters ); extern void vRegTest2Task( void * pvParameters );
/* /*
* The hardware only has a single LED. Simply toggle it. * The hardware only has a single LED. Simply toggle it.
@ -143,7 +143,7 @@ static void prvFlashTimerCallback( TimerHandle_t xTimer );
* The task that toggles an LED each time the semaphore 'given' by the tick * The task that toggles an LED each time the semaphore 'given' by the tick
* hook function (which is defined in main.c) is 'taken' in the task. * hook function (which is defined in main.c) is 'taken' in the task.
*/ */
static void prvSemaphoreTakeTask( void *pvParameters ); static void prvSemaphoreTakeTask( void * pvParameters );
/* /*
* Called by main() to create the comprehensive test/demo application if * Called by main() to create the comprehensive test/demo application if
@ -154,27 +154,28 @@ void main_full( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep * register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If * incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */ * a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/* The semaphore that is given by the tick hook function (defined in main.c) /* The semaphore that is given by the tick hook function (defined in main.c)
and taken by the task implemented by the prvSemaphoreTakeTask() function. The * and taken by the task implemented by the prvSemaphoreTakeTask() function. The
task toggles LED mainSEMAPHORE_LED each time the semaphore is taken. */ * task toggles LED mainSEMAPHORE_LED each time the semaphore is taken. */
SemaphoreHandle_t xLEDSemaphore = NULL; SemaphoreHandle_t xLEDSemaphore = NULL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xTimer = NULL; TimerHandle_t xTimer = NULL;
unsigned long ulTimer; unsigned long ulTimer;
const unsigned long ulTimersToCreate = 3L; const unsigned long ulTimersToCreate = 3L;
/* The register test tasks are asm functions that don't use a stack. The /* The register test tasks are asm functions that don't use a stack. The
stack allocated just has to be large enough to hold the task context, and * stack allocated just has to be large enough to hold the task context, and
for the additional required for the stack overflow checking to work (if * for the additional required for the stack overflow checking to work (if
configured). */ * configured). */
const size_t xRegTestStackSize = 25U; const size_t xRegTestStackSize = 25U;
/* Create the standard demo tasks */ /* Create the standard demo tasks */
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
@ -185,7 +186,7 @@ const size_t xRegTestStackSize = 25U;
vStartQueueSetTasks(); vStartQueueSetTasks();
/* Create that is given from the tick hook function, and the task that /* Create that is given from the tick hook function, and the task that
toggles an LED each time the semaphore is given. */ * toggles an LED each time the semaphore is given. */
vSemaphoreCreateBinary( xLEDSemaphore ); vSemaphoreCreateBinary( xLEDSemaphore );
xTaskCreate( prvSemaphoreTakeTask, /* Function that implements the task. */ xTaskCreate( prvSemaphoreTakeTask, /* Function that implements the task. */
"Sem", /* Text name of the task. */ "Sem", /* Text name of the task. */
@ -195,8 +196,8 @@ const size_t xRegTestStackSize = 25U;
NULL ); /* Don't receive a handle back, it is not needed. */ NULL ); /* Don't receive a handle back, it is not needed. */
/* Create the register test tasks as described at the top of this file. /* Create the register test tasks as described at the top of this file.
These are naked functions that don't use any stack. A stack still has * These are naked functions that don't use any stack. A stack still has
to be allocated to hold the task context. */ * to be allocated to hold the task context. */
xTaskCreate( vRegTest1Task, /* Function that implements the task. */ xTaskCreate( vRegTest1Task, /* Function that implements the task. */
"Reg1", /* Text name of the task. */ "Reg1", /* Text name of the task. */
xRegTestStackSize, /* Stack allocated to the task. */ xRegTestStackSize, /* Stack allocated to the task. */
@ -228,7 +229,7 @@ const size_t xRegTestStackSize = 25U;
} }
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
@ -237,9 +238,9 @@ const size_t xRegTestStackSize = 25U;
); );
/* If the software timer was created successfully, start it. It won't /* If the software timer was created successfully, start it. It won't
actually start running until the scheduler starts. A block time of * actually start running until the scheduler starts. A block time of
zero is used in this call, although any value could be used as the block * zero is used in this call, although any value could be used as the block
time will be ignored because the scheduler has not started yet. */ * time will be ignored because the scheduler has not started yet. */
if( xTimer != NULL ) if( xTimer != NULL )
{ {
xTimerStart( xTimer, mainDONT_BLOCK ); xTimerStart( xTimer, mainDONT_BLOCK );
@ -249,23 +250,25 @@ const size_t xRegTestStackSize = 25U;
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then there * line will never be reached. If the following line does execute, then there
was insufficient FreeRTOS heap memory available for the idle and/or timer * was insufficient FreeRTOS heap memory available for the idle and/or timer
tasks to be created. See the memory management section on the FreeRTOS web * tasks to be created. See the memory management section on the FreeRTOS web
site, or the FreeRTOS tutorial books for more details. */ * site, or the FreeRTOS tutorial books for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* See the description at the top of this file. */ /* See the description at the top of this file. */
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangedTimerPeriodAlready = pdFALSE; static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Check all the demo and test tasks to ensure that they are all still /* Check all the demo and test tasks to ensure that they are all still
running, and that none have detected an error. */ * running, and that none have detected an error. */
if( xAreDynamicPriorityTasksStillRunning() != pdPASS ) if( xAreDynamicPriorityTasksStillRunning() != pdPASS )
{ {
ulErrorFound |= ( 0x01UL << 0UL ); ulErrorFound |= ( 0x01UL << 0UL );
@ -291,6 +294,7 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound |= ( 0x01UL << 4UL ); ulErrorFound |= ( 0x01UL << 4UL );
} }
ulLastRegTest1Value = ulRegTest1LoopCounter; ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ /* Check that the register test 2 task is still running. */
@ -298,6 +302,7 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound |= ( 0x01UL << 5UL ); ulErrorFound |= ( 0x01UL << 5UL );
} }
ulLastRegTest2Value = ulRegTest2LoopCounter; ulLastRegTest2Value = ulRegTest2LoopCounter;
if( xAreQueueSetTasksStillRunning() != pdPASS ) if( xAreQueueSetTasksStillRunning() != pdPASS )
@ -311,14 +316,14 @@ unsigned long ulErrorFound = pdFALSE;
} }
/* Toggle the check LED to give an indication of the system status. If /* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */ * everything is ok. A faster toggle indicates an error. */
vParTestToggleLED( mainCHECK_LED ); vParTestToggleLED( mainCHECK_LED );
/* Have any errors been latched in ulErrorFound? If so, shorten the /* Have any errors been latched in ulErrorFound? If so, shorten the
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. * period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
This will result in an increase in the rate at which mainCHECK_LED * This will result in an increase in the rate at which mainCHECK_LED
toggles. */ * toggles. */
if( ulErrorFound != pdFALSE ) if( ulErrorFound != pdFALSE )
{ {
if( lChangedTimerPeriodAlready == pdFALSE ) if( lChangedTimerPeriodAlready == pdFALSE )
@ -326,22 +331,22 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE; lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time. /* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must * Functions called from inside of a timer callback function must
*never* attempt to block. */ * never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSemaphoreTakeTask( void *pvParameters ) static void prvSemaphoreTakeTask( void * pvParameters )
{ {
configASSERT( xLEDSemaphore ); configASSERT( xLEDSemaphore );
for( ;; ) for( ; ; )
{ {
/* Wait to obtain the semaphore - which is given by the tick hook /* Wait to obtain the semaphore - which is given by the tick hook
function every 50ms. */ * function every 50ms. */
xSemaphoreTake( xLEDSemaphore, portMAX_DELAY ); xSemaphoreTake( xLEDSemaphore, portMAX_DELAY );
vParTestToggleLED( mainSEMAPHORE_LED ); vParTestToggleLED( mainSEMAPHORE_LED );
} }
@ -350,14 +355,13 @@ static void prvSemaphoreTakeTask( void *pvParameters )
static void prvFlashTimerCallback( TimerHandle_t xTimer ) static void prvFlashTimerCallback( TimerHandle_t xTimer )
{ {
unsigned long ulLED; unsigned long ulLED;
/* This callback function is assigned to three separate software timers. /* This callback function is assigned to three separate software timers.
Each timer toggles a different LED. Obtain the number of the LED that * Each timer toggles a different LED. Obtain the number of the LED that
this timer is toggling. */ * this timer is toggling. */
ulLED = ( unsigned long ) pvTimerGetTimerID( xTimer ); ulLED = ( unsigned long ) pvTimerGetTimerID( xTimer );
/* Toggle the LED. */ /* Toggle the LED. */
vParTestToggleLED( ulLED ); vParTestToggleLED( ulLED );
} }

View file

@ -54,7 +54,7 @@
#include "QueueSet.h" #include "QueueSet.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
@ -86,7 +86,7 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
{ {
main_blinky(); main_blinky();
@ -111,62 +111,69 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* This function will be called by each tick interrupt if /* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be * configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so * added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API * code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). The code in this * functions can be used (those that end in FromISR()). The code in this
tick hook implementation is for demonstration only - it has no real * tick hook implementation is for demonstration only - it has no real
purpose. It just gives a semaphore every 50ms. The semaphore unblocks a * purpose. It just gives a semaphore every 50ms. The semaphore unblocks a
task that then toggles an LED. Additionally, the call to * task that then toggles an LED. Additionally, the call to
vQueueSetAccessQueueSetFromISR() is part of the "standard demo tasks" * vQueueSetAccessQueueSetFromISR() is part of the "standard demo tasks"
functionality. */ * functionality. */
/* The semaphore and associated task are not created when the simple blinky /* The semaphore and associated task are not created when the simple blinky
demo is used. */ * demo is used. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
static unsigned long ulLastGiveTime = 0UL; static unsigned long ulLastGiveTime = 0UL;
@ -178,16 +185,16 @@ void vApplicationTickHook( void )
if( ( xTaskGetTickCountFromISR() - ulLastGiveTime ) > ulRate ) if( ( xTaskGetTickCountFromISR() - ulLastGiveTime ) > ulRate )
{ {
/* The second parameter is normally used to determine if a context /* The second parameter is normally used to determine if a context
switch should be performed or not. In this case the function is * switch should be performed or not. In this case the function is
being performed from the tick hook, so the scheduler will make that * being performed from the tick hook, so the scheduler will make that
assessment before returning to a task anyway - so the parameter is * assessment before returning to a task anyway - so the parameter is
not needed and is just set to NULL. */ * not needed and is just set to NULL. */
xSemaphoreGiveFromISR( xLEDSemaphore, NULL ); xSemaphoreGiveFromISR( xLEDSemaphore, NULL );
ulLastGiveTime += ulRate; ulLastGiveTime += ulRate;
} }
/* Write to a queue that is in use as part of the queue set demo to /* Write to a queue that is in use as part of the queue set demo to
demonstrate using queue sets from an ISR. */ * demonstrate using queue sets from an ISR. */
vQueueSetAccessQueueSetFromISR(); vQueueSetAccessQueueSetFromISR();
} }
#endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */ #endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */
@ -196,32 +203,28 @@ void vApplicationTickHook( void )
#ifdef JUST_AN_EXAMPLE_ISR #ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void) void Dummy_IRQHandler( void )
{ {
long lHigherPriorityTaskWoken = pdFALSE; long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */ /* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit(); Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a /* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note * task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. Only FreeRTOS API functions * lHigherPriorityTaskWoken is initialised to zero. Only FreeRTOS API functions
that end in "FromISR" can be called from an ISR. */ * that end in "FromISR" can be called from an ISR. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* If there was a task that was blocked on the semaphore, and giving the /* If there was a task that was blocked on the semaphore, and giving the
semaphore caused the task to unblock, and the unblocked task has a priority * semaphore caused the task to unblock, and the unblocked task has a priority
higher than the current Running state task (the task that this interrupt * higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE * interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the * internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to * portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority, * ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */ * task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
} }
#endif /* JUST_AN_EXAMPLE_ISR */ #endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -77,16 +77,16 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -94,8 +94,8 @@ functionality. */
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -123,7 +123,7 @@ void main_blinky( void )
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
@ -138,18 +138,20 @@ void main_blinky( void )
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
@ -157,39 +159,39 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
vParTestToggleLED( LED1 ); vParTestToggleLED( LED1 );
@ -198,4 +200,3 @@ unsigned long ulReceivedValue;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -87,20 +87,20 @@
#include "stm320518_eval.h" #include "stm320518_eval.h"
/* The period after which the check timer will expire provided no errors have /* The period after which the check timer will expire provided no errors have
been reported by any of the standard demo tasks. ms are converted to the * been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire if an error has been /* The period at which the check timer will expire if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/* A block time of zero simply means "don't block". */ /* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The base toggle rate used by the flash timers. Each toggle rate is a /* The base toggle rate used by the flash timers. Each toggle rate is a
multiple of this. */ * multiple of this. */
#define mainFLASH_TIMER_BASE_RATE ( 200UL / portTICK_PERIOD_MS ) #define mainFLASH_TIMER_BASE_RATE ( 200UL / portTICK_PERIOD_MS )
/* The LED toggle by the check timer. */ /* The LED toggle by the check timer. */
@ -111,8 +111,8 @@ multiple of this. */
* Register check tasks, as described at the top of this file. The nature of * Register check tasks, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly. * these files necessitates that they are written in an assembly.
*/ */
extern void vRegTest1Task( void *pvParameters ); extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void *pvParameters ); extern void vRegTest2Task( void * pvParameters );
/* /*
* The hardware only has a single LED. Simply toggle it. * The hardware only has a single LED. Simply toggle it.
@ -139,23 +139,24 @@ void main_full( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep * register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If * incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */ * a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xTimer = NULL; TimerHandle_t xTimer = NULL;
unsigned long ulTimer; unsigned long ulTimer;
const unsigned long ulTimersToCreate = 3L; const unsigned long ulTimersToCreate = 3L;
/* The register test tasks are asm functions that don't use a stack. The /* The register test tasks are asm functions that don't use a stack. The
stack allocated just has to be large enough to hold the task context, and * stack allocated just has to be large enough to hold the task context, and
for the additional required for the stack overflow checking to work (if * for the additional required for the stack overflow checking to work (if
configured). */ * configured). */
const size_t xRegTestStackSize = 25U; const size_t xRegTestStackSize = 25U;
/* Create the standard demo tasks */ /* Create the standard demo tasks */
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
@ -164,8 +165,8 @@ const size_t xRegTestStackSize = 25U;
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
/* Create the register test tasks as described at the top of this file. /* Create the register test tasks as described at the top of this file.
These are naked functions that don't use any stack. A stack still has * These are naked functions that don't use any stack. A stack still has
to be allocated to hold the task context. */ * to be allocated to hold the task context. */
xTaskCreate( vRegTest1Task, /* Function that implements the task. */ xTaskCreate( vRegTest1Task, /* Function that implements the task. */
"Reg1", /* Text name of the task. */ "Reg1", /* Text name of the task. */
xRegTestStackSize, /* Stack allocated to the task. */ xRegTestStackSize, /* Stack allocated to the task. */
@ -197,7 +198,7 @@ const size_t xRegTestStackSize = 25U;
} }
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
@ -206,9 +207,9 @@ const size_t xRegTestStackSize = 25U;
); );
/* If the software timer was created successfully, start it. It won't /* If the software timer was created successfully, start it. It won't
actually start running until the scheduler starts. A block time of * actually start running until the scheduler starts. A block time of
zero is used in this call, although any value could be used as the block * zero is used in this call, although any value could be used as the block
time will be ignored because the scheduler has not started yet. */ * time will be ignored because the scheduler has not started yet. */
if( xTimer != NULL ) if( xTimer != NULL )
{ {
xTimerStart( xTimer, mainDONT_BLOCK ); xTimerStart( xTimer, mainDONT_BLOCK );
@ -218,23 +219,25 @@ const size_t xRegTestStackSize = 25U;
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then there * line will never be reached. If the following line does execute, then there
was insufficient FreeRTOS heap memory available for the idle and/or timer * was insufficient FreeRTOS heap memory available for the idle and/or timer
tasks to be created. See the memory management section on the FreeRTOS web * tasks to be created. See the memory management section on the FreeRTOS web
site, or the FreeRTOS tutorial books for more details. */ * site, or the FreeRTOS tutorial books for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* See the description at the top of this file. */ /* See the description at the top of this file. */
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangedTimerPeriodAlready = pdFALSE; static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Check all the demo and test tasks to ensure that they are all still /* Check all the demo and test tasks to ensure that they are all still
running, and that none have detected an error. */ * running, and that none have detected an error. */
if( xAreDynamicPriorityTasksStillRunning() != pdPASS ) if( xAreDynamicPriorityTasksStillRunning() != pdPASS )
{ {
ulErrorFound |= ( 0x01UL << 0UL ); ulErrorFound |= ( 0x01UL << 0UL );
@ -260,6 +263,7 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound |= ( 0x01UL << 4UL ); ulErrorFound |= ( 0x01UL << 4UL );
} }
ulLastRegTest1Value = ulRegTest1LoopCounter; ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ /* Check that the register test 2 task is still running. */
@ -267,17 +271,18 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound |= ( 0x01UL << 5UL ); ulErrorFound |= ( 0x01UL << 5UL );
} }
ulLastRegTest2Value = ulRegTest2LoopCounter; ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If /* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */ * everything is ok. A faster toggle indicates an error. */
vParTestToggleLED( mainCHECK_LED ); vParTestToggleLED( mainCHECK_LED );
/* Have any errors been latched in ulErrorFound? If so, shorten the /* Have any errors been latched in ulErrorFound? If so, shorten the
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. * period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
This will result in an increase in the rate at which mainCHECK_LED * This will result in an increase in the rate at which mainCHECK_LED
toggles. */ * toggles. */
if( ulErrorFound != pdFALSE ) if( ulErrorFound != pdFALSE )
{ {
if( lChangedTimerPeriodAlready == pdFALSE ) if( lChangedTimerPeriodAlready == pdFALSE )
@ -285,8 +290,8 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE; lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time. /* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must * Functions called from inside of a timer callback function must
*never* attempt to block. */ * never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
} }
} }
@ -295,14 +300,13 @@ unsigned long ulErrorFound = pdFALSE;
static void prvFlashTimerCallback( TimerHandle_t xTimer ) static void prvFlashTimerCallback( TimerHandle_t xTimer )
{ {
unsigned long ulLED; unsigned long ulLED;
/* This callback function is assigned to three separate software timers. /* This callback function is assigned to three separate software timers.
Each timer toggles a different LED. Obtain the number of the LED that * Each timer toggles a different LED. Obtain the number of the LED that
this timer is toggling. */ * this timer is toggling. */
ulLED = ( unsigned long ) pvTimerGetTimerID( xTimer ); ulLED = ( unsigned long ) pvTimerGetTimerID( xTimer );
/* Toggle the LED. */ /* Toggle the LED. */
vParTestToggleLED( ulLED ); vParTestToggleLED( ulLED );
} }

View file

@ -52,7 +52,7 @@
#include "ParTest.h" #include "ParTest.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
@ -65,7 +65,7 @@ or 0 to run the more comprehensive test and demo application. */
static void prvSetupHardware( void ); static void prvSetupHardware( void );
/* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. /* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. */ * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. */
extern void main_blinky( void ); extern void main_blinky( void );
extern void main_full( void ); extern void main_full( void );
@ -77,7 +77,7 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
{ {
main_blinky(); main_blinky();
@ -101,85 +101,88 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* This function will be called by each tick interrupt if /* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be * configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so * added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API * code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */ * functions can be used (those that end in FromISR()). */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef JUST_AN_EXAMPLE_ISR #ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void) void Dummy_IRQHandler( void )
{ {
long lHigherPriorityTaskWoken = pdFALSE; long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */ /* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit(); Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a /* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note * task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. Only FreeRTOS API functions * lHigherPriorityTaskWoken is initialised to zero. Only FreeRTOS API functions
that end in "FromISR" can be called from an ISR. */ * that end in "FromISR" can be called from an ISR. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* If there was a task that was blocked on the semaphore, and giving the /* If there was a task that was blocked on the semaphore, and giving the
semaphore caused the task to unblock, and the unblocked task has a priority * semaphore caused the task to unblock, and the unblocked task has a priority
higher than the current Running state task (the task that this interrupt * higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE * interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the * internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to * portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority, * ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */ * task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
} }
#endif /* JUST_AN_EXAMPLE_ISR */ #endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -52,9 +52,9 @@
#include "task.h" #include "task.h"
/* Hardware register addresses. */ /* Hardware register addresses. */
#define mainVTOR ( * ( uint32_t * ) 0xE000ED08 ) #define mainVTOR ( *( uint32_t * ) 0xE000ED08 )
#define mainNVIC_AUX_ACTLR ( * ( uint32_t * ) 0xE000E008 ) #define mainNVIC_AUX_ACTLR ( *( uint32_t * ) 0xE000E008 )
#define mainEC_INTERRUPT_CONTROL ( * ( volatile uint32_t * ) 0x4000FC18 ) #define mainEC_INTERRUPT_CONTROL ( *( volatile uint32_t * ) 0x4000FC18 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -67,7 +67,7 @@ static void prvSetupHardware( void );
* main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1. * main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1.
* main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0. * main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0.
*/ */
#if( configCREATE_LOW_POWER_DEMO == 1 ) #if ( configCREATE_LOW_POWER_DEMO == 1 )
extern void main_low_power( void ); extern void main_low_power( void );
@ -75,27 +75,28 @@ static void prvSetupHardware( void );
extern void main_full( void ); extern void main_full( void );
/* Some of the tests and examples executed as part of the full demo make use /* Some of the tests and examples executed as part of the full demo make use
of the tick hook to call API functions from an interrupt context. */ * of the tick hook to call API functions from an interrupt context. */
extern void vFullDemoTickHook( void ); extern void vFullDemoTickHook( void );
#endif /* #if configCREATE_LOW_POWER_DEMO == 1 */ #endif /* #if configCREATE_LOW_POWER_DEMO == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The variable that is incremented to represent each LED toggle. On the /* The variable that is incremented to represent each LED toggle. On the
clicker hardware the LED state is set to the value of the least significant bit * clicker hardware the LED state is set to the value of the least significant bit
of this variable. On other hardware, where an LED is not used, the LED just * of this variable. On other hardware, where an LED is not used, the LED just
keeps a count of the number of times the LED would otherwise have been toggled. * keeps a count of the number of times the LED would otherwise have been toggled.
See the comments in main_low_power.c and main_full.c for information on the * See the comments in main_low_power.c and main_full.c for information on the
expected LED toggle rate). */ * expected LED toggle rate). */
volatile uint32_t ulLED = 0; volatile uint32_t ulLED = 0;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -108,11 +109,11 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The configCREATE_LOW_POWER_DEMO setting is described at the top /* The configCREATE_LOW_POWER_DEMO setting is described at the top
of this file. */ * of this file. */
#if( configCREATE_LOW_POWER_DEMO == 1 ) #if ( configCREATE_LOW_POWER_DEMO == 1 )
{ {
/* The low power demo also demonstrated aggregated interrupts, so clear /* The low power demo also demonstrated aggregated interrupts, so clear
the interrupt control register to disable the alternative NVIC vectors. */ * the interrupt control register to disable the alternative NVIC vectors. */
mainEC_INTERRUPT_CONTROL = pdFALSE; mainEC_INTERRUPT_CONTROL = pdFALSE;
main_low_power(); main_low_power();
@ -120,12 +121,12 @@ int main( void )
#else #else
{ {
/* The full demo also demonstrated disaggregated interrupts, so set the /* The full demo also demonstrated disaggregated interrupts, so set the
interrupt control register to enable the alternative NVIC vectors. */ * interrupt control register to enable the alternative NVIC vectors. */
mainEC_INTERRUPT_CONTROL = pdTRUE; mainEC_INTERRUPT_CONTROL = pdTRUE;
main_full(); main_full();
} }
#endif #endif /* if ( configCREATE_LOW_POWER_DEMO == 1 ) */
/* Should not get here. */ /* Should not get here. */
return 0; return 0;
@ -134,8 +135,8 @@ int main( void )
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
extern void system_set_ec_clock( void ); extern void system_set_ec_clock( void );
extern unsigned long __Vectors[]; extern unsigned long __Vectors[];
/* Disable M4 write buffer: fix CEC1302 hardware bug. */ /* Disable M4 write buffer: fix CEC1302 hardware bug. */
mainNVIC_AUX_ACTLR |= 0x07; mainNVIC_AUX_ACTLR |= 0x07;
@ -143,7 +144,7 @@ extern unsigned long __Vectors[];
system_set_ec_clock(); system_set_ec_clock();
/* Assuming downloading code via the debugger - so ensure the hardware /* Assuming downloading code via the debugger - so ensure the hardware
is using the vector table downloaded with the application. */ * is using the vector table downloaded with the application. */
mainVTOR = ( uint32_t ) __Vectors; mainVTOR = ( uint32_t ) __Vectors;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -151,24 +152,25 @@ extern unsigned long __Vectors[];
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
@ -177,15 +179,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -196,11 +198,11 @@ volatile size_t xFreeHeapSpace;
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* The full demo includes tests that run from the tick hook. */ /* The full demo includes tests that run from the tick hook. */
#if( configCREATE_LOW_POWER_DEMO == 0 ) #if ( configCREATE_LOW_POWER_DEMO == 0 )
{ {
/* Some of the tests and demo tasks executed by the full demo include /* Some of the tests and demo tasks executed by the full demo include
interaction from an interrupt - for which the tick interrupt is used * interaction from an interrupt - for which the tick interrupt is used
via the tick hook function. */ * via the tick hook function. */
vFullDemoTickHook(); vFullDemoTickHook();
} }
#endif #endif
@ -208,52 +210,54 @@ void vApplicationTickHook( void )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */ * used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{ {
/* If the buffers to be provided to the Idle task are declared inside this /* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB; static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */ * state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB; *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */ /* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack; *ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory() * application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */ * to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
uint32_t * pulTimerTaskStackSize )
{ {
/* If the buffers to be provided to the Timer task are declared inside this /* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB; static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer /* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */ * task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB; *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */ /* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack; *ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
} }

View file

@ -47,10 +47,10 @@
#include "task.h" #include "task.h"
/* Hardware register addresses and value. */ /* Hardware register addresses and value. */
#define mainVTOR ( * ( uint32_t * ) 0xE000ED08 ) #define mainVTOR ( *( uint32_t * ) 0xE000ED08 )
#define mainNVIC_AUX_ACTLR ( * ( uint32_t * ) 0xE000E008 ) #define mainNVIC_AUX_ACTLR ( *( uint32_t * ) 0xE000E008 )
#define mainEC_INTERRUPT_CONTROL ( * ( volatile uint32_t * ) 0x4000FC18 ) #define mainEC_INTERRUPT_CONTROL ( *( volatile uint32_t * ) 0x4000FC18 )
#define mainMMCR_PCR_PROCESSOR_CLOCK_CONTROL ( * ( volatile uint32_t * )( 0x40080120 ) ) #define mainMMCR_PCR_PROCESSOR_CLOCK_CONTROL ( *( volatile uint32_t * ) ( 0x40080120 ) )
#define mainCPU_CLOCK_DIVIDER 1 #define mainCPU_CLOCK_DIVIDER 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -64,7 +64,7 @@ static void prvSetupHardware( void );
* main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1. * main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1.
* main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0. * main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0.
*/ */
#if( configCREATE_LOW_POWER_DEMO == 1 ) #if ( configCREATE_LOW_POWER_DEMO == 1 )
extern void main_low_power( void ); extern void main_low_power( void );
@ -72,27 +72,28 @@ static void prvSetupHardware( void );
extern void main_full( void ); extern void main_full( void );
/* Some of the tests and examples executed as part of the full demo make use /* Some of the tests and examples executed as part of the full demo make use
of the tick hook to call API functions from an interrupt context. */ * of the tick hook to call API functions from an interrupt context. */
extern void vFullDemoTickHook( void ); extern void vFullDemoTickHook( void );
#endif /* #if configCREATE_LOW_POWER_DEMO == 1 */ #endif /* #if configCREATE_LOW_POWER_DEMO == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The variable that is incremented to represent each LED toggle. On the /* The variable that is incremented to represent each LED toggle. On the
clicker hardware the LED state is set to the value of the least significant bit * clicker hardware the LED state is set to the value of the least significant bit
of this variable. On other hardware, where an LED is not used, the LED just * of this variable. On other hardware, where an LED is not used, the LED just
keeps a count of the number of times the LED would otherwise have been toggled. * keeps a count of the number of times the LED would otherwise have been toggled.
See the comments in main_low_power.c and main_full.c for information on the * See the comments in main_low_power.c and main_full.c for information on the
expected LED toggle rate). */ * expected LED toggle rate). */
volatile uint32_t ulLED = 0; volatile uint32_t ulLED = 0;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -103,8 +104,8 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The configCREATE_LOW_POWER_DEMO setting is described at the top /* The configCREATE_LOW_POWER_DEMO setting is described at the top
of this file. */ * of this file. */
#if( configCREATE_LOW_POWER_DEMO == 1 ) #if ( configCREATE_LOW_POWER_DEMO == 1 )
{ {
main_low_power(); main_low_power();
} }
@ -125,7 +126,7 @@ static void prvSetupHardware( void )
mainNVIC_AUX_ACTLR |= 0x07; mainNVIC_AUX_ACTLR |= 0x07;
/* Set divider to 8 for 8MHz operation, MCLK in silicon chip is 64MHz, /* Set divider to 8 for 8MHz operation, MCLK in silicon chip is 64MHz,
CPU=MCLK/Divider. */ * CPU=MCLK/Divider. */
mainMMCR_PCR_PROCESSOR_CLOCK_CONTROL = mainCPU_CLOCK_DIVIDER; mainMMCR_PCR_PROCESSOR_CLOCK_CONTROL = mainCPU_CLOCK_DIVIDER;
/* Enable alternative NVIC vectors. */ /* Enable alternative NVIC vectors. */
@ -141,24 +142,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
@ -167,15 +169,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -186,11 +188,11 @@ volatile size_t xFreeHeapSpace;
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* The full demo includes tests that run from the tick hook. */ /* The full demo includes tests that run from the tick hook. */
#if( configCREATE_LOW_POWER_DEMO == 0 ) #if ( configCREATE_LOW_POWER_DEMO == 0 )
{ {
/* Some of the tests and demo tasks executed by the full demo include /* Some of the tests and demo tasks executed by the full demo include
interaction from an interrupt - for which the tick interrupt is used * interaction from an interrupt - for which the tick interrupt is used
via the tick hook function. */ * via the tick hook function. */
vFullDemoTickHook(); vFullDemoTickHook();
} }
#endif #endif
@ -198,52 +200,54 @@ void vApplicationTickHook( void )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */ * used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{ {
/* If the buffers to be provided to the Idle task are declared inside this /* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB; static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */ * state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB; *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */ /* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack; *ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory() * application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */ * to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
uint32_t * pulTimerTaskStackSize )
{ {
/* If the buffers to be provided to the Timer task are declared inside this /* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB; static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer /* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */ * task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB; *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */ /* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack; *ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
} }

View file

@ -48,12 +48,12 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( pdMS_TO_TICKS( 1000UL ) ) #define mainQUEUE_SEND_FREQUENCY_MS ( pdMS_TO_TICKS( 1000UL ) )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH_IN_ITEMS ( 1 ) #define mainQUEUE_LENGTH_IN_ITEMS ( 1 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -67,20 +67,20 @@ static void prvSetupHardware( void );
* Simple routine to print a string to ITM for viewing in the Keil serial debug * Simple routine to print a string to ITM for viewing in the Keil serial debug
* viewer. * viewer.
*/ */
static void prvITMPrintString( const char *pcString ); static void prvITMPrintString( const char * pcString );
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configSUPPORT_STATIC_ALLOCATION is 1 and configSUPPORT_DYNAMIC_ALLOCATION is /* configSUPPORT_STATIC_ALLOCATION is 1 and configSUPPORT_DYNAMIC_ALLOCATION is
0 so the queue structure and the queue storage area can only be statically * 0 so the queue structure and the queue storage area can only be statically
allocated. See http://TBD for more information. * allocated. See http://TBD for more information.
The queue storage area is dimensioned to hold just one 32-bit value. */ * The queue storage area is dimensioned to hold just one 32-bit value. */
static StaticQueue_t xStaticQueue; static StaticQueue_t xStaticQueue;
static uint8_t ucQueueStorageArea[ mainQUEUE_LENGTH_IN_ITEMS * sizeof( uint32_t ) ]; static uint8_t ucQueueStorageArea[ mainQUEUE_LENGTH_IN_ITEMS * sizeof( uint32_t ) ];
@ -88,8 +88,8 @@ static uint8_t ucQueueStorageArea[ mainQUEUE_LENGTH_IN_ITEMS * sizeof( uint32_t
static QueueHandle_t xQueue = NULL; static QueueHandle_t xQueue = NULL;
/* configSUPPORT_STATIC_ALLOCATION is 1 and configSUPPORT_DYNAMIC_ALLOCATION is /* configSUPPORT_STATIC_ALLOCATION is 1 and configSUPPORT_DYNAMIC_ALLOCATION is
0 so the task structure and the stacks used by the tasks can only be statically * 0 so the task structure and the stacks used by the tasks can only be statically
allocated. See http://TBD for more information. */ * allocated. See http://TBD for more information. */
StaticTask_t xRxTCBBuffer, xTxTCBBuffer; StaticTask_t xRxTCBBuffer, xTxTCBBuffer;
static StackType_t uxRxStackBuffer[ configMINIMAL_STACK_SIZE ], uxTxStackBuffer[ configMINIMAL_STACK_SIZE ]; static StackType_t uxRxStackBuffer[ configMINIMAL_STACK_SIZE ], uxTxStackBuffer[ configMINIMAL_STACK_SIZE ];
@ -102,22 +102,22 @@ int main( void )
prvITMPrintString( "Starting\r\n" ); prvITMPrintString( "Starting\r\n" );
/* Create the queue. xQueueCreateStatic() has two more parameters than the /* Create the queue. xQueueCreateStatic() has two more parameters than the
xQueueCreate() function. The first new parameter is a pointer to the * xQueueCreate() function. The first new parameter is a pointer to the
pre-allocated queue storage area. The second new parameter is a pointer to * pre-allocated queue storage area. The second new parameter is a pointer to
the StaticQueue_t structure that will hold the queue state information in * the StaticQueue_t structure that will hold the queue state information in
an anonymous way. */ * an anonymous way. */
xQueue = xQueueCreateStatic( mainQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */ xQueue = xQueueCreateStatic( mainQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
sizeof( uint32_t ), /* The size of each item. */ sizeof( uint32_t ), /* The size of each item. */
ucQueueStorageArea, /* The buffer used to hold items within the queue. */ ucQueueStorageArea, /* The buffer used to hold items within the queue. */
&xStaticQueue ); /* The static queue structure that will hold the state of the queue. */ &xStaticQueue ); /* The static queue structure that will hold the state of the queue. */
/* Create the two tasks as described in the comments at the top of this /* Create the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreateStatic( prvQueueReceiveTask, /* Function that implements the task. */ xTaskCreateStatic( prvQueueReceiveTask, /* Function that implements the task. */
"Rx", /* Human readable name for the task. */ "Rx", /* Human readable name for the task. */
configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */ configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
NULL, /* Parameter to pass into the task. */ NULL, /* Parameter to pass into the task. */
mainQUEUE_RECEIVE_TASK_PRIORITY,/* The priority of the task. */ mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority of the task. */
&( uxRxStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */ &( uxRxStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */
&xRxTCBBuffer ); /* The variable that will hold that task's TCB. */ &xRxTCBBuffer ); /* The variable that will hold that task's TCB. */
@ -133,51 +133,53 @@ int main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* If dynamic memory allocation was used then the following code line would /* If dynamic memory allocation was used then the following code line would
be reached if there was insufficient heap memory available to create either * be reached if there was insufficient heap memory available to create either
the timer or idle tasks. As this project is using static memory allocation * the timer or idle tasks. As this project is using static memory allocation
then the following line should never be reached. */ * then the following line should never be reached. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
/* Output a string in lieu of using an LED. */ /* Output a string in lieu of using an LED. */
@ -194,67 +196,75 @@ static void prvSetupHardware( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
/* If configCHECK_FOR_STACK_OVERFLOW is set to either 1 or 2 then this /* If configCHECK_FOR_STACK_OVERFLOW is set to either 1 or 2 then this
function will automatically get called if a task overflows its stack. */ * function will automatically get called if a task overflows its stack. */
( void ) pxTask; ( void ) pxTask;
( void ) pcTaskName; ( void ) pcTaskName;
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */ * used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{ {
/* If the buffers to be provided to the Idle task are declared inside this /* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB; static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */ * state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB; *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */ /* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack; *ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory() * application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */ * to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
uint32_t * pulTimerTaskStackSize )
{ {
/* If the buffers to be provided to the Timer task are declared inside this /* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB; static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer /* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */ * task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB; *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */ /* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack; *ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvITMPrintString( const char *pcString ) static void prvITMPrintString( const char * pcString )
{ {
while( *pcString != 0x00 ) while( *pcString != 0x00 )
{ {
@ -263,4 +273,3 @@ static void prvITMPrintString( const char *pcString )
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -62,7 +62,7 @@
#include "task.h" #include "task.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -87,7 +87,7 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
{ {
main_blinky(); main_blinky();
@ -114,80 +114,87 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* This function will be called by each tick interrupt if /* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be * configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so * added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API * code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */ * functions can be used (those that end in FromISR()). */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef JUST_AN_EXAMPLE_ISR #ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void) void Dummy_IRQHandler( void )
{ {
long lHigherPriorityTaskWoken = pdFALSE; long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */ /* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit(); Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a /* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note * task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. */ * lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* If there was a task that was blocked on the semaphore, and giving the /* If there was a task that was blocked on the semaphore, and giving the
semaphore caused the task to unblock, and the unblocked task has a priority * semaphore caused the task to unblock, and the unblocked task has a priority
higher than the current Running state task (the task that this interrupt * higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE * interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the * internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to * portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority, * ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */ * task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
} }
#endif /* JUST_AN_EXAMPLE_ISR */ #endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -74,16 +74,16 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
@ -92,8 +92,8 @@ functionality. */
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -116,7 +116,7 @@ void main_blinky( void )
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
@ -131,18 +131,20 @@ void main_blinky( void )
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
@ -150,39 +152,39 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
configTOGGLE_LED(); configTOGGLE_LED();
@ -191,4 +193,3 @@ unsigned long ulReceivedValue;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -93,13 +93,13 @@
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The period after which the check timer will expire, in ms, provided no errors /* The period after which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the * have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been /* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -114,26 +114,26 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer );
* of the FPU registers, as described at the top of this file. The nature of * of the FPU registers, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly file. * these files necessitates that they are written in an assembly file.
*/ */
static void prvRegTest1Task( void *pvParameters ) __attribute__((naked)); static void prvRegTest1Task( void * pvParameters ) __attribute__( ( naked ) );
static void prvRegTest2Task( void *pvParameters ) __attribute__((naked)); static void prvRegTest2Task( void * pvParameters ) __attribute__( ( naked ) );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep * register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If * incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */ * a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xCheckTimer = NULL; TimerHandle_t xCheckTimer = NULL;
/* Start all the other standard demo/test tasks. The have not particular /* Start all the other standard demo/test tasks. The have not particular
functionality, but do demonstrate how to use the FreeRTOS API and test the * functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */ * kernel port. */
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartCountingSemaphoreTasks(); vStartCountingSemaphoreTasks();
@ -143,12 +143,12 @@ TimerHandle_t xCheckTimer = NULL;
vStartMathTasks( mainFLOP_TASK_PRIORITY ); vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* Create the register check tasks, as described at the top of this /* Create the register check tasks, as described at the top of this
file */ * file */
xTaskCreate( prvRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( prvRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( prvRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( prvRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
@ -165,22 +165,24 @@ TimerHandle_t xCheckTimer = NULL;
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangedTimerPeriodAlready = pdFALSE; static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
@ -192,17 +194,17 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
@ -217,6 +219,7 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
ulLastRegTest1Value = ulRegTest1LoopCounter; ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ /* Check that the register test 2 task is still running. */
@ -224,17 +227,18 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
ulLastRegTest2Value = ulRegTest2LoopCounter; ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If /* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */ * everything is ok. A faster toggle indicates an error. */
configTOGGLE_LED(); configTOGGLE_LED();
/* Have any errors been latch in ulErrorFound? If so, shorten the /* Have any errors been latch in ulErrorFound? If so, shorten the
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. * period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
This will result in an increase in the rate at which mainCHECK_LED * This will result in an increase in the rate at which mainCHECK_LED
toggles. */ * toggles. */
if( ulErrorFound != pdFALSE ) if( ulErrorFound != pdFALSE )
{ {
if( lChangedTimerPeriodAlready == pdFALSE ) if( lChangedTimerPeriodAlready == pdFALSE )
@ -242,8 +246,8 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE; lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time. /* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must * Functions called from inside of a timer callback function must
*never* attempt to block. */ * never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
} }
} }
@ -251,7 +255,7 @@ unsigned long ulErrorFound = pdFALSE;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* This is a naked function. */ /* This is a naked function. */
static void prvRegTest1Task( void *pvParameters ) static void prvRegTest1Task( void * pvParameters )
{ {
__asm volatile __asm volatile
( (
@ -435,7 +439,7 @@ static void prvRegTest1Task( void *pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* This is a naked function. */ /* This is a naked function. */
static void prvRegTest2Task( void *pvParameters ) static void prvRegTest2Task( void * pvParameters )
{ {
__asm volatile __asm volatile
( (
@ -609,8 +613,8 @@ static void prvRegTest2Task( void *pvParameters )
" \n" " \n"
" /* Yield to increase test coverage. */ \n" " /* Yield to increase test coverage. */ \n"
" movs r0, #0x01 \n" " movs r0, #0x01 \n"
" ldr r1, =0xe000ed04 \n" /*NVIC_INT_CTRL */ " ldr r1, =0xe000ed04 \n"/*NVIC_INT_CTRL */
" lsl r0, #28 \n" /* Shift to PendSV bit */ " lsl r0, #28 \n"/* Shift to PendSV bit */
" str r0, [r1] \n" " str r0, [r1] \n"
" dsb \n" " dsb \n"
" pop { r0-r1 } \n" " pop { r0-r1 } \n"

View file

@ -59,7 +59,7 @@
#include "QueueOverwrite.h" #include "QueueOverwrite.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -84,7 +84,7 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
{ {
main_blinky(); main_blinky();
@ -111,59 +111,66 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* This function will be called by each tick interrupt if /* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be * configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so * added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API * code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */ * functions can be used (those that end in FromISR()). */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
/* Write to a queue that is in use as part of the queue set demo to /* Write to a queue that is in use as part of the queue set demo to
demonstrate using queue sets from an ISR. */ * demonstrate using queue sets from an ISR. */
vQueueSetAccessQueueSetFromISR(); vQueueSetAccessQueueSetFromISR();
/* Test the ISR safe queue overwrite functions. */ /* Test the ISR safe queue overwrite functions. */
@ -175,27 +182,27 @@ void vApplicationTickHook( void )
#ifdef JUST_AN_EXAMPLE_ISR #ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void) void Dummy_IRQHandler( void )
{ {
long lHigherPriorityTaskWoken = pdFALSE; long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */ /* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit(); Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a /* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note * task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. */ * lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* If there was a task that was blocked on the semaphore, and giving the /* If there was a task that was blocked on the semaphore, and giving the
semaphore caused the task to unblock, and the unblocked task has a priority * semaphore caused the task to unblock, and the unblocked task has a priority
higher than the current Running state task (the task that this interrupt * higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE * interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the * internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to * portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority, * ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */ * task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
} }
#endif /* JUST_AN_EXAMPLE_ISR */ #endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -74,16 +74,16 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
@ -92,8 +92,8 @@ functionality. */
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -116,7 +116,7 @@ void main_blinky( void )
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
@ -131,18 +131,20 @@ void main_blinky( void )
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
@ -150,39 +152,39 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
configTOGGLE_LED(); configTOGGLE_LED();
@ -191,4 +193,3 @@ unsigned long ulReceivedValue;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -95,13 +95,13 @@
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The period after which the check timer will expire, in ms, provided no errors /* The period after which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the * have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been /* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -116,26 +116,26 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer );
* of the FPU registers, as described at the top of this file. The nature of * of the FPU registers, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly file. * these files necessitates that they are written in an assembly file.
*/ */
extern void vRegTest1Task( void *pvParameters ); extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void *pvParameters ); extern void vRegTest2Task( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep * register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If * incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */ * a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xCheckTimer = NULL; TimerHandle_t xCheckTimer = NULL;
/* Start all the other standard demo/test tasks. The have not particular /* Start all the other standard demo/test tasks. The have not particular
functionality, but do demonstrate how to use the FreeRTOS API and test the * functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */ * kernel port. */
vStartQueueSetTasks(); vStartQueueSetTasks();
vStartQueueOverwriteTask( tskIDLE_PRIORITY ); vStartQueueOverwriteTask( tskIDLE_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
@ -145,12 +145,12 @@ TimerHandle_t xCheckTimer = NULL;
vStartMathTasks( mainFLOP_TASK_PRIORITY ); vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* Create the register check tasks, as described at the top of this /* Create the register check tasks, as described at the top of this
file */ * file */
xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
@ -167,22 +167,24 @@ TimerHandle_t xCheckTimer = NULL;
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangedTimerPeriodAlready = pdFALSE; static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
@ -194,17 +196,17 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
@ -224,6 +226,7 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
ulLastRegTest1Value = ulRegTest1LoopCounter; ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ /* Check that the register test 2 task is still running. */
@ -231,17 +234,18 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
ulLastRegTest2Value = ulRegTest2LoopCounter; ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If /* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */ * everything is ok. A faster toggle indicates an error. */
configTOGGLE_LED(); configTOGGLE_LED();
/* Have any errors been latch in ulErrorFound? If so, shorten the /* Have any errors been latch in ulErrorFound? If so, shorten the
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. * period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
This will result in an increase in the rate at which mainCHECK_LED * This will result in an increase in the rate at which mainCHECK_LED
toggles. */ * toggles. */
if( ulErrorFound != pdFALSE ) if( ulErrorFound != pdFALSE )
{ {
if( lChangedTimerPeriodAlready == pdFALSE ) if( lChangedTimerPeriodAlready == pdFALSE )
@ -249,11 +253,10 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE; lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time. /* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must * Functions called from inside of a timer callback function must
*never* attempt to block. */ * never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -55,7 +55,7 @@
#include "task.h" #include "task.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -80,7 +80,7 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
{ {
main_blinky(); main_blinky();
@ -107,80 +107,87 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* This function will be called by each tick interrupt if /* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be * configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so * added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API * code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */ * functions can be used (those that end in FromISR()). */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef JUST_AN_EXAMPLE_ISR #ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void) void Dummy_IRQHandler( void )
{ {
long lHigherPriorityTaskWoken = pdFALSE; long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */ /* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit(); Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a /* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note * task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. */ * lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* If there was a task that was blocked on the semaphore, and giving the /* If there was a task that was blocked on the semaphore, and giving the
semaphore caused the task to unblock, and the unblocked task has a priority * semaphore caused the task to unblock, and the unblocked task has a priority
higher than the current Running state task (the task that this interrupt * higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE * interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the * internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to * portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority, * ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */ * task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
} }
#endif /* JUST_AN_EXAMPLE_ISR */ #endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -74,16 +74,16 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
@ -92,8 +92,8 @@ functionality. */
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -116,7 +116,7 @@ void main_blinky( void )
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
@ -131,18 +131,20 @@ void main_blinky( void )
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
@ -150,39 +152,39 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
configTOGGLE_LED(); configTOGGLE_LED();
@ -191,4 +193,3 @@ unsigned long ulReceivedValue;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -93,13 +93,13 @@
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The period after which the check timer will expire, in ms, provided no errors /* The period after which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the * have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been /* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -114,26 +114,26 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer );
* of the FPU registers, as described at the top of this file. The nature of * of the FPU registers, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly file. * these files necessitates that they are written in an assembly file.
*/ */
extern void vRegTest1Task( void *pvParameters ); extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void *pvParameters ); extern void vRegTest2Task( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep * register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If * incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */ * a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xCheckTimer = NULL; TimerHandle_t xCheckTimer = NULL;
/* Start all the other standard demo/test tasks. The have not particular /* Start all the other standard demo/test tasks. The have not particular
functionality, but do demonstrate how to use the FreeRTOS API and test the * functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */ * kernel port. */
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartCountingSemaphoreTasks(); vStartCountingSemaphoreTasks();
@ -143,12 +143,12 @@ TimerHandle_t xCheckTimer = NULL;
vStartMathTasks( mainFLOP_TASK_PRIORITY ); vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* Create the register check tasks, as described at the top of this /* Create the register check tasks, as described at the top of this
file */ * file */
xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
@ -165,22 +165,24 @@ TimerHandle_t xCheckTimer = NULL;
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangedTimerPeriodAlready = pdFALSE; static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
@ -192,17 +194,17 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
@ -217,6 +219,7 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
ulLastRegTest1Value = ulRegTest1LoopCounter; ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ /* Check that the register test 2 task is still running. */
@ -224,17 +227,18 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
ulLastRegTest2Value = ulRegTest2LoopCounter; ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If /* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */ * everything is ok. A faster toggle indicates an error. */
configTOGGLE_LED(); configTOGGLE_LED();
/* Have any errors been latch in ulErrorFound? If so, shorten the /* Have any errors been latch in ulErrorFound? If so, shorten the
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. * period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
This will result in an increase in the rate at which mainCHECK_LED * This will result in an increase in the rate at which mainCHECK_LED
toggles. */ * toggles. */
if( ulErrorFound != pdFALSE ) if( ulErrorFound != pdFALSE )
{ {
if( lChangedTimerPeriodAlready == pdFALSE ) if( lChangedTimerPeriodAlready == pdFALSE )
@ -242,11 +246,10 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE; lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time. /* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must * Functions called from inside of a timer callback function must
*never* attempt to block. */ * never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -68,7 +68,7 @@
#include "QueueOverwrite.h" #include "QueueOverwrite.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -93,7 +93,7 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
{ {
main_blinky(); main_blinky();
@ -120,49 +120,52 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; )
for( ; ; )
{ {
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
}; }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; )
for( ; ; )
{ {
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -170,15 +173,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* This function will be called by each tick interrupt if /* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be * configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so * added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API * code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */ * functions can be used (those that end in FromISR()). */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
/* Write to a queue that is in use as part of the queue set demo to /* Write to a queue that is in use as part of the queue set demo to
demonstrate using queue sets from an ISR. */ * demonstrate using queue sets from an ISR. */
vQueueSetAccessQueueSetFromISR(); vQueueSetAccessQueueSetFromISR();
/* Test the ISR safe queue overwrite functions. */ /* Test the ISR safe queue overwrite functions. */
@ -190,27 +193,27 @@ void vApplicationTickHook( void )
#ifdef JUST_AN_EXAMPLE_ISR #ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void) void Dummy_IRQHandler( void )
{ {
long lHigherPriorityTaskWoken = pdFALSE; long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */ /* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit(); Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a /* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note * task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. */ * lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* If there was a task that was blocked on the semaphore, and giving the /* If there was a task that was blocked on the semaphore, and giving the
semaphore caused the task to unblock, and the unblocked task has a priority * semaphore caused the task to unblock, and the unblocked task has a priority
higher than the current Running state task (the task that this interrupt * higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE * interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the * internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to * portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority, * ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */ * task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
} }
#endif /* JUST_AN_EXAMPLE_ISR */ #endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -74,16 +74,16 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
@ -92,8 +92,8 @@ functionality. */
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -116,7 +116,7 @@ void main_blinky( void )
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
@ -131,21 +131,21 @@ void main_blinky( void )
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ) for( ; ; )
{ {
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
@ -153,39 +153,39 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
configTOGGLE_LED(); configTOGGLE_LED();
@ -194,4 +194,3 @@ unsigned long ulReceivedValue;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -95,13 +95,13 @@
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The period after which the check timer will expire, in ms, provided no errors /* The period after which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the * have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been /* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -116,26 +116,26 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer );
* of the FPU registers, as described at the top of this file. The nature of * of the FPU registers, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly file. * these files necessitates that they are written in an assembly file.
*/ */
static void vRegTest1Task( void *pvParameters ); static void vRegTest1Task( void * pvParameters );
static void vRegTest2Task( void *pvParameters ); static void vRegTest2Task( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep * register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If * incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */ * a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xCheckTimer = NULL; TimerHandle_t xCheckTimer = NULL;
/* Start all the other standard demo/test tasks. The have not particular /* Start all the other standard demo/test tasks. The have not particular
functionality, but do demonstrate how to use the FreeRTOS API and test the * functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */ * kernel port. */
vStartQueueSetTasks(); vStartQueueSetTasks();
vStartQueueOverwriteTask( tskIDLE_PRIORITY ); vStartQueueOverwriteTask( tskIDLE_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
@ -145,12 +145,12 @@ TimerHandle_t xCheckTimer = NULL;
vStartMathTasks( mainFLOP_TASK_PRIORITY ); vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* Create the register check tasks, as described at the top of this /* Create the register check tasks, as described at the top of this
file */ * file */
xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
@ -167,25 +167,25 @@ TimerHandle_t xCheckTimer = NULL;
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ) for( ; ; )
{ {
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangedTimerPeriodAlready = pdFALSE; static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
@ -197,17 +197,17 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
@ -227,6 +227,7 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
ulLastRegTest1Value = ulRegTest1LoopCounter; ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ /* Check that the register test 2 task is still running. */
@ -234,17 +235,18 @@ unsigned long ulErrorFound = pdFALSE;
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
ulLastRegTest2Value = ulRegTest2LoopCounter; ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If /* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */ * everything is ok. A faster toggle indicates an error. */
configTOGGLE_LED(); configTOGGLE_LED();
/* Have any errors been latch in ulErrorFound? If so, shorten the /* Have any errors been latch in ulErrorFound? If so, shorten the
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. * period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
This will result in an increase in the rate at which mainCHECK_LED * This will result in an increase in the rate at which mainCHECK_LED
toggles. */ * toggles. */
if( ulErrorFound != pdFALSE ) if( ulErrorFound != pdFALSE )
{ {
if( lChangedTimerPeriodAlready == pdFALSE ) if( lChangedTimerPeriodAlready == pdFALSE )
@ -252,8 +254,8 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE; lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time. /* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must * Functions called from inside of a timer callback function must
*never* attempt to block. */ * never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
} }
} }
@ -261,11 +263,11 @@ unsigned long ulErrorFound = pdFALSE;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* This is a naked function. */ /* This is a naked function. */
static void vRegTest1Task( void *pvParameters ) static void vRegTest1Task( void * pvParameters )
{ {
__asm volatile __asm volatile
( (
" \n" /* Fill the core registers with known values. */ " \n"/* Fill the core registers with known values. */
" mov r0, #100 \n" " mov r0, #100 \n"
" mov r1, #101 \n" " mov r1, #101 \n"
" mov r2, #102 \n" " mov r2, #102 \n"
@ -280,7 +282,7 @@ static void vRegTest1Task( void *pvParameters )
" mov r11, #111 \n" " mov r11, #111 \n"
" mov r12, #112 \n" " mov r12, #112 \n"
" \n" " \n"
" vmov d0, r0, r1 \n" /* Fill the VFP registers with known values. */ " vmov d0, r0, r1 \n"/* Fill the VFP registers with known values. */
" vmov d1, r2, r3 \n" " vmov d1, r2, r3 \n"
" vmov d2, r4, r5 \n" " vmov d2, r4, r5 \n"
" vmov d3, r6, r7 \n" " vmov d3, r6, r7 \n"
@ -297,8 +299,8 @@ static void vRegTest1Task( void *pvParameters )
" vmov d14, r4, r5 \n" " vmov d14, r4, r5 \n"
" vmov d15, r6, r7 \n" " vmov d15, r6, r7 \n"
" \n" " \n"
"reg1_loop: \n" /* Check all the VFP registers still contain the values set above." */ "reg1_loop: \n"/* Check all the VFP registers still contain the values set above." */
" push { r0-r1 } \n" /* First save registers that are clobbered by the test. */ " push { r0-r1 } \n"/* First save registers that are clobbered by the test. */
" \n" " \n"
" vmov r0, r1, d0 \n" " vmov r0, r1, d0 \n"
" cmp r0, #100 \n" " cmp r0, #100 \n"
@ -381,12 +383,12 @@ static void vRegTest1Task( void *pvParameters )
" cmp r1, #107 \n" " cmp r1, #107 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" \n" " \n"
" pop {r0-r1} \n" /* Restore the registers that were clobbered by the test. */ " pop {r0-r1} \n"/* Restore the registers that were clobbered by the test. */
" \n" " \n"
" b reg1_loopf_pass \n" /* VFP register test passed. Jump to the core register test. */ " b reg1_loopf_pass \n"/* VFP register test passed. Jump to the core register test. */
" \n" " \n"
"reg1_error_loopf: \n" "reg1_error_loopf: \n"
" b reg1_error_loopf \n" /* If this line is hit then a VFP register value was found to be\n incorrect. */ " b reg1_error_loopf \n"/* If this line is hit then a VFP register value was found to be\n incorrect. */
" \n" " \n"
"reg1_loopf_pass: \n" "reg1_loopf_pass: \n"
" \n" " \n"
@ -417,28 +419,28 @@ static void vRegTest1Task( void *pvParameters )
" cmp r12, #112 \n" " cmp r12, #112 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" \n" " \n"
" push { r0-r1 } \n" /* Everything passed, increment the loop counter. */ " push { r0-r1 } \n"/* Everything passed, increment the loop counter. */
" ldr r0, =ulRegTest1LoopCounter \n" " ldr r0, =ulRegTest1LoopCounter \n"
" ldr r1, [r0] \n" " ldr r1, [r0] \n"
" adds r1, r1, #1 \n" " adds r1, r1, #1 \n"
" str r1, [r0] \n" " str r1, [r0] \n"
" pop { r0-r1 } \n" " pop { r0-r1 } \n"
" \n" " \n"
" b reg1_loop \n" /* Start again. */ " b reg1_loop \n"/* Start again. */
" \n" " \n"
"reg1_error_loop: \n" /* If this line is hit then there was an error in a core register value. */ "reg1_error_loop: \n"/* If this line is hit then there was an error in a core register value. */
" b reg1_error_loop \n" /* The loop ensures the loop counter stops incrementing. */ " b reg1_error_loop \n"/* The loop ensures the loop counter stops incrementing. */
" nop " " nop "
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* This is a naked function. */ /* This is a naked function. */
static void vRegTest2Task( void *pvParameters ) static void vRegTest2Task( void * pvParameters )
{ {
__asm volatile __asm volatile
( (
" mov r0, #-1 \n" /* Set all the core registers to known values. */ " mov r0, #-1 \n"/* Set all the core registers to known values. */
" mov r1, #1 \n" " mov r1, #1 \n"
" mov r2, #2 \n" " mov r2, #2 \n"
" mov r3, #3 \n" " mov r3, #3 \n"
@ -452,7 +454,7 @@ static void vRegTest2Task( void *pvParameters )
" mov r11, #11 \n" " mov r11, #11 \n"
" mov r12, #12 \n" " mov r12, #12 \n"
" \n" " \n"
" vmov d0, r0, r1 \n" /* Set all the VFP to known values. */ " vmov d0, r0, r1 \n"/* Set all the VFP to known values. */
" vmov d1, r2, r3 \n" " vmov d1, r2, r3 \n"
" vmov d2, r4, r5 \n" " vmov d2, r4, r5 \n"
" vmov d3, r6, r7 \n" " vmov d3, r6, r7 \n"
@ -471,8 +473,8 @@ static void vRegTest2Task( void *pvParameters )
" \n" " \n"
"reg2_loop: \n" "reg2_loop: \n"
" \n" " \n"
" push { r0-r1 } \n" /* Check all the VFP registers still contain the values set above. */ " push { r0-r1 } \n"/* Check all the VFP registers still contain the values set above. */
" vmov r0, r1, d0 \n" /*First save registers that are clobbered by the test. */ " vmov r0, r1, d0 \n"/*First save registers that are clobbered by the test. */
" cmp r0, #-1 \n" " cmp r0, #-1 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #1 \n" " cmp r1, #1 \n"
@ -553,12 +555,12 @@ static void vRegTest2Task( void *pvParameters )
" cmp r1, #7 \n" " cmp r1, #7 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" \n" " \n"
" pop {r0-r1} \n" /* Restore the registers that were clobbered by the test. */ " pop {r0-r1} \n"/* Restore the registers that were clobbered by the test. */
" \n" " \n"
" b reg2_loopf_pass \n" /* VFP register test passed. Jump to the core register test. */ " b reg2_loopf_pass \n"/* VFP register test passed. Jump to the core register test. */
" \n" " \n"
"reg2_error_loopf: \n" "reg2_error_loopf: \n"
" b reg2_error_loopf \n" /* If this line is hit then a VFP register value was found to be incorrect. */ " b reg2_error_loopf \n"/* If this line is hit then a VFP register value was found to be incorrect. */
" \n" " \n"
"reg2_loopf_pass: \n" "reg2_loopf_pass: \n"
" \n" " \n"
@ -589,26 +591,23 @@ static void vRegTest2Task( void *pvParameters )
" cmp r12, #12 \n" " cmp r12, #12 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" \n" " \n"
" push { r0-r1 } \n" /* Increment the loop counter to indicate this test is still functioning correctly. */ " push { r0-r1 } \n"/* Increment the loop counter to indicate this test is still functioning correctly. */
" ldr r0, =ulRegTest2LoopCounter \n" " ldr r0, =ulRegTest2LoopCounter \n"
" ldr r1, [r0] \n" " ldr r1, [r0] \n"
" adds r1, r1, #1 \n" " adds r1, r1, #1 \n"
" str r1, [r0] \n" " str r1, [r0] \n"
" \n" " \n"
" movs r0, #0x01 \n" /* Yield to increase test coverage. */ " movs r0, #0x01 \n"/* Yield to increase test coverage. */
" ldr r1, =0xe000ed04 \n" /*NVIC_INT_CTRL */ " ldr r1, =0xe000ed04 \n"/*NVIC_INT_CTRL */
" lsl r0, r0, #28 \n" /* Shift to PendSV bit */ " lsl r0, r0, #28 \n"/* Shift to PendSV bit */
" str r0, [r1] \n" " str r0, [r1] \n"
" dsb \n" " dsb \n"
" pop { r0-r1 } \n" " pop { r0-r1 } \n"
" \n" " \n"
" b reg2_loop \n" /* Start again. */ " b reg2_loop \n"/* Start again. */
" \n" " \n"
"reg2_error_loop: \n" /* If this line is hit then there was an error in a core register value. */ "reg2_error_loop: \n"/* If this line is hit then there was an error in a core register value. */
" b reg2_error_loop \n" /* This loop ensures the loop counter variable stops incrementing. */ " b reg2_error_loop \n"/* This loop ensures the loop counter variable stops incrementing. */
" nop \n" " nop \n"
); );
} }

View file

@ -57,8 +57,8 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* NOTE: If an IAR build results in an undefined "reference to __write" linker /* NOTE: If an IAR build results in an undefined "reference to __write" linker
error then set the printf formatter project option to "tiny" and the scanf * error then set the printf formatter project option to "tiny" and the scanf
formatter project option to "small". */ * formatter project option to "small". */
/* /*
* Set up the hardware ready to run this demo. * Set up the hardware ready to run this demo.
@ -82,8 +82,8 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The configCREATE_SIMPLE_TICKLESS_DEMO setting is described at the top /* The configCREATE_SIMPLE_TICKLESS_DEMO setting is described at the top
of this file. */ * of this file. */
#if( configCREATE_SIMPLE_TICKLESS_DEMO == 1 ) #if ( configCREATE_SIMPLE_TICKLESS_DEMO == 1 )
{ {
main_blinky(); main_blinky();
} }
@ -99,11 +99,11 @@ int main( void )
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
extern void FPU_enableModule( void ); extern void FPU_enableModule( void );
/* The clocks are not configured here, but inside main_full() and /* The clocks are not configured here, but inside main_full() and
main_blinky() as the full demo uses a fast clock and the blinky demo uses * main_blinky() as the full demo uses a fast clock and the blinky demo uses
a slow clock. */ * a slow clock. */
/* Stop the watchdog timer. */ /* Stop the watchdog timer. */
MAP_WDT_A_holdTimer(); MAP_WDT_A_holdTimer();
@ -121,54 +121,62 @@ extern void FPU_enableModule( void );
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void *malloc( size_t xSize ) void * malloc( size_t xSize )
{ {
/* There should not be a heap defined, so trap any attempts to call /* There should not be a heap defined, so trap any attempts to call
malloc. */ * malloc. */
Interrupt_disableMaster(); Interrupt_disableMaster();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -143,20 +143,20 @@
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The period after which the check timer will expire, in ms, provided no errors /* The period after which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the * have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been /* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/* Set mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY to 1 to create a simple demo. /* Set mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY to 1 to create a simple demo.
Set mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY to 0 to create a much more * Set mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY to 0 to create a much more
comprehensive test application. See the comments at the top of this file, and * comprehensive test application. See the comments at the top of this file, and
the documentation page on the http://www.FreeRTOS.org web site for more * the documentation page on the http://www.FreeRTOS.org web site for more
information. */ * information. */
#define mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY 0 #define mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -182,8 +182,8 @@ static void prvSetupNestedFPUInterruptsTest( void );
* of the FPU registers, as described at the top of this file. The nature of * of the FPU registers, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly file. * these files necessitates that they are written in an assembly file.
*/ */
extern void vRegTest1Task( void *pvParameters ); extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void *pvParameters ); extern void vRegTest2Task( void * pvParameters );
extern void vRegTestClearFlopRegistersToParameterValue( unsigned long ulValue ); extern void vRegTestClearFlopRegistersToParameterValue( unsigned long ulValue );
extern unsigned long ulRegTestCheckFlopRegistersContainParameterValue( unsigned long ulValue ); extern unsigned long ulRegTestCheckFlopRegistersContainParameterValue( unsigned long ulValue );
@ -192,7 +192,7 @@ extern unsigned long ulRegTestCheckFlopRegistersContainParameterValue( unsigned
* to demonstrate how to write interrupt service routines, and how to * to demonstrate how to write interrupt service routines, and how to
* synchronise a task with an interrupt. * synchronise a task with an interrupt.
*/ */
static void prvButtonTestTask( void *pvParameters ); static void prvButtonTestTask( void * pvParameters );
/* /*
* This file can be used to create either a simple LED flasher example, or a * This file can be used to create either a simple LED flasher example, or a
@ -208,65 +208,67 @@ static void prvOptionallyCreateComprehensveTestApplication( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep * register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If * incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */ * a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/* The following variables are used to verify that the interrupt nesting depth /* The following variables are used to verify that the interrupt nesting depth
is as intended. ulFPUInterruptNesting is incremented on entry to an interrupt * is as intended. ulFPUInterruptNesting is incremented on entry to an interrupt
that uses the FPU, and decremented on exit of the same interrupt. * that uses the FPU, and decremented on exit of the same interrupt.
ulMaxFPUInterruptNesting latches the highest value reached by * ulMaxFPUInterruptNesting latches the highest value reached by
ulFPUInterruptNesting. These variables have no other purpose. */ * ulFPUInterruptNesting. These variables have no other purpose. */
volatile unsigned long ulFPUInterruptNesting = 0UL, ulMaxFPUInterruptNesting = 0UL; volatile unsigned long ulFPUInterruptNesting = 0UL, ulMaxFPUInterruptNesting = 0UL;
/* The semaphore used to demonstrate a task being synchronised with an /* The semaphore used to demonstrate a task being synchronised with an
interrupt. */ * interrupt. */
static SemaphoreHandle_t xTestSemaphore = NULL; static SemaphoreHandle_t xTestSemaphore = NULL;
/* The variable that is incremented by the task synchronised with the button /* The variable that is incremented by the task synchronised with the button
interrupt. */ * interrupt. */
volatile unsigned long ulButtonPressCounts = 0UL; volatile unsigned long ulButtonPressCounts = 0UL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main(void) int main( void )
{ {
/* Configure the hardware ready to run the test. */ /* Configure the hardware ready to run the test. */
prvSetupHardware(); prvSetupHardware();
/* Start standard demo/test application flash tasks. See the comments at /* Start standard demo/test application flash tasks. See the comments at
the top of this file. The LED flash tasks are always created. The other * the top of this file. The LED flash tasks are always created. The other
tasks are only created if mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY is set to * tasks are only created if mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY is set to
0 (at the top of this file). See the comments at the top of this file for * 0 (at the top of this file). See the comments at the top of this file for
more information. */ * more information. */
vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY ); vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );
/* The following function will only create more tasks and timers if /* The following function will only create more tasks and timers if
mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY is set to 0 (at the top of this * mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY is set to 0 (at the top of this
file). See the comments at the top of this file for more information. */ * file). See the comments at the top of this file for more information. */
prvOptionallyCreateComprehensveTestApplication(); prvOptionallyCreateComprehensveTestApplication();
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangedTimerPeriodAlready = pdFALSE; static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
long lErrorFound = pdFALSE; long lErrorFound = pdFALSE;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
@ -288,17 +290,17 @@ long lErrorFound = pdFALSE;
lErrorFound = pdTRUE; lErrorFound = pdTRUE;
} }
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
lErrorFound = pdTRUE; lErrorFound = pdTRUE;
} }
if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
lErrorFound = pdTRUE; lErrorFound = pdTRUE;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
lErrorFound = pdTRUE; lErrorFound = pdTRUE;
} }
@ -323,6 +325,7 @@ long lErrorFound = pdFALSE;
{ {
lErrorFound = pdTRUE; lErrorFound = pdTRUE;
} }
ulLastRegTest1Value = ulRegTest1LoopCounter; ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ /* Check that the register test 2 task is still running. */
@ -330,17 +333,18 @@ long lErrorFound = pdFALSE;
{ {
lErrorFound = pdTRUE; lErrorFound = pdTRUE;
} }
ulLastRegTest2Value = ulRegTest2LoopCounter; ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If /* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */ * everything is ok. A faster toggle indicates an error. */
vParTestToggleLED( mainCHECK_LED ); vParTestToggleLED( mainCHECK_LED );
/* Have any errors been latch in lErrorFound? If so, shorten the /* Have any errors been latch in lErrorFound? If so, shorten the
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. * period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
This will result in an increase in the rate at which mainCHECK_LED * This will result in an increase in the rate at which mainCHECK_LED
toggles. */ * toggles. */
if( lErrorFound != pdFALSE ) if( lErrorFound != pdFALSE )
{ {
if( lChangedTimerPeriodAlready == pdFALSE ) if( lChangedTimerPeriodAlready == pdFALSE )
@ -348,28 +352,28 @@ long lErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE; lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time. /* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must * Functions called from inside of a timer callback function must
*never* attempt to block. */ * never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvButtonTestTask( void *pvParameters ) static void prvButtonTestTask( void * pvParameters )
{ {
configASSERT( xTestSemaphore ); configASSERT( xTestSemaphore );
/* This is the task used as an example of how to synchronise a task with /* This is the task used as an example of how to synchronise a task with
an interrupt. Each time the button interrupt gives the semaphore, this task * an interrupt. Each time the button interrupt gives the semaphore, this task
will unblock, increment its execution counter, then return to block * will unblock, increment its execution counter, then return to block
again. */ * again. */
/* Take the semaphore before started to ensure it is in the correct /* Take the semaphore before started to ensure it is in the correct
state. */ * state. */
xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK ); xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );
for( ;; ) for( ; ; )
{ {
xSemaphoreTake( xTestSemaphore, portMAX_DELAY ); xSemaphoreTake( xTestSemaphore, portMAX_DELAY );
ulButtonPressCounts++; ulButtonPressCounts++;
@ -389,8 +393,8 @@ static void prvSetupHardware( void )
vParTestInitialise(); vParTestInitialise();
/* Configure the button input. This configures the interrupt to use the /* Configure the button input. This configures the interrupt to use the
lowest interrupt priority, so it is ok to use the ISR safe FreeRTOS API * lowest interrupt priority, so it is ok to use the ISR safe FreeRTOS API
from the button interrupt handler. */ * from the button interrupt handler. */
STM_EVAL_PBInit( BUTTON_USER, BUTTON_MODE_EXTI ); STM_EVAL_PBInit( BUTTON_USER, BUTTON_MODE_EXTI );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -400,37 +404,37 @@ void vApplicationTickHook( void )
#if ( mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY == 0 ) #if ( mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY == 0 )
{ {
/* Just to verify that the interrupt nesting behaves as expected, /* Just to verify that the interrupt nesting behaves as expected,
increment ulFPUInterruptNesting on entry, and decrement it on exit. */ * increment ulFPUInterruptNesting on entry, and decrement it on exit. */
ulFPUInterruptNesting++; ulFPUInterruptNesting++;
/* Fill the FPU registers with 0. */ /* Fill the FPU registers with 0. */
vRegTestClearFlopRegistersToParameterValue( 0UL ); vRegTestClearFlopRegistersToParameterValue( 0UL );
/* Trigger a timer 2 interrupt, which will fill the registers with a /* Trigger a timer 2 interrupt, which will fill the registers with a
different value and itself trigger a timer 3 interrupt. Note that the * different value and itself trigger a timer 3 interrupt. Note that the
timers are not actually used. The timer 2 and 3 interrupt vectors are * timers are not actually used. The timer 2 and 3 interrupt vectors are
just used for convenience. */ * just used for convenience. */
NVIC_SetPendingIRQ( TIM2_IRQn ); NVIC_SetPendingIRQ( TIM2_IRQn );
/* Ensure that, after returning from the nested interrupts, all the FPU /* Ensure that, after returning from the nested interrupts, all the FPU
registers contain the value to which they were set by the tick hook * registers contain the value to which they were set by the tick hook
function. */ * function. */
configASSERT( ulRegTestCheckFlopRegistersContainParameterValue( 0UL ) ); configASSERT( ulRegTestCheckFlopRegistersContainParameterValue( 0UL ) );
ulFPUInterruptNesting--; ulFPUInterruptNesting--;
} }
#endif #endif /* if ( mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY == 0 ) */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupNestedFPUInterruptsTest( void ) static void prvSetupNestedFPUInterruptsTest( void )
{ {
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM2 interrupt in the NVIC. The timer itself is not used, /* Enable the TIM2 interrupt in the NVIC. The timer itself is not used,
just its interrupt vector to force nesting from software. TIM2 must have * just its interrupt vector to force nesting from software. TIM2 must have
a lower priority than TIM3, and both must have priorities above * a lower priority than TIM3, and both must have priorities above
configMAX_SYSCALL_INTERRUPT_PRIORITY. */ * configMAX_SYSCALL_INTERRUPT_PRIORITY. */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY - 1; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY - 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
@ -438,9 +442,9 @@ NVIC_InitTypeDef NVIC_InitStructure;
NVIC_Init( &NVIC_InitStructure ); NVIC_Init( &NVIC_InitStructure );
/* Enable the TIM3 interrupt in the NVIC. The timer itself is not used, /* Enable the TIM3 interrupt in the NVIC. The timer itself is not used,
just its interrupt vector to force nesting from software. TIM2 must have * just its interrupt vector to force nesting from software. TIM2 must have
a lower priority than TIM3, and both must have priorities above * a lower priority than TIM3, and both must have priorities above
configMAX_SYSCALL_INTERRUPT_PRIORITY. */ * configMAX_SYSCALL_INTERRUPT_PRIORITY. */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY - 2; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY - 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
@ -452,20 +456,20 @@ NVIC_InitTypeDef NVIC_InitStructure;
void TIM3_IRQHandler( void ) void TIM3_IRQHandler( void )
{ {
/* Just to verify that the interrupt nesting behaves as expected, increment /* Just to verify that the interrupt nesting behaves as expected, increment
ulFPUInterruptNesting on entry, and decrement it on exit. */ * ulFPUInterruptNesting on entry, and decrement it on exit. */
ulFPUInterruptNesting++; ulFPUInterruptNesting++;
/* This is the highest priority interrupt in the chain of forced nesting /* This is the highest priority interrupt in the chain of forced nesting
interrupts, so latch the maximum value reached by ulFPUInterruptNesting. * interrupts, so latch the maximum value reached by ulFPUInterruptNesting.
This is done purely to allow verification that the nesting depth reaches * This is done purely to allow verification that the nesting depth reaches
that intended. */ * that intended. */
if( ulFPUInterruptNesting > ulMaxFPUInterruptNesting ) if( ulFPUInterruptNesting > ulMaxFPUInterruptNesting )
{ {
ulMaxFPUInterruptNesting = ulFPUInterruptNesting; ulMaxFPUInterruptNesting = ulFPUInterruptNesting;
} }
/* Fill the FPU registers with 99 to overwrite the values written by /* Fill the FPU registers with 99 to overwrite the values written by
TIM2_IRQHandler(). */ * TIM2_IRQHandler(). */
vRegTestClearFlopRegistersToParameterValue( 99UL ); vRegTestClearFlopRegistersToParameterValue( 99UL );
ulFPUInterruptNesting--; ulFPUInterruptNesting--;
@ -475,19 +479,19 @@ void TIM3_IRQHandler( void )
void TIM2_IRQHandler( void ) void TIM2_IRQHandler( void )
{ {
/* Just to verify that the interrupt nesting behaves as expected, increment /* Just to verify that the interrupt nesting behaves as expected, increment
ulFPUInterruptNesting on entry, and decrement it on exit. */ * ulFPUInterruptNesting on entry, and decrement it on exit. */
ulFPUInterruptNesting++; ulFPUInterruptNesting++;
/* Fill the FPU registers with 1. */ /* Fill the FPU registers with 1. */
vRegTestClearFlopRegistersToParameterValue( 1UL ); vRegTestClearFlopRegistersToParameterValue( 1UL );
/* Trigger a timer 3 interrupt, which will fill the registers with a /* Trigger a timer 3 interrupt, which will fill the registers with a
different value. */ * different value. */
NVIC_SetPendingIRQ( TIM3_IRQn ); NVIC_SetPendingIRQ( TIM3_IRQn );
/* Ensure that, after returning from the nesting interrupt, all the FPU /* Ensure that, after returning from the nesting interrupt, all the FPU
registers contain the value to which they were set by this interrupt * registers contain the value to which they were set by this interrupt
function. */ * function. */
configASSERT( ulRegTestCheckFlopRegistersContainParameterValue( 1UL ) ); configASSERT( ulRegTestCheckFlopRegistersContainParameterValue( 1UL ) );
ulFPUInterruptNesting--; ulFPUInterruptNesting--;
@ -501,7 +505,7 @@ static void prvOptionallyCreateComprehensveTestApplication( void )
TimerHandle_t xCheckTimer = NULL; TimerHandle_t xCheckTimer = NULL;
/* Configure the interrupts used to test FPU registers being used from /* Configure the interrupts used to test FPU registers being used from
nested interrupts. */ * nested interrupts. */
prvSetupNestedFPUInterruptsTest(); prvSetupNestedFPUInterruptsTest();
/* Start all the other standard demo/test tasks. */ /* Start all the other standard demo/test tasks. */
@ -519,19 +523,19 @@ static void prvOptionallyCreateComprehensveTestApplication( void )
vStartMathTasks( mainFLOP_TASK_PRIORITY ); vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* Create the register check tasks, as described at the top of this /* Create the register check tasks, as described at the top of this
file */ * file */
xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the semaphore that is used to demonstrate a task being /* Create the semaphore that is used to demonstrate a task being
synchronised with an interrupt. */ * synchronised with an interrupt. */
vSemaphoreCreateBinary( xTestSemaphore ); vSemaphoreCreateBinary( xTestSemaphore );
/* Create the task that is unblocked by the demonstration interrupt. */ /* Create the task that is unblocked by the demonstration interrupt. */
xTaskCreate( prvButtonTestTask, "BtnTest", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( prvButtonTestTask, "BtnTest", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
@ -545,13 +549,13 @@ static void prvOptionallyCreateComprehensveTestApplication( void )
} }
/* This task has to be created last as it keeps account of the number of /* This task has to be created last as it keeps account of the number of
tasks it expects to see running. */ * tasks it expects to see running. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
} }
#else /* mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY */ #else /* mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY */
{ {
/* Just to prevent compiler warnings when the configuration options are /* Just to prevent compiler warnings when the configuration options are
set such that these static functions are not used. */ * set such that these static functions are not used. */
( void ) vRegTest1Task; ( void ) vRegTest1Task;
( void ) vRegTest2Task; ( void ) vRegTest2Task;
( void ) prvCheckTimerCallback; ( void ) prvCheckTimerCallback;
@ -561,25 +565,25 @@ static void prvOptionallyCreateComprehensveTestApplication( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void EXTI9_5_IRQHandler(void) void EXTI9_5_IRQHandler( void )
{ {
long lHigherPriorityTaskWoken = pdFALSE; long lHigherPriorityTaskWoken = pdFALSE;
/* Only line 6 is enabled, so there is no need to test which line generated /* Only line 6 is enabled, so there is no need to test which line generated
the interrupt. */ * the interrupt. */
EXTI_ClearITPendingBit( EXTI_Line6 ); EXTI_ClearITPendingBit( EXTI_Line6 );
/* This interrupt does nothing more than demonstrate how to synchronise a /* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. First the handler releases a semaphore. * task with an interrupt. First the handler releases a semaphore.
lHigherPriorityTaskWoken has been initialised to zero. */ * lHigherPriorityTaskWoken has been initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* If there was a task that was blocked on the semaphore, and giving the /* If there was a task that was blocked on the semaphore, and giving the
semaphore caused the task to unblock, and the unblocked task has a priority * semaphore caused the task to unblock, and the unblocked task has a priority
higher than the currently executing task (the task that this interrupt * higher than the currently executing task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE. * interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE.
Passing pdTRUE into the following macro call will cause this interrupt to * Passing pdTRUE into the following macro call will cause this interrupt to
return directly to the unblocked, higher priority, task. */ * return directly to the unblocked, higher priority, task. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -587,43 +591,50 @@ long lHigherPriorityTaskWoken = pdFALSE;
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -75,15 +75,15 @@ extern void main_full( void );
int main( void ) int main( void )
{ {
/* See http://www.FreeRTOS.org/TI_CC3220_SimpleLink_FreeRTOS_Demo.html for /* See http://www.FreeRTOS.org/TI_CC3220_SimpleLink_FreeRTOS_Demo.html for
instructions. */ * instructions. */
/* Prepare the hardware to run this demo. */ /* Prepare the hardware to run this demo. */
prvSetupHardware(); prvSetupHardware();
/* The configCREATE_SIMPLE_TICKLESS_DEMO setting is described at the top /* The configCREATE_SIMPLE_TICKLESS_DEMO setting is described at the top
of this file. */ * of this file. */
#if( configCREATE_SIMPLE_TICKLESS_DEMO == 1 ) #if ( configCREATE_SIMPLE_TICKLESS_DEMO == 1 )
{ {
main_blinky(); main_blinky();
} }
@ -108,7 +108,7 @@ static void prvSetupHardware( void )
void vMainToggleLED( void ) void vMainToggleLED( void )
{ {
static uint32_t ulLEDState = Board_GPIO_LED_OFF; static uint32_t ulLEDState = Board_GPIO_LED_OFF;
ulLEDState = !ulLEDState; ulLEDState = !ulLEDState;
GPIO_write( Board_LED0, ulLEDState ); GPIO_write( Board_LED0, ulLEDState );
@ -118,118 +118,134 @@ static uint32_t ulLEDState = Board_GPIO_LED_OFF;
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void *malloc( size_t xSize ) void * malloc( size_t xSize )
{ {
/* There should not be a heap defined, so trap any attempts to call /* There should not be a heap defined, so trap any attempts to call
malloc. */ * malloc. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */ * used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{ {
/* If the buffers to be provided to the Idle task are declared inside this /* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB; static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */ * state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB; *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */ /* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack; *ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory() * application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */ * to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
uint32_t * pulTimerTaskStackSize )
{ {
/* If the buffers to be provided to the Timer task are declared inside this /* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB; static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer /* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */ * task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB; *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */ /* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack; *ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Catch asserts so the file and line number of the assert can be viewed. */ /* Catch asserts so the file and line number of the assert can be viewed. */
void vMainAssertCalled( const char *pcFileName, uint32_t ulLineNumber ) void vMainAssertCalled( const char * pcFileName,
uint32_t ulLineNumber )
{ {
volatile BaseType_t xSetToNonZeroToStepOutOfLoop = 0; volatile BaseType_t xSetToNonZeroToStepOutOfLoop = 0;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
while( xSetToNonZeroToStepOutOfLoop == 0 ) while( xSetToNonZeroToStepOutOfLoop == 0 )
{ {
/* Use the variables to prevent compiler warnings and in an attempt to /* Use the variables to prevent compiler warnings and in an attempt to
ensure they can be viewed in the debugger. If the variables get * ensure they can be viewed in the debugger. If the variables get
optimised away then set copy their values to file scope or globals then * optimised away then set copy their values to file scope or globals then
view the variables they are copied to. */ * view the variables they are copied to. */
( void ) pcFileName; ( void ) pcFileName;
( void ) ulLineNumber; ( void ) ulLineNumber;
} }
@ -237,11 +253,11 @@ volatile BaseType_t xSetToNonZeroToStepOutOfLoop = 0;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* To enable the libraries to build. */ /* To enable the libraries to build. */
void PowerCC32XX_enterLPDS( void *driverlibFunc ) void PowerCC32XX_enterLPDS( void * driverlibFunc )
{ {
( void ) driverlibFunc; ( void ) driverlibFunc;
/* This function is not implemented so trap any calls to it by halting /* This function is not implemented so trap any calls to it by halting
here. */ * here. */
configASSERT( driverlibFunc == NULL ); configASSERT( driverlibFunc == NULL );
} }

View file

@ -57,7 +57,7 @@
#include "board.h" #include "board.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -78,10 +78,11 @@ static void prvSetupHardware( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -92,8 +93,8 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
@ -124,24 +125,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
@ -150,15 +152,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -171,7 +173,7 @@ void vApplicationTickHook( void )
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
@ -186,7 +188,7 @@ void vApplicationTickHook( void )
/* Call the code that 'gives' a task notification from an ISR. */ /* Call the code that 'gives' a task notification from an ISR. */
xNotifyTaskFromISR(); xNotifyTaskFromISR();
} }
#endif #endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -57,7 +57,7 @@
#include "board.h" #include "board.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -78,10 +78,11 @@ static void prvSetupHardware( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -92,8 +93,8 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
@ -124,24 +125,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
@ -150,15 +152,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -171,7 +173,7 @@ void vApplicationTickHook( void )
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
@ -186,7 +188,7 @@ void vApplicationTickHook( void )
/* Call the code that 'gives' a task notification from an ISR. */ /* Call the code that 'gives' a task notification from an ISR. */
xNotifyTaskFromISR(); xNotifyTaskFromISR();
} }
#endif #endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -42,7 +42,7 @@
#include "semphr.h" #include "semphr.h"
/* Standard demo includes - these are needed here as the tick hook function is /* Standard demo includes - these are needed here as the tick hook function is
defined in this file. */ * defined in this file. */
#include "TimerDemo.h" #include "TimerDemo.h"
#include "QueueOverwrite.h" #include "QueueOverwrite.h"
#include "EventGroupsDemo.h" #include "EventGroupsDemo.h"
@ -51,7 +51,7 @@ defined in this file. */
#include "TaskNotify.h" #include "TaskNotify.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -70,17 +70,18 @@ static void prvSystemClockConfig( void );
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
*/ */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
extern void main_blinky( void ); extern void main_blinky( void );
#else #else
extern void main_full( void ); extern void main_full( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -91,8 +92,8 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
@ -108,10 +109,10 @@ int main( void )
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitTypeDef GPIO_InitStruct;
/* Configure Flash prefetch and Instruction cache through ART accelerator. */ /* Configure Flash prefetch and Instruction cache through ART accelerator. */
#if( ART_ACCLERATOR_ENABLE != 0 ) #if ( ART_ACCLERATOR_ENABLE != 0 )
{ {
__HAL_FLASH_ART_ENABLE(); __HAL_FLASH_ART_ENABLE();
} }
@ -127,7 +128,7 @@ GPIO_InitTypeDef GPIO_InitStruct;
prvSystemClockConfig(); prvSystemClockConfig();
/* Enable GPIOB Clock (to be able to program the configuration /* Enable GPIOB Clock (to be able to program the configuration
registers) and configure for LED output. */ * registers) and configure for LED output. */
__GPIOG_CLK_ENABLE(); __GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE();
@ -145,20 +146,20 @@ GPIO_InitTypeDef GPIO_InitStruct;
static void prvSystemClockConfig( void ) static void prvSystemClockConfig( void )
{ {
/* The system Clock is configured as follow : /* The system Clock is configured as follow :
System Clock source = PLL (HSE) * System Clock source = PLL (HSE)
SYSCLK(Hz) = 200000000 * SYSCLK(Hz) = 200000000
HCLK(Hz) = 200000000 * HCLK(Hz) = 200000000
AHB Prescaler = 1 * AHB Prescaler = 1
APB1 Prescaler = 4 * APB1 Prescaler = 4
APB2 Prescaler = 2 * APB2 Prescaler = 2
HSE Frequency(Hz) = 25000000 * HSE Frequency(Hz) = 25000000
PLL_M = 25 * PLL_M = 25
PLL_N = 400 * PLL_N = 400
PLL_P = 2 * PLL_P = 2
PLL_Q = 7 * PLL_Q = 7
VDD(V) = 3.3 * VDD(V) = 3.3
Main regulator output voltage = Scale1 mode * Main regulator output voltage = Scale1 mode
Flash Latency(WS) = 7 */ * Flash Latency(WS) = 7 */
RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct;
@ -172,40 +173,41 @@ static void prvSystemClockConfig( void )
RCC_OscInitStruct.PLL.PLLN = 400; RCC_OscInitStruct.PLL.PLLN = 400;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7; RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct); HAL_RCC_OscConfig( &RCC_OscInitStruct );
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */ * clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.ClockType = ( RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 );
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
configASSERT( HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) == HAL_OK ); configASSERT( HAL_RCC_ClockConfig( &RCC_ClkInitStruct, FLASH_LATENCY_7 ) == HAL_OK );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
@ -214,15 +216,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -230,9 +232,10 @@ volatile size_t xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( uint32_t ulLine, const char *pcFile ) void vAssertCalled( uint32_t ulLine,
const char * pcFile )
{ {
volatile unsigned long ul = 0; volatile unsigned long ul = 0;
( void ) pcFile; ( void ) pcFile;
( void ) ulLine; ( void ) ulLine;
@ -240,7 +243,7 @@ volatile unsigned long ul = 0;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Set ul to a non-zero value using the debugger to step out of this /* Set ul to a non-zero value using the debugger to step out of this
function. */ * function. */
while( ul == 0 ) while( ul == 0 )
{ {
__NOP(); __NOP();
@ -252,10 +255,10 @@ volatile unsigned long ul = 0;
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 )
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
@ -273,9 +276,6 @@ void vApplicationTickHook( void )
/* Use task notifications from an ISR. */ /* Use task notifications from an ISR. */
xNotifyTaskFromISR(); xNotifyTaskFromISR();
} }
#endif #endif /* if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -135,34 +135,34 @@
#include "dynamic.h" #include "dynamic.h"
/* The rate at which data is sent to the queue, specified in milliseconds, and /* The rate at which data is sent to the queue, specified in milliseconds, and
converted to ticks using the portTICK_PERIOD_MS constant. */ * converted to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* The LED toggled by the check timer callback function. This is an LED in the /* The LED toggled by the check timer callback function. This is an LED in the
second digit of the two digit 7 segment display. See the documentation page * second digit of the two digit 7 segment display. See the documentation page
for this demo on the FreeRTOS.org web site to see which LED this relates to. */ * for this demo on the FreeRTOS.org web site to see which LED this relates to. */
#define mainCHECK_LED ( 1UL << 3UL ) #define mainCHECK_LED ( 1UL << 3UL )
/* The LED toggle by the queue receive task. This is an LED in the second digit /* The LED toggle by the queue receive task. This is an LED in the second digit
of the two digit 7 segment display. See the documentation page for this demo on * of the two digit 7 segment display. See the documentation page for this demo on
the FreeRTOS.org web site to see which LED this relates to. */ * the FreeRTOS.org web site to see which LED this relates to. */
#define mainTASK_CONTROLLED_LED 0x07UL #define mainTASK_CONTROLLED_LED 0x07UL
/* The LED turned on by the button interrupt, and turned off by the LED timer. /* The LED turned on by the button interrupt, and turned off by the LED timer.
This is an LED in the second digit of the two digit 7 segment display. See the * This is an LED in the second digit of the two digit 7 segment display. See the
documentation page for this demo on the FreeRTOS.org web site to see which LED * documentation page for this demo on the FreeRTOS.org web site to see which LED
this relates to. */ * this relates to. */
#define mainTIMER_CONTROLLED_LED 0x05UL #define mainTIMER_CONTROLLED_LED 0x05UL
/* The LED used by the comtest tasks. See the comtest.c file for more /* The LED used by the comtest tasks. See the comtest.c file for more
information. The LEDs used by the comtest task are in the second digit of the * information. The LEDs used by the comtest task are in the second digit of the
two digit 7 segment display. See the documentation page for this demo on the * two digit 7 segment display. See the documentation page for this demo on the
FreeRTOS.org web site to see which LEDs this relates to. */ * FreeRTOS.org web site to see which LEDs this relates to. */
#define mainCOM_TEST_LED 0x03UL #define mainCOM_TEST_LED 0x03UL
/* Constant used by the standard timer test functions. */ /* Constant used by the standard timer test functions. */
@ -184,21 +184,21 @@ FreeRTOS.org web site to see which LEDs this relates to. */
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The period at which the check timer will expire, in ms, provided no errors /* The period at which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the * have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been /* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_PERIOD_MS )
/* The period at which the digit counter timer will expire, in ms, and converted /* The period at which the digit counter timer will expire, in ms, and converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainDIGIT_COUNTER_TIMER_PERIOD_MS ( 250UL / portTICK_PERIOD_MS ) #define mainDIGIT_COUNTER_TIMER_PERIOD_MS ( 250UL / portTICK_PERIOD_MS )
/* The LED will remain on until the button has not been pushed for a full /* The LED will remain on until the button has not been pushed for a full
5000ms. */ * 5000ms. */
#define mainLED_TIMER_PERIOD_MS ( 5000UL / portTICK_PERIOD_MS ) #define mainLED_TIMER_PERIOD_MS ( 5000UL / portTICK_PERIOD_MS )
/* A zero block time. */ /* A zero block time. */
@ -218,8 +218,8 @@ static void prvSetupHardware( void );
* The application specific (not common demo) tasks as described in the comments * The application specific (not common demo) tasks as described in the comments
* at the top of this file. * at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* The LED timer callback function. This does nothing but switch an LED off. * The LED timer callback function. This does nothing but switch an LED off.
@ -240,7 +240,8 @@ static void prvDigitCounterTimerCallback( TimerHandle_t xTimer );
* This is not a 'standard' partest function, so the prototype is not in * This is not a 'standard' partest function, so the prototype is not in
* partest.h, and is instead included here. * partest.h, and is instead included here.
*/ */
void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue ); void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED,
signed portBASE_TYPE xValue );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -248,25 +249,25 @@ void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE x
static QueueHandle_t xQueue = NULL; static QueueHandle_t xQueue = NULL;
/* The LED software timer. This uses prvLEDTimerCallback() as it's callback /* The LED software timer. This uses prvLEDTimerCallback() as it's callback
function. */ * function. */
static TimerHandle_t xLEDTimer = NULL; static TimerHandle_t xLEDTimer = NULL;
/* The digit counter software timer. This displays a counting digit on one half /* The digit counter software timer. This displays a counting digit on one half
of the seven segment displays. */ * of the seven segment displays. */
static TimerHandle_t xDigitCounterTimer = NULL; static TimerHandle_t xDigitCounterTimer = NULL;
/* The check timer. This uses prvCheckTimerCallback() as its callback /* The check timer. This uses prvCheckTimerCallback() as its callback
function. */ * function. */
static TimerHandle_t xCheckTimer = NULL; static TimerHandle_t xCheckTimer = NULL;
/* If an error is detected in a standard demo task, then pcStatusMessage will /* If an error is detected in a standard demo task, then pcStatusMessage will
be set to point to a string that identifies the offending task. This is just * be set to point to a string that identifies the offending task. This is just
to make debugging easier. */ * to make debugging easier. */
static const char *pcStatusMessage = NULL; static const char * pcStatusMessage = NULL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main(void) int main( void )
{ {
/* Configure the NVIC, LED outputs and button inputs. */ /* Configure the NVIC, LED outputs and button inputs. */
prvSetupHardware(); prvSetupHardware();
@ -277,22 +278,22 @@ int main(void)
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two application specific demo tasks, as described in the /* Start the two application specific demo tasks, as described in the
comments at the top of this file. */ * comments at the top of this file. */
xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Create the software timer that is responsible for turning off the LED /* Create the software timer that is responsible for turning off the LED
if the button is not pushed within 5000ms, as described at the top of * if the button is not pushed within 5000ms, as described at the top of
this file. */ * this file. */
xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */ xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */
( mainLED_TIMER_PERIOD_MS ),/* The timer period, in this case 5000ms (5s). */ ( mainLED_TIMER_PERIOD_MS ), /* The timer period, in this case 5000ms (5s). */
pdFALSE, /* This is a one-shot timer, so xAutoReload is set to pdFALSE. */ pdFALSE, /* This is a one-shot timer, so xAutoReload is set to pdFALSE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvLEDTimerCallback /* The callback function that switches the LED off. */ prvLEDTimerCallback /* The callback function that switches the LED off. */
); );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
@ -301,7 +302,7 @@ int main(void)
); );
/* Create the software timer that performs the 'digit counting' /* Create the software timer that performs the 'digit counting'
functionality, as described at the top of this file. */ * functionality, as described at the top of this file. */
xDigitCounterTimer = xTimerCreate( "DigitCounter", /* A text name, purely to help debugging. */ xDigitCounterTimer = xTimerCreate( "DigitCounter", /* A text name, purely to help debugging. */
( mainDIGIT_COUNTER_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainDIGIT_COUNTER_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
@ -310,8 +311,8 @@ int main(void)
); );
/* Create a lot of 'standard demo' tasks. Over 40 tasks are created in /* Create a lot of 'standard demo' tasks. Over 40 tasks are created in
this demo. For a much simpler demo, select the 'blinky' build * this demo. For a much simpler demo, select the 'blinky' build
configuration. */ * configuration. */
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
@ -326,9 +327,9 @@ int main(void)
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
/* The suicide tasks must be created last, as they need to know how many /* The suicide tasks must be created last, as they need to know how many
tasks were running prior to their creation in order to ascertain whether * tasks were running prior to their creation in order to ascertain whether
or not the correct/expected number of tasks are running at any given * or not the correct/expected number of tasks are running at any given
time. */ * time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
@ -336,18 +337,20 @@ int main(void)
} }
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
/* Check the standard demo tasks are running without error. Latch the /* Check the standard demo tasks are running without error. Latch the
latest reported error in the pcStatusMessage character pointer. */ * latest reported error in the pcStatusMessage character pointer. */
if( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: GenQueue"; pcStatusMessage = "Error: GenQueue";
@ -409,12 +412,12 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer )
} }
/* Toggle the check LED to give an indication of the system status. If /* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. vParTestToggleLED() * everything is ok. A faster toggle indicates an error. vParTestToggleLED()
is not used to toggle this particular LED as it is on a different IP port * is not used to toggle this particular LED as it is on a different IP port
to to the LEDs controlled by ParTest.c. A critical section is not required * to to the LEDs controlled by ParTest.c. A critical section is not required
as the only other place this port is accessed is from another timer - and * as the only other place this port is accessed is from another timer - and
only one timer can be running at any one time. */ * only one timer can be running at any one time. */
if( ( FM3_GPIO->PDOR3 & mainCHECK_LED ) != 0 ) if( ( FM3_GPIO->PDOR3 & mainCHECK_LED ) != 0 )
{ {
FM3_GPIO->PDOR3 &= ~mainCHECK_LED; FM3_GPIO->PDOR3 &= ~mainCHECK_LED;
@ -425,14 +428,14 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer )
} }
/* Have any errors been latch in pcStatusMessage? If so, shorten the /* Have any errors been latch in pcStatusMessage? If so, shorten the
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. * period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
This will result in an increase in the rate at which mainCHECK_LED * This will result in an increase in the rate at which mainCHECK_LED
toggles. */ * toggles. */
if( pcStatusMessage != NULL ) if( pcStatusMessage != NULL )
{ {
/* This call to xTimerChangePeriod() uses a zero block time. Functions /* This call to xTimerChangePeriod() uses a zero block time. Functions
called from inside of a timer callback function must *never* attempt * called from inside of a timer callback function must *never* attempt
to block. */ * to block. */
xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
} }
} }
@ -441,7 +444,7 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer )
static void prvLEDTimerCallback( TimerHandle_t xTimer ) static void prvLEDTimerCallback( TimerHandle_t xTimer )
{ {
/* The timer has expired - so no button pushes have occurred in the last /* The timer has expired - so no button pushes have occurred in the last
five seconds - turn the LED off. */ * five seconds - turn the LED off. */
vParTestSetLED( mainTIMER_CONTROLLED_LED, pdFALSE ); vParTestSetLED( mainTIMER_CONTROLLED_LED, pdFALSE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -449,14 +452,14 @@ static void prvLEDTimerCallback( TimerHandle_t xTimer )
static void prvDigitCounterTimerCallback( TimerHandle_t xTimer ) static void prvDigitCounterTimerCallback( TimerHandle_t xTimer )
{ {
/* Define the bit patterns that display numbers on the seven segment display. */ /* Define the bit patterns that display numbers on the seven segment display. */
static const unsigned short usNumbersPatterns[] = { 0x8004, 0xF204, 0x4804, 0x6004, 0x3204, 0x2404, 0x0404, 0xF104, 0x0004, 0x2004 }; static const unsigned short usNumbersPatterns[] = { 0x8004, 0xF204, 0x4804, 0x6004, 0x3204, 0x2404, 0x0404, 0xF104, 0x0004, 0x2004 };
static long lCounter = 0L; static long lCounter = 0L;
const long lNumberOfDigits = 10L; const long lNumberOfDigits = 10L;
unsigned short usCheckLEDState; unsigned short usCheckLEDState;
/* Unfortunately the LED uses the same port as the digit counter, so remember /* Unfortunately the LED uses the same port as the digit counter, so remember
the state of the check LED. A critical section is not required to access * the state of the check LED. A critical section is not required to access
the port as only one timer can be executing at any one time. */ * the port as only one timer can be executing at any one time. */
usCheckLEDState = ( FM3_GPIO->PDOR3 & mainCHECK_LED ); usCheckLEDState = ( FM3_GPIO->PDOR3 & mainCHECK_LED );
/* Display the next number, counting up. */ /* Display the next number, counting up. */
@ -476,78 +479,78 @@ unsigned short usCheckLEDState;
/* The ISR executed when the user button is pushed. */ /* The ISR executed when the user button is pushed. */
void INT0_7_Handler( void ) void INT0_7_Handler( void )
{ {
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* The button was pushed, so ensure the LED is on before resetting the /* The button was pushed, so ensure the LED is on before resetting the
LED timer. The LED timer will turn the LED off if the button is not * LED timer. The LED timer will turn the LED off if the button is not
pushed within 5000ms. */ * pushed within 5000ms. */
vParTestSetLEDFromISR( mainTIMER_CONTROLLED_LED, pdTRUE ); vParTestSetLEDFromISR( mainTIMER_CONTROLLED_LED, pdTRUE );
/* This interrupt safe FreeRTOS function can be called from this interrupt /* This interrupt safe FreeRTOS function can be called from this interrupt
because the interrupt priority is below the * because the interrupt priority is below the
configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */ * configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken ); xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken );
/* Clear the interrupt before leaving. This just clears all the interrupts /* Clear the interrupt before leaving. This just clears all the interrupts
for simplicity, as only one is actually used in this simple demo anyway. */ * for simplicity, as only one is actually used in this simple demo anyway. */
FM3_EXTI->EICL = 0x0000; FM3_EXTI->EICL = 0x0000;
/* If calling xTimerResetFromISR() caused a task (in this case the timer /* If calling xTimerResetFromISR() caused a task (in this case the timer
service/daemon task) to unblock, and the unblocked task has a priority * service/daemon task) to unblock, and the unblocked task has a priority
higher than or equal to the task that was interrupted, then * higher than or equal to the task that was interrupted, then
xHigherPriorityTaskWoken will now be set to pdTRUE, and calling * xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */ * portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* The timer command queue will have been filled when the timer test tasks /* The timer command queue will have been filled when the timer test tasks
were created in main() (this is part of the test they perform). Therefore, * were created in main() (this is part of the test they perform). Therefore,
while the check and digit counter timers can be created in main(), they * while the check and digit counter timers can be created in main(), they
cannot be started from main(). Once the scheduler has started, the timer * cannot be started from main(). Once the scheduler has started, the timer
service task will drain the command queue, and now the check and digit * service task will drain the command queue, and now the check and digit
counter timers can be started successfully. */ * counter timers can be started successfully. */
xTimerStart( xCheckTimer, portMAX_DELAY ); xTimerStart( xCheckTimer, portMAX_DELAY );
xTimerStart( xDigitCounterTimer, portMAX_DELAY ); xTimerStart( xDigitCounterTimer, portMAX_DELAY );
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle an LED. 0 is used as the block time so the sending operation * toggle an LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK ); xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
vParTestToggleLED( mainTASK_CONTROLLED_LED ); vParTestToggleLED( mainTASK_CONTROLLED_LED );
@ -558,7 +561,7 @@ unsigned long ulReceivedValue;
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
const unsigned short usButtonInputBit = 0x01U; const unsigned short usButtonInputBit = 0x01U;
SystemInit(); SystemInit();
SystemCoreClockUpdate(); SystemCoreClockUpdate();
@ -591,42 +594,48 @@ const unsigned short usButtonInputBit = 0x01U;
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeStackSpace; volatile size_t xFreeStackSpace;
/* This function is called on each cycle of the idle task. In this case it /* This function is called on each cycle of the idle task. In this case it
does nothing useful, other than report the amount of FreeRTOS heap that * does nothing useful, other than report the amount of FreeRTOS heap that
remains unallocated. */ * remains unallocated. */
xFreeStackSpace = xPortGetFreeHeapSize(); xFreeStackSpace = xPortGetFreeHeapSize();
if( xFreeStackSpace > 100 ) if( xFreeStackSpace > 100 )
{ {
/* By now, the kernel has allocated everything it is going to, so /* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then * if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be * the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */ * reduced accordingly. */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -634,8 +643,7 @@ volatile size_t xFreeStackSpace;
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* Call the periodic timer test, which tests the timer API functions that /* Call the periodic timer test, which tests the timer API functions that
can be called from an ISR. */ * can be called from an ISR. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -88,12 +88,12 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue, specified in milliseconds, and /* The rate at which data is sent to the queue, specified in milliseconds, and
converted to ticks using the portTICK_PERIOD_MS constant. */ * converted to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* The LED toggle by the queue receive task. */ /* The LED toggle by the queue receive task. */
@ -112,8 +112,8 @@ static void prvSetupHardware( void );
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* The LED timer callback function. This does nothing but switch off the * The LED timer callback function. This does nothing but switch off the
@ -127,12 +127,12 @@ static void vLEDTimerCallback( TimerHandle_t xTimer );
static QueueHandle_t xQueue = NULL; static QueueHandle_t xQueue = NULL;
/* The LED software timer. This uses vLEDTimerCallback() as its callback /* The LED software timer. This uses vLEDTimerCallback() as its callback
function. */ * function. */
static TimerHandle_t xLEDTimer = NULL; static TimerHandle_t xLEDTimer = NULL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main(void) int main( void )
{ {
/* Configure the NVIC, LED outputs and button inputs. */ /* Configure the NVIC, LED outputs and button inputs. */
prvSetupHardware(); prvSetupHardware();
@ -143,13 +143,13 @@ int main(void)
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Create the software timer that is responsible for turning off the LED /* Create the software timer that is responsible for turning off the LED
if the button is not pushed within 5000ms, as described at the top of * if the button is not pushed within 5000ms, as described at the top of
this file. */ * this file. */
xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */ xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */
( 5000 / portTICK_PERIOD_MS ), /* The timer period, in this case 5000ms (5s). */ ( 5000 / portTICK_PERIOD_MS ), /* The timer period, in this case 5000ms (5s). */
pdFALSE, /* This is a one-shot timer, so xAutoReload is set to pdFALSE. */ pdFALSE, /* This is a one-shot timer, so xAutoReload is set to pdFALSE. */
@ -162,21 +162,23 @@ int main(void)
} }
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vLEDTimerCallback( TimerHandle_t xTimer ) static void vLEDTimerCallback( TimerHandle_t xTimer )
{ {
/* The timer has expired - so no button pushes have occurred in the last /* The timer has expired - so no button pushes have occurred in the last
five seconds - turn the LED off. NOTE - accessing the LED port should use * five seconds - turn the LED off. NOTE - accessing the LED port should use
a critical section because it is accessed from multiple tasks, and the * a critical section because it is accessed from multiple tasks, and the
button interrupt - in this trivial case, for simplicity, the critical * button interrupt - in this trivial case, for simplicity, the critical
section is omitted. */ * section is omitted. */
FM3_GPIO->PDOR3 |= mainTIMER_CONTROLLED_LED; FM3_GPIO->PDOR3 |= mainTIMER_CONTROLLED_LED;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -184,75 +186,75 @@ static void vLEDTimerCallback( TimerHandle_t xTimer )
/* The ISR executed when the user button is pushed. */ /* The ISR executed when the user button is pushed. */
void INT0_7_Handler( void ) void INT0_7_Handler( void )
{ {
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* The button was pushed, so ensure the LED is on before resetting the /* The button was pushed, so ensure the LED is on before resetting the
LED timer. The LED timer will turn the LED off if the button is not * LED timer. The LED timer will turn the LED off if the button is not
pushed within 5000ms. */ * pushed within 5000ms. */
FM3_GPIO->PDOR3 &= ~mainTIMER_CONTROLLED_LED; FM3_GPIO->PDOR3 &= ~mainTIMER_CONTROLLED_LED;
/* This interrupt safe FreeRTOS function can be called from this interrupt /* This interrupt safe FreeRTOS function can be called from this interrupt
because the interrupt priority is below the * because the interrupt priority is below the
configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */ * configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken ); xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken );
/* Clear the interrupt before leaving. This just clears all the interrupts /* Clear the interrupt before leaving. This just clears all the interrupts
for simplicity, as only one is actually used in this simple demo anyway. */ * for simplicity, as only one is actually used in this simple demo anyway. */
FM3_EXTI->EICL = 0x0000; FM3_EXTI->EICL = 0x0000;
/* If calling xTimerResetFromISR() caused a task (in this case the timer /* If calling xTimerResetFromISR() caused a task (in this case the timer
service/daemon task) to unblock, and the unblocked task has a priority * service/daemon task) to unblock, and the unblocked task has a priority
higher than or equal to the task that was interrupted, then * higher than or equal to the task that was interrupted, then
xHigherPriorityTaskWoken will now be set to pdTRUE, and calling * xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */ * portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle an LED. 0 is used as the block time so the sending operation * toggle an LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0 ); xQueueSend( xQueue, &ulValueToSend, 0 );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
/* NOTE - accessing the LED port should use a critical section /* NOTE - accessing the LED port should use a critical section
because it is accessed from multiple tasks, and the button interrupt * because it is accessed from multiple tasks, and the button interrupt
- in this trivial case, for simplicity, the critical section is * - in this trivial case, for simplicity, the critical section is
omitted. */ * omitted. */
if( ( FM3_GPIO->PDOR3 & mainTASK_CONTROLLED_LED ) != 0 ) if( ( FM3_GPIO->PDOR3 & mainTASK_CONTROLLED_LED ) != 0 )
{ {
FM3_GPIO->PDOR3 &= ~mainTASK_CONTROLLED_LED; FM3_GPIO->PDOR3 &= ~mainTASK_CONTROLLED_LED;
@ -268,7 +270,7 @@ unsigned long ulReceivedValue;
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
const unsigned short usButtonInputBit = 0x01U; const unsigned short usButtonInputBit = 0x01U;
SystemInit(); SystemInit();
SystemCoreClockUpdate(); SystemCoreClockUpdate();
@ -313,54 +315,55 @@ const unsigned short usButtonInputBit = 0x01U;
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* A tick hook is used by the "Full" build configuration. The Full and /* A tick hook is used by the "Full" build configuration. The Full and
blinky build configurations share a FreeRTOSConfig.h header file, so this * blinky build configurations share a FreeRTOSConfig.h header file, so this
simple build configuration also has to define a tick hook - even though it * simple build configuration also has to define a tick hook - even though it
does not actually use it for anything. */ * does not actually use it for anything. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This function is called on each cycle of the idle task. In this case it /* This function is called on each cycle of the idle task. In this case it
does nothing useful, other than report the amount of FreeRTOS heap that * does nothing useful, other than report the amount of FreeRTOS heap that
remains unallocated. */ * remains unallocated. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
if( xFreeHeapSpace > 100 ) if( xFreeHeapSpace > 100 )
{ {
/* By now, the kernel has allocated everything it is going to, so /* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then * if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be * the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */ * reduced accordingly. */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -136,34 +136,34 @@
#include "dynamic.h" #include "dynamic.h"
/* The rate at which data is sent to the queue, specified in milliseconds, and /* The rate at which data is sent to the queue, specified in milliseconds, and
converted to ticks using the portTICK_PERIOD_MS constant. */ * converted to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* The LED toggled by the check timer callback function. This is an LED in the /* The LED toggled by the check timer callback function. This is an LED in the
second digit of the two digit 7 segment display. See the documentation page * second digit of the two digit 7 segment display. See the documentation page
for this demo on the FreeRTOS.org web site to see which LED this relates to. */ * for this demo on the FreeRTOS.org web site to see which LED this relates to. */
#define mainCHECK_LED 0x07UL #define mainCHECK_LED 0x07UL
/* The LED toggle by the queue receive task. This is an LED in the second digit /* The LED toggle by the queue receive task. This is an LED in the second digit
of the two digit 7 segment display. See the documentation page for this demo on * of the two digit 7 segment display. See the documentation page for this demo on
the FreeRTOS.org web site to see which LED this relates to. */ * the FreeRTOS.org web site to see which LED this relates to. */
#define mainTASK_CONTROLLED_LED 0x06UL #define mainTASK_CONTROLLED_LED 0x06UL
/* The LED turned on by the button interrupt, and turned off by the LED timer. /* The LED turned on by the button interrupt, and turned off by the LED timer.
This is an LED in the second digit of the two digit 7 segment display. See the * This is an LED in the second digit of the two digit 7 segment display. See the
documentation page for this demo on the FreeRTOS.org web site to see which LED * documentation page for this demo on the FreeRTOS.org web site to see which LED
this relates to. */ * this relates to. */
#define mainTIMER_CONTROLLED_LED 0x05UL #define mainTIMER_CONTROLLED_LED 0x05UL
/* The LED used by the comtest tasks. See the comtest.c file for more /* The LED used by the comtest tasks. See the comtest.c file for more
information. The LEDs used by the comtest task are in the second digit of the * information. The LEDs used by the comtest task are in the second digit of the
two digit 7 segment display. See the documentation page for this demo on the * two digit 7 segment display. See the documentation page for this demo on the
FreeRTOS.org web site to see which LEDs this relates to. */ * FreeRTOS.org web site to see which LEDs this relates to. */
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
/* Constant used by the standard timer test functions. */ /* Constant used by the standard timer test functions. */
@ -185,21 +185,21 @@ FreeRTOS.org web site to see which LEDs this relates to. */
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The period at which the check timer will expire, in ms, provided no errors /* The period at which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the * have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been /* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_PERIOD_MS )
/* The period at which the digit counter timer will expire, in ms, and converted /* The period at which the digit counter timer will expire, in ms, and converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainDIGIT_COUNTER_TIMER_PERIOD_MS ( 250UL / portTICK_PERIOD_MS ) #define mainDIGIT_COUNTER_TIMER_PERIOD_MS ( 250UL / portTICK_PERIOD_MS )
/* The LED will remain on until the button has not been pushed for a full /* The LED will remain on until the button has not been pushed for a full
5000ms. */ * 5000ms. */
#define mainLED_TIMER_PERIOD_MS ( 5000UL / portTICK_PERIOD_MS ) #define mainLED_TIMER_PERIOD_MS ( 5000UL / portTICK_PERIOD_MS )
/* A zero block time. */ /* A zero block time. */
@ -219,8 +219,8 @@ static void prvSetupHardware( void );
* The application specific (not common demo) tasks as described in the comments * The application specific (not common demo) tasks as described in the comments
* at the top of this file. * at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* The LED timer callback function. This does nothing but switch an LED off. * The LED timer callback function. This does nothing but switch an LED off.
@ -241,7 +241,8 @@ static void prvDigitCounterTimerCallback( TimerHandle_t xTimer );
* This is not a 'standard' partest function, so the prototype is not in * This is not a 'standard' partest function, so the prototype is not in
* partest.h, and is instead included here. * partest.h, and is instead included here.
*/ */
void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue ); void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED,
signed portBASE_TYPE xValue );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -249,25 +250,25 @@ void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE x
static QueueHandle_t xQueue = NULL; static QueueHandle_t xQueue = NULL;
/* The LED software timer. This uses prvLEDTimerCallback() as it's callback /* The LED software timer. This uses prvLEDTimerCallback() as it's callback
function. */ * function. */
static TimerHandle_t xLEDTimer = NULL; static TimerHandle_t xLEDTimer = NULL;
/* The digit counter software timer. This displays a counting digit on one half /* The digit counter software timer. This displays a counting digit on one half
of the seven segment displays. */ * of the seven segment displays. */
static TimerHandle_t xDigitCounterTimer = NULL; static TimerHandle_t xDigitCounterTimer = NULL;
/* The check timer. This uses prvCheckTimerCallback() as its callback /* The check timer. This uses prvCheckTimerCallback() as its callback
function. */ * function. */
static TimerHandle_t xCheckTimer = NULL; static TimerHandle_t xCheckTimer = NULL;
/* If an error is detected in a standard demo task, then pcStatusMessage will /* If an error is detected in a standard demo task, then pcStatusMessage will
be set to point to a string that identifies the offending task. This is just * be set to point to a string that identifies the offending task. This is just
to make debugging easier. */ * to make debugging easier. */
static const char *pcStatusMessage = NULL; static const char * pcStatusMessage = NULL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main(void) int main( void )
{ {
/* Configure the NVIC, LED outputs and button inputs. */ /* Configure the NVIC, LED outputs and button inputs. */
prvSetupHardware(); prvSetupHardware();
@ -278,22 +279,22 @@ int main(void)
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two application specific demo tasks, as described in the /* Start the two application specific demo tasks, as described in the
comments at the top of this file. */ * comments at the top of this file. */
xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Create the software timer that is responsible for turning off the LED /* Create the software timer that is responsible for turning off the LED
if the button is not pushed within 5000ms, as described at the top of * if the button is not pushed within 5000ms, as described at the top of
this file. */ * this file. */
xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */ xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */
( mainLED_TIMER_PERIOD_MS ),/* The timer period, in this case 5000ms (5s). */ ( mainLED_TIMER_PERIOD_MS ), /* The timer period, in this case 5000ms (5s). */
pdFALSE, /* This is a one-shot timer, so xAutoReload is set to pdFALSE. */ pdFALSE, /* This is a one-shot timer, so xAutoReload is set to pdFALSE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvLEDTimerCallback /* The callback function that switches the LED off. */ prvLEDTimerCallback /* The callback function that switches the LED off. */
); );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
@ -302,7 +303,7 @@ int main(void)
); );
/* Create the software timer that performs the 'digit counting' /* Create the software timer that performs the 'digit counting'
functionality, as described at the top of this file. */ * functionality, as described at the top of this file. */
xDigitCounterTimer = xTimerCreate( "DigitCounter", /* A text name, purely to help debugging. */ xDigitCounterTimer = xTimerCreate( "DigitCounter", /* A text name, purely to help debugging. */
( mainDIGIT_COUNTER_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainDIGIT_COUNTER_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
@ -311,8 +312,8 @@ int main(void)
); );
/* Create a lot of 'standard demo' tasks. Over 40 tasks are created in /* Create a lot of 'standard demo' tasks. Over 40 tasks are created in
this demo. For a much simpler demo, select the 'blinky' build * this demo. For a much simpler demo, select the 'blinky' build
configuration. */ * configuration. */
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
@ -327,9 +328,9 @@ int main(void)
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
/* The suicide tasks must be created last, as they need to know how many /* The suicide tasks must be created last, as they need to know how many
tasks were running prior to their creation in order to ascertain whether * tasks were running prior to their creation in order to ascertain whether
or not the correct/expected number of tasks are running at any given * or not the correct/expected number of tasks are running at any given
time. */ * time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
@ -337,18 +338,20 @@ int main(void)
} }
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
/* Check the standard demo tasks are running without error. Latch the /* Check the standard demo tasks are running without error. Latch the
latest reported error in the pcStatusMessage character pointer. */ * latest reported error in the pcStatusMessage character pointer. */
if( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: GenQueue"; pcStatusMessage = "Error: GenQueue";
@ -410,19 +413,19 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer )
} }
/* Toggle the check LED to give an indication of the system status. If /* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */ * everything is ok. A faster toggle indicates an error. */
vParTestToggleLED( mainCHECK_LED ); vParTestToggleLED( mainCHECK_LED );
/* Have any errors been latch in pcStatusMessage? If so, shorten the /* Have any errors been latch in pcStatusMessage? If so, shorten the
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. * period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
This will result in an increase in the rate at which mainCHECK_LED * This will result in an increase in the rate at which mainCHECK_LED
toggles. */ * toggles. */
if( pcStatusMessage != NULL ) if( pcStatusMessage != NULL )
{ {
/* This call to xTimerChangePeriod() uses a zero block time. Functions /* This call to xTimerChangePeriod() uses a zero block time. Functions
called from inside of a timer callback function must *never* attempt * called from inside of a timer callback function must *never* attempt
to block. */ * to block. */
xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
} }
} }
@ -431,7 +434,7 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer )
static void prvLEDTimerCallback( TimerHandle_t xTimer ) static void prvLEDTimerCallback( TimerHandle_t xTimer )
{ {
/* The timer has expired - so no button pushes have occurred in the last /* The timer has expired - so no button pushes have occurred in the last
five seconds - turn the LED off. */ * five seconds - turn the LED off. */
vParTestSetLED( mainTIMER_CONTROLLED_LED, pdFALSE ); vParTestSetLED( mainTIMER_CONTROLLED_LED, pdFALSE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -439,9 +442,9 @@ static void prvLEDTimerCallback( TimerHandle_t xTimer )
static void prvDigitCounterTimerCallback( TimerHandle_t xTimer ) static void prvDigitCounterTimerCallback( TimerHandle_t xTimer )
{ {
/* Define the bit patterns that display numbers on the seven segment display. */ /* Define the bit patterns that display numbers on the seven segment display. */
static const unsigned short usNumbersPatterns[] = { 0xC000U, 0xF900U, 0xA400U, 0xB000U, 0x9900U, 0x9200U, 0x8200U, 0xF800U, 0x8000U, 0x9000U }; static const unsigned short usNumbersPatterns[] = { 0xC000U, 0xF900U, 0xA400U, 0xB000U, 0x9900U, 0x9200U, 0x8200U, 0xF800U, 0x8000U, 0x9000U };
static long lCounter = 0L; static long lCounter = 0L;
const long lNumberOfDigits = 10L; const long lNumberOfDigits = 10L;
/* Display the next number, counting up. */ /* Display the next number, counting up. */
FM3_GPIO->PDOR1 = usNumbersPatterns[ lCounter ]; FM3_GPIO->PDOR1 = usNumbersPatterns[ lCounter ];
@ -460,78 +463,78 @@ const long lNumberOfDigits = 10L;
/* The ISR executed when the user button is pushed. */ /* The ISR executed when the user button is pushed. */
void INT0_7_Handler( void ) void INT0_7_Handler( void )
{ {
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* The button was pushed, so ensure the LED is on before resetting the /* The button was pushed, so ensure the LED is on before resetting the
LED timer. The LED timer will turn the LED off if the button is not * LED timer. The LED timer will turn the LED off if the button is not
pushed within 5000ms. */ * pushed within 5000ms. */
vParTestSetLEDFromISR( mainTIMER_CONTROLLED_LED, pdTRUE ); vParTestSetLEDFromISR( mainTIMER_CONTROLLED_LED, pdTRUE );
/* This interrupt safe FreeRTOS function can be called from this interrupt /* This interrupt safe FreeRTOS function can be called from this interrupt
because the interrupt priority is below the * because the interrupt priority is below the
configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */ * configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken ); xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken );
/* Clear the interrupt before leaving. This just clears all the interrupts /* Clear the interrupt before leaving. This just clears all the interrupts
for simplicity, as only one is actually used in this simple demo anyway. */ * for simplicity, as only one is actually used in this simple demo anyway. */
FM3_EXTI->EICL = 0x0000; FM3_EXTI->EICL = 0x0000;
/* If calling xTimerResetFromISR() caused a task (in this case the timer /* If calling xTimerResetFromISR() caused a task (in this case the timer
service/daemon task) to unblock, and the unblocked task has a priority * service/daemon task) to unblock, and the unblocked task has a priority
higher than or equal to the task that was interrupted, then * higher than or equal to the task that was interrupted, then
xHigherPriorityTaskWoken will now be set to pdTRUE, and calling * xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */ * portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* The timer command queue will have been filled when the timer test tasks /* The timer command queue will have been filled when the timer test tasks
were created in main() (this is part of the test they perform). Therefore, * were created in main() (this is part of the test they perform). Therefore,
while the check and digit counter timers can be created in main(), they * while the check and digit counter timers can be created in main(), they
cannot be started from main(). Once the scheduler has started, the timer * cannot be started from main(). Once the scheduler has started, the timer
service task will drain the command queue, and now the check and digit * service task will drain the command queue, and now the check and digit
counter timers can be started successfully. */ * counter timers can be started successfully. */
xTimerStart( xCheckTimer, portMAX_DELAY ); xTimerStart( xCheckTimer, portMAX_DELAY );
xTimerStart( xDigitCounterTimer, portMAX_DELAY ); xTimerStart( xDigitCounterTimer, portMAX_DELAY );
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle an LED. 0 is used as the block time so the sending operation * toggle an LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK ); xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
vParTestToggleLED( mainTASK_CONTROLLED_LED ); vParTestToggleLED( mainTASK_CONTROLLED_LED );
@ -542,7 +545,7 @@ unsigned long ulReceivedValue;
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
const unsigned short usButtonInputBit = 0x01U; const unsigned short usButtonInputBit = 0x01U;
SystemInit(); SystemInit();
SystemCoreClockUpdate(); SystemCoreClockUpdate();
@ -575,42 +578,48 @@ const unsigned short usButtonInputBit = 0x01U;
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeStackSpace; volatile size_t xFreeStackSpace;
/* This function is called on each cycle of the idle task. In this case it /* This function is called on each cycle of the idle task. In this case it
does nothing useful, other than report the amount of FreeRTOS heap that * does nothing useful, other than report the amount of FreeRTOS heap that
remains unallocated. */ * remains unallocated. */
xFreeStackSpace = xPortGetFreeHeapSize(); xFreeStackSpace = xPortGetFreeHeapSize();
if( xFreeStackSpace > 100 ) if( xFreeStackSpace > 100 )
{ {
/* By now, the kernel has allocated everything it is going to, so /* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then * if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be * the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */ * reduced accordingly. */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -618,8 +627,7 @@ volatile size_t xFreeStackSpace;
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* Call the periodic timer test, which tests the timer API functions that /* Call the periodic timer test, which tests the timer API functions that
can be called from an ISR. */ * can be called from an ISR. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -89,12 +89,12 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue, specified in milliseconds, and /* The rate at which data is sent to the queue, specified in milliseconds, and
converted to ticks using the portTICK_PERIOD_MS constant. */ * converted to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* The LED toggle by the queue receive task. */ /* The LED toggle by the queue receive task. */
@ -113,8 +113,8 @@ static void prvSetupHardware( void );
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* The LED timer callback function. This does nothing but switch off the * The LED timer callback function. This does nothing but switch off the
@ -128,12 +128,12 @@ static void vLEDTimerCallback( TimerHandle_t xTimer );
static QueueHandle_t xQueue = NULL; static QueueHandle_t xQueue = NULL;
/* The LED software timer. This uses vLEDTimerCallback() as its callback /* The LED software timer. This uses vLEDTimerCallback() as its callback
function. */ * function. */
static TimerHandle_t xLEDTimer = NULL; static TimerHandle_t xLEDTimer = NULL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main(void) int main( void )
{ {
/* Configure the NVIC, LED outputs and button inputs. */ /* Configure the NVIC, LED outputs and button inputs. */
prvSetupHardware(); prvSetupHardware();
@ -144,15 +144,15 @@ int main(void)
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Create the software timer that is responsible for turning off the LED /* Create the software timer that is responsible for turning off the LED
if the button is not pushed within 5000ms, as described at the top of * if the button is not pushed within 5000ms, as described at the top of
this file. */ * this file. */
xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */ xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */
( 5000 / portTICK_PERIOD_MS ),/* The timer period, in this case 5000ms (5s). */ ( 5000 / portTICK_PERIOD_MS ), /* The timer period, in this case 5000ms (5s). */
pdFALSE, /* This is a one-shot timer, so xAutoReload is set to pdFALSE. */ pdFALSE, /* This is a one-shot timer, so xAutoReload is set to pdFALSE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
vLEDTimerCallback /* The callback function that switches the LED off. */ vLEDTimerCallback /* The callback function that switches the LED off. */
@ -163,21 +163,23 @@ int main(void)
} }
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vLEDTimerCallback( TimerHandle_t xTimer ) static void vLEDTimerCallback( TimerHandle_t xTimer )
{ {
/* The timer has expired - so no button pushes have occurred in the last /* The timer has expired - so no button pushes have occurred in the last
five seconds - turn the LED off. NOTE - accessing the LED port should use * five seconds - turn the LED off. NOTE - accessing the LED port should use
a critical section because it is accessed from multiple tasks, and the * a critical section because it is accessed from multiple tasks, and the
button interrupt - in this trivial case, for simplicity, the critical * button interrupt - in this trivial case, for simplicity, the critical
section is omitted. */ * section is omitted. */
FM3_GPIO->PDOR1 |= mainTIMER_CONTROLLED_LED; FM3_GPIO->PDOR1 |= mainTIMER_CONTROLLED_LED;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -185,75 +187,75 @@ static void vLEDTimerCallback( TimerHandle_t xTimer )
/* The ISR executed when the user button is pushed. */ /* The ISR executed when the user button is pushed. */
void INT0_7_Handler( void ) void INT0_7_Handler( void )
{ {
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* The button was pushed, so ensure the LED is on before resetting the /* The button was pushed, so ensure the LED is on before resetting the
LED timer. The LED timer will turn the LED off if the button is not * LED timer. The LED timer will turn the LED off if the button is not
pushed within 5000ms. */ * pushed within 5000ms. */
FM3_GPIO->PDOR1 &= ~mainTIMER_CONTROLLED_LED; FM3_GPIO->PDOR1 &= ~mainTIMER_CONTROLLED_LED;
/* This interrupt safe FreeRTOS function can be called from this interrupt /* This interrupt safe FreeRTOS function can be called from this interrupt
because the interrupt priority is below the * because the interrupt priority is below the
configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */ * configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken ); xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken );
/* Clear the interrupt before leaving. This just clears all the interrupts /* Clear the interrupt before leaving. This just clears all the interrupts
for simplicity, as only one is actually used in this simple demo anyway. */ * for simplicity, as only one is actually used in this simple demo anyway. */
FM3_EXTI->EICL = 0x0000; FM3_EXTI->EICL = 0x0000;
/* If calling xTimerResetFromISR() caused a task (in this case the timer /* If calling xTimerResetFromISR() caused a task (in this case the timer
service/daemon task) to unblock, and the unblocked task has a priority * service/daemon task) to unblock, and the unblocked task has a priority
higher than or equal to the task that was interrupted, then * higher than or equal to the task that was interrupted, then
xHigherPriorityTaskWoken will now be set to pdTRUE, and calling * xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */ * portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle an LED. 0 is used as the block time so the sending operation * toggle an LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0 ); xQueueSend( xQueue, &ulValueToSend, 0 );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
/* NOTE - accessing the LED port should use a critical section /* NOTE - accessing the LED port should use a critical section
because it is accessed from multiple tasks, and the button interrupt * because it is accessed from multiple tasks, and the button interrupt
- in this trivial case, for simplicity, the critical section is * - in this trivial case, for simplicity, the critical section is
omitted. */ * omitted. */
if( ( FM3_GPIO->PDOR3 & mainTASK_CONTROLLED_LED ) != 0 ) if( ( FM3_GPIO->PDOR3 & mainTASK_CONTROLLED_LED ) != 0 )
{ {
FM3_GPIO->PDOR3 &= ~mainTASK_CONTROLLED_LED; FM3_GPIO->PDOR3 &= ~mainTASK_CONTROLLED_LED;
@ -269,8 +271,8 @@ unsigned long ulReceivedValue;
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
const unsigned short usButtonInputBit = 0x01U; const unsigned short usButtonInputBit = 0x01U;
const unsigned short usGPIOState = 0xFF00U; const unsigned short usGPIOState = 0xFF00U;
SystemInit(); SystemInit();
SystemCoreClockUpdate(); SystemCoreClockUpdate();
@ -315,54 +317,55 @@ const unsigned short usGPIOState = 0xFF00U;
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* A tick hook is used by the "Full" build configuration. The Full and /* A tick hook is used by the "Full" build configuration. The Full and
blinky build configurations share a FreeRTOSConfig.h header file, so this * blinky build configurations share a FreeRTOSConfig.h header file, so this
simple build configuration also has to define a tick hook - even though it * simple build configuration also has to define a tick hook - even though it
does not actually use it for anything. */ * does not actually use it for anything. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This function is called on each cycle of the idle task. In this case it /* This function is called on each cycle of the idle task. In this case it
does nothing useful, other than report the amount of FreeRTOS heap that * does nothing useful, other than report the amount of FreeRTOS heap that
remains unallocated. */ * remains unallocated. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
if( xFreeHeapSpace > 100 ) if( xFreeHeapSpace > 100 )
{ {
/* By now, the kernel has allocated everything it is going to, so /* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then * if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be * the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */ * reduced accordingly. */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -55,24 +55,24 @@
#include <string.h> #include <string.h>
/* This project provides two demo applications. A simple blinky style demo /* This project provides two demo applications. A simple blinky style demo
application, and a more comprehensive test and demo application. The * application, and a more comprehensive test and demo application. The
mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is used to select between the two. * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is used to select between the two.
*
If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is 1 then the blinky demo will be built. * If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is 1 then the blinky demo will be built.
The blinky demo is implemented and described in main_blinky.c. * The blinky demo is implemented and described in main_blinky.c.
*
If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is not 1 then the comprehensive test and * If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is not 1 then the comprehensive test and
demo application will be built. The comprehensive test and demo application is * demo application will be built. The comprehensive test and demo application is
implemented and described in main_full.c. */ * implemented and described in main_full.c. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/* printf() output uses the UART. These constants define the addresses of the /* printf() output uses the UART. These constants define the addresses of the
required UART registers. */ * required UART registers. */
#define UART0_ADDRESS ( 0x40004000UL ) #define UART0_ADDRESS ( 0x40004000UL )
#define UART0_DATA ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 0UL ) ) ) ) #define UART0_DATA ( *( ( ( volatile uint32_t * ) ( UART0_ADDRESS + 0UL ) ) ) )
#define UART0_STATE ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 4UL ) ) ) ) #define UART0_STATE ( *( ( ( volatile uint32_t * ) ( UART0_ADDRESS + 4UL ) ) ) )
#define UART0_CTRL ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 8UL ) ) ) ) #define UART0_CTRL ( *( ( ( volatile uint32_t * ) ( UART0_ADDRESS + 8UL ) ) ) )
#define UART0_BAUDDIV ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 16UL ) ) ) ) #define UART0_BAUDDIV ( *( ( ( volatile uint32_t * ) ( UART0_ADDRESS + 16UL ) ) ) )
#define TX_BUFFER_MASK ( 1UL ) #define TX_BUFFER_MASK ( 1UL )
/* /*
@ -99,13 +99,13 @@ static void prvUARTInit( void );
void main( void ) void main( void )
{ {
/* See https://www.freertos.org/freertos-on-qemu-mps2-an385-model.html for /* See https://www.freertos.org/freertos-on-qemu-mps2-an385-model.html for
instructions. */ * instructions. */
/* Hardware initialisation. printf() output uses the UART for IO. */ /* Hardware initialisation. printf() output uses the UART for IO. */
prvUARTInit(); prvUARTInit();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
@ -121,59 +121,66 @@ void main( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created using the dynamic allocation (as opposed to * timer or semaphore is created using the dynamic allocation (as opposed to
static allocation) option. It is also called by various parts of the * static allocation) option. It is also called by various parts of the
demo application. If heap_1.c, heap_2.c or heap_4.c is being used, then the * demo application. If heap_1.c, heap_2.c or heap_4.c is being used, then the
size of the heap available to pvPortMalloc() is defined by * size of the heap available to pvPortMalloc() is defined by
configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize() * configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize()
API function can be used to query the size of free heap space that remains * API function can be used to query the size of free heap space that remains
(although it does not provide information on how the remaining heap might be * (although it does not provide information on how the remaining heap might be
fragmented). See http://www.freertos.org/a00111.html for more * fragmented). See http://www.freertos.org/a00111.html for more
information. */ * information. */
printf( "\r\n\r\nMalloc failed\r\n" ); printf( "\r\n\r\nMalloc failed\r\n" );
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If application tasks make use of the * specified, or call vTaskDelay()). If application tasks make use of the
vTaskDelete() API function to delete themselves then it is also important * vTaskDelete() API function to delete themselves then it is also important
that vApplicationIdleHook() is permitted to return to its calling function, * that vApplicationIdleHook() is permitted to return to its calling function,
because it is the responsibility of the idle task to clean up memory * because it is the responsibility of the idle task to clean up memory
allocated by the kernel to any task that has since deleted itself. */ * allocated by the kernel to any task that has since deleted itself. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
printf( "\r\n\r\nStack overflow in %s\r\n", pcTaskName ); printf( "\r\n\r\nStack overflow in %s\r\n", pcTaskName );
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* This function will be called by each tick interrupt if /* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be * configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so * added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API * code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */ * functions can be used (those that end in FromISR()). */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 )
{ {
@ -188,30 +195,31 @@ void vApplicationTickHook( void )
void vApplicationDaemonTaskStartupHook( void ) void vApplicationDaemonTaskStartupHook( void )
{ {
/* This function will be called once only, when the daemon task starts to /* This function will be called once only, when the daemon task starts to
execute (sometimes called the timer task). This is useful if the * execute (sometimes called the timer task). This is useful if the
application includes initialisation code that would benefit from executing * application includes initialisation code that would benefit from executing
after the scheduler has been started. */ * after the scheduler has been started. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( const char *pcFileName, uint32_t ulLine ) void vAssertCalled( const char * pcFileName,
uint32_t ulLine )
{ {
volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0; volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
/* Called if an assertion passed to configASSERT() fails. See /* Called if an assertion passed to configASSERT() fails. See
http://www.freertos.org/a00110.html#configASSERT for more information. */ * http://www.freertos.org/a00110.html#configASSERT for more information. */
printf( "ASSERT! Line %d, file %s\r\n", ( int ) ulLine, pcFileName ); printf( "ASSERT! Line %d, file %s\r\n", ( int ) ulLine, pcFileName );
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* You can step out of this function to debug the assertion by using /* You can step out of this function to debug the assertion by using
the debugger to set ulSetToNonZeroInDebuggerToContinue to a non-zero * the debugger to set ulSetToNonZeroInDebuggerToContinue to a non-zero
value. */ * value. */
while( ulSetToNonZeroInDebuggerToContinue == 0 ) while( ulSetToNonZeroInDebuggerToContinue == 0 )
{ {
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
@ -219,51 +227,55 @@ volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */ * used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{ {
/* If the buffers to be provided to the Idle task are declared inside this /* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB; static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */ * state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB; *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */ /* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack; *ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory() * application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */ * to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
uint32_t * pulTimerTaskStackSize )
{ {
/* If the buffers to be provided to the Timer task are declared inside this /* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB; static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer /* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */ * task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB; *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */ /* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack; *ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -275,7 +287,9 @@ static void prvUARTInit( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int __write( int iFile, char *pcString, int iStringLength ) int __write( int iFile,
char * pcString,
int iStringLength )
{ {
int iNextChar; int iNextChar;
@ -285,7 +299,10 @@ int __write( int iFile, char *pcString, int iStringLength )
/* Output the formatted string to the UART. */ /* Output the formatted string to the UART. */
for( iNextChar = 0; iNextChar < iStringLength; iNextChar++ ) for( iNextChar = 0; iNextChar < iStringLength; iNextChar++ )
{ {
while( ( UART0_STATE & TX_BUFFER_MASK ) != 0 ); while( ( UART0_STATE & TX_BUFFER_MASK ) != 0 )
{
}
UART0_DATA = *pcString; UART0_DATA = *pcString;
pcString++; pcString++;
} }
@ -294,16 +311,17 @@ int __write( int iFile, char *pcString, int iStringLength )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void *malloc( size_t size ) void * malloc( size_t size )
{ {
( void ) size; ( void ) size;
/* This project uses heap_4 so doesn't set up a heap for use by the C /* This project uses heap_4 so doesn't set up a heap for use by the C
library - but something is calling the C library malloc(). See * library - but something is calling the C library malloc(). See
https://freertos.org/a00111.html for more information. */ * https://freertos.org/a00111.html for more information. */
printf( "\r\n\r\nUnexpected call to malloc() - should be usine pvPortMalloc()\r\n" ); printf( "\r\n\r\nUnexpected call to malloc() - should be usine pvPortMalloc()\r\n" );
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }

View file

@ -70,7 +70,7 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The times are converted from /* The rate at which data is sent to the queue. The times are converted from
milliseconds to ticks using the pdMS_TO_TICKS() macro. */ * milliseconds to ticks using the pdMS_TO_TICKS() macro. */
#define mainTASK_SEND_FREQUENCY_MS pdMS_TO_TICKS( 200UL ) #define mainTASK_SEND_FREQUENCY_MS pdMS_TO_TICKS( 200UL )
#define mainTIMER_SEND_FREQUENCY_MS pdMS_TO_TICKS( 2000UL ) #define mainTIMER_SEND_FREQUENCY_MS pdMS_TO_TICKS( 2000UL )
@ -78,7 +78,7 @@ milliseconds to ticks using the pdMS_TO_TICKS() macro. */
#define mainQUEUE_LENGTH ( 2 ) #define mainQUEUE_LENGTH ( 2 )
/* The values sent to the queue receive task from the queue send task and the /* The values sent to the queue receive task from the queue send task and the
queue send software timer respectively. */ * queue send software timer respectively. */
#define mainVALUE_SENT_FROM_TASK ( 100UL ) #define mainVALUE_SENT_FROM_TASK ( 100UL )
#define mainVALUE_SENT_FROM_TIMER ( 200UL ) #define mainVALUE_SENT_FROM_TIMER ( 200UL )
@ -87,8 +87,8 @@ queue send software timer respectively. */
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* The callback function executed when the software timer expires. * The callback function executed when the software timer expires.
@ -108,7 +108,7 @@ static TimerHandle_t xTimer = NULL;
/*** SEE THE COMMENTS AT THE TOP OF THIS FILE ***/ /*** SEE THE COMMENTS AT THE TOP OF THIS FILE ***/
void main_blinky( void ) void main_blinky( void )
{ {
const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS; const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS;
/* Create the queue. */ /* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) ); xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );
@ -116,12 +116,12 @@ const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS;
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
NULL, /* The parameter passed to the task - not used in this simple case. */ NULL, /* The parameter passed to the task - not used in this simple case. */
mainQUEUE_RECEIVE_TASK_PRIORITY,/* The priority assigned to the task. */ mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
NULL ); /* The task handle is not required, so NULL is passed. */ NULL ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
@ -131,7 +131,7 @@ const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS;
xTimerPeriod, /* The period of the software timer in ticks. */ xTimerPeriod, /* The period of the software timer in ticks. */
pdTRUE, /* xAutoReload is set to pdTRUE, so this is an auto-reload timer. */ pdTRUE, /* xAutoReload is set to pdTRUE, so this is an auto-reload timer. */
NULL, /* The timer's ID is not used. */ NULL, /* The timer's ID is not used. */
prvQueueSendTimerCallback );/* The function executed when the timer expires. */ prvQueueSendTimerCallback ); /* The function executed when the timer expires. */
xTimerStart( xTimer, 0 ); /* The scheduler has not started so use a block time of 0. */ xTimerStart( xTimer, 0 ); /* The scheduler has not started so use a block time of 0. */
@ -140,20 +140,22 @@ const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS;
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. NOTE: This demo uses static allocation * FreeRTOS web site for more details. NOTE: This demo uses static allocation
for the idle and timer tasks so this line should never execute. */ * for the idle and timer tasks so this line should never execute. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const TickType_t xBlockTime = mainTASK_SEND_FREQUENCY_MS; const TickType_t xBlockTime = mainTASK_SEND_FREQUENCY_MS;
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK; const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK;
/* Prevent the compiler warning about the unused parameter. */ /* Prevent the compiler warning about the unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
@ -161,18 +163,18 @@ const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, pdMS_TO_TICKS() was used to * The block time is specified in ticks, pdMS_TO_TICKS() was used to
convert a time specified in milliseconds into a time specified in ticks. * convert a time specified in milliseconds into a time specified in ticks.
While in the Blocked state this task will not consume any CPU time. */ * While in the Blocked state this task will not consume any CPU time. */
vTaskDelayUntil( &xNextWakeTime, xBlockTime ); vTaskDelayUntil( &xNextWakeTime, xBlockTime );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
write to the console. 0 is used as the block time so the send operation * write to the console. 0 is used as the block time so the send operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
have at least one space at this point in the code. */ * have at least one space at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
@ -180,44 +182,44 @@ const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK;
static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle ) static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle )
{ {
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TIMER; const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TIMER;
/* This is the software timer callback function. The software timer has a /* This is the software timer callback function. The software timer has a
period of two seconds and is reset each time a key is pressed. This * period of two seconds and is reset each time a key is pressed. This
callback function will execute if the timer expires, which will only happen * callback function will execute if the timer expires, which will only happen
if a key is not pressed for two seconds. */ * if a key is not pressed for two seconds. */
/* Avoid compiler warnings resulting from the unused parameter. */ /* Avoid compiler warnings resulting from the unused parameter. */
( void ) xTimerHandle; ( void ) xTimerHandle;
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
write out a message. This function is called from the timer/daemon task, so * write out a message. This function is called from the timer/daemon task, so
must not block. Hence the block time is set to 0. */ * must not block. Hence the block time is set to 0. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
uint32_t ulReceivedValue; uint32_t ulReceivedValue;
/* Prevent the compiler warning about the unused parameter. */ /* Prevent the compiler warning about the unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. It will not use any CPU time while it is in the * FreeRTOSConfig.h. It will not use any CPU time while it is in the
Blocked state. */ * Blocked state. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it an expected value? */ * is it an expected value? */
if( ulReceivedValue == mainVALUE_SENT_FROM_TASK ) if( ulReceivedValue == mainVALUE_SENT_FROM_TASK )
{ {
/* It is normally not good to call printf() from an embedded system, /* It is normally not good to call printf() from an embedded system,
although it is ok in this simulated case. */ * although it is ok in this simulated case. */
printf( "Message received from task\r\n" ); printf( "Message received from task\r\n" );
} }
else if( ulReceivedValue == mainVALUE_SENT_FROM_TIMER ) else if( ulReceivedValue == mainVALUE_SENT_FROM_TIMER )
@ -231,5 +233,3 @@ uint32_t ulReceivedValue;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -105,15 +105,15 @@
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* Stack sizes are defined relative to configMINIMAL_STACK_SIZE so they scale /* Stack sizes are defined relative to configMINIMAL_STACK_SIZE so they scale
across projects that have that constant set differently - in this case the * across projects that have that constant set differently - in this case the
constant is different depending on the compiler in use. */ * constant is different depending on the compiler in use. */
#define mainMESSAGE_BUFFER_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) ) #define mainMESSAGE_BUFFER_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) )
#define mainCHECK_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) ) #define mainCHECK_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The task that checks the operation of all the other standard demo tasks, as /* The task that checks the operation of all the other standard demo tasks, as
* described at the top of this file. */ * described at the top of this file. */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -145,8 +145,8 @@ void main_full( void )
vStartInterruptSemaphoreTasks(); vStartInterruptSemaphoreTasks();
/* The suicide tasks must be created last as they need to know how many /* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation in order to ascertain whether * tasks were running prior to their creation in order to ascertain whether
or not the correct/expected number of tasks are running at any given time. */ * or not the correct/expected number of tasks are running at any given time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
@ -155,27 +155,29 @@ void main_full( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* If configSUPPORT_STATIC_ALLOCATION was false then execution would only /* If configSUPPORT_STATIC_ALLOCATION was false then execution would only
get here if there was insufficient heap memory to create either the idle or * get here if there was insufficient heap memory to create either the idle or
timer tasks. As static allocation is used execution should never be able * timer tasks. As static allocation is used execution should never be able
to reach here. */ * to reach here. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* See the comments at the top of this file. */ /* See the comments at the top of this file. */
static void prvCheckTask( void *pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
static const char * pcMessage = "PASS"; static const char * pcMessage = "PASS";
const TickType_t xTaskPeriod = pdMS_TO_TICKS( 5000UL ); const TickType_t xTaskPeriod = pdMS_TO_TICKS( 5000UL );
TickType_t xPreviousWakeTime; TickType_t xPreviousWakeTime;
extern uint32_t ulNestCount; extern uint32_t ulNestCount;
/* Avoid warning about unused parameter. */ /* Avoid warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
xPreviousWakeTime = xTaskGetTickCount(); xPreviousWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
vTaskDelayUntil( &xPreviousWakeTime, xTaskPeriod ); vTaskDelayUntil( &xPreviousWakeTime, xTaskPeriod );
@ -188,6 +190,7 @@ extern uint32_t ulNestCount;
{ {
pcMessage = "xAreMessageBufferTasksStillRunning() returned false"; pcMessage = "xAreMessageBufferTasksStillRunning() returned false";
} }
if( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
pcMessage = "xAreGenericQueueTasksStillRunning() returned false"; pcMessage = "xAreGenericQueueTasksStillRunning() returned false";
@ -278,8 +281,8 @@ extern uint32_t ulNestCount;
} }
/* It is normally not good to call printf() from an embedded system, /* It is normally not good to call printf() from an embedded system,
although it is ok in this simulated case. */ * although it is ok in this simulated case. */
printf( "%s : %d (%d)\r\n", pcMessage, (int) xTaskGetTickCount(), ( int ) ulNestCount ); printf( "%s : %d (%d)\r\n", pcMessage, ( int ) xTaskGetTickCount(), ( int ) ulNestCount );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -287,7 +290,7 @@ extern uint32_t ulNestCount;
void vFullDemoTickHookFunction( void ) void vFullDemoTickHookFunction( void )
{ {
/* Write to a queue that is in use as part of the queue set demo to /* Write to a queue that is in use as part of the queue set demo to
demonstrate using queue sets from an ISR. */ * demonstrate using queue sets from an ISR. */
vQueueSetAccessQueueSetFromISR(); vQueueSetAccessQueueSetFromISR();
/* Call the event group ISR tests. */ /* Call the event group ISR tests. */
@ -316,4 +319,3 @@ void vFullDemoTickHookFunction( void )
vInterruptSemaphorePeriodicTest(); vInterruptSemaphorePeriodicTest();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -45,14 +45,14 @@
#include "task.h" #include "task.h"
/* Standard demo includes - just needed for the LED (ParTest) initialisation /* Standard demo includes - just needed for the LED (ParTest) initialisation
function. */ * function. */
#include "partest.h" #include "partest.h"
/* Library includes. */ /* Library includes. */
#include "het.h" #include "het.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -72,14 +72,14 @@ extern void main_full( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* See the documentation page for this demo on the FreeRTOS.org web site for /* See the documentation page for this demo on the FreeRTOS.org web site for
full information - including hardware setup requirements. */ * full information - including hardware setup requirements. */
int main( void ) int main( void )
{ {
/* Prepare the hardware to run this demo. */ /* Prepare the hardware to run this demo. */
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
{ {
main_blinky(); main_blinky();
@ -97,7 +97,7 @@ int main( void )
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Perform any configuration necessary to use the ParTest LED output /* Perform any configuration necessary to use the ParTest LED output
functions. */ * functions. */
vParTestInitialise(); vParTestInitialise();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -105,54 +105,60 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* This function will be called by each tick interrupt if /* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be * configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so * added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API * code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */ * functions can be used (those that end in FromISR()). */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -77,16 +77,16 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
@ -95,8 +95,8 @@ functionality. */
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -119,7 +119,7 @@ void main_blinky( void )
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
@ -134,18 +134,20 @@ void main_blinky( void )
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
@ -153,39 +155,39 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
vParTestToggleLED( 0 ); vParTestToggleLED( 0 );
@ -194,4 +196,3 @@ unsigned long ulReceivedValue;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -131,26 +131,26 @@ static void prvLEDTimerCallback( TimerHandle_t xTimer );
/* /*
* The reg test tasks, as described at the top of this file. * The reg test tasks, as described at the top of this file.
*/ */
extern void vRegTestTask1( void *pvParameters ); extern void vRegTestTask1( void * pvParameters );
extern void vRegTestTask2( void *pvParameters ); extern void vRegTestTask2( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Variables that are incremented on each iteration of the reg test tasks - /* Variables that are incremented on each iteration of the reg test tasks -
provided the tasks have not reported any errors. The check task inspects these * provided the tasks have not reported any errors. The check task inspects these
variables to ensure they are still incrementing as expected. If a variable * variables to ensure they are still incrementing as expected. If a variable
stops incrementing then it is likely that its associate task has stalled. */ * stops incrementing then it is likely that its associate task has stalled. */
volatile unsigned long ulRegTest1Counter = 0, ulRegTest2Counter = 0; volatile unsigned long ulRegTest1Counter = 0, ulRegTest2Counter = 0;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xTimer = NULL; TimerHandle_t xTimer = NULL;
/* Start all the standard demo/test tasks. These have not particular /* Start all the standard demo/test tasks. These have not particular
functionality, but do demonstrate how to use the FreeRTOS API, and test the * functionality, but do demonstrate how to use the FreeRTOS API, and test the
kernel port. */ * kernel port. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
@ -169,7 +169,7 @@ TimerHandle_t xTimer = NULL;
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
@ -183,9 +183,9 @@ TimerHandle_t xTimer = NULL;
} }
/* Create the software timer that performs the 'LED spin' functionality, /* Create the software timer that performs the 'LED spin' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */ xTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */
( mainLED_TIMER_PERIOD_MS ),/* The timer period, in this case 75ms. */ ( mainLED_TIMER_PERIOD_MS ), /* The timer period, in this case 75ms. */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvLEDTimerCallback /* The callback function that toggles the white LEDs. */ prvLEDTimerCallback /* The callback function that toggles the white LEDs. */
@ -197,34 +197,37 @@ TimerHandle_t xTimer = NULL;
} }
/* The set of tasks created by the following function call have to be /* The set of tasks created by the following function call have to be
created last as they keep account of the number of tasks they expect to see * created last as they keep account of the number of tasks they expect to see
running. */ * running. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangeToRedLEDsAlready = pdFALSE; static long lChangeToRedLEDsAlready = pdFALSE;
static unsigned long ulLastRegTest1Counter = 0, ulLastRegTest2Counter = 0; static unsigned long ulLastRegTest1Counter = 0, ulLastRegTest2Counter = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* LEDs are defaulted to use the Green LEDs. The Red LEDs are used if an error /* LEDs are defaulted to use the Green LEDs. The Red LEDs are used if an error
is found. */ * is found. */
static unsigned long ulLED1 = 8, ulLED2 = 11; static unsigned long ulLED1 = 8, ulLED2 = 11;
const unsigned long ulRedLED1 = 6, ulRedLED2 = 9; const unsigned long ulRedLED1 = 6, ulRedLED2 = 9;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
they are all still running, and that none have detected an error. */ * they are all still running, and that none have detected an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -241,17 +244,17 @@ const unsigned long ulRedLED1 = 6, ulRedLED2 = 9;
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
@ -282,7 +285,7 @@ const unsigned long ulRedLED1 = 6, ulRedLED2 = 9;
} }
/* Check the reg test tasks are still cycling. They will stop /* Check the reg test tasks are still cycling. They will stop
incrementing their loop counters if they encounter an error. */ * incrementing their loop counters if they encounter an error. */
if( ulRegTest1Counter == ulLastRegTest1Counter ) if( ulRegTest1Counter == ulLastRegTest1Counter )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
@ -297,13 +300,13 @@ const unsigned long ulRedLED1 = 6, ulRedLED2 = 9;
ulLastRegTest2Counter = ulRegTest2Counter; ulLastRegTest2Counter = ulRegTest2Counter;
/* Toggle the check LEDs to give an indication of the system status. If /* Toggle the check LEDs to give an indication of the system status. If
the green LEDs are toggling, then no errors have been detected. If the red * the green LEDs are toggling, then no errors have been detected. If the red
LEDs are toggling, then an error has been reported in at least one task. */ * LEDs are toggling, then an error has been reported in at least one task. */
vParTestToggleLED( ulLED1 ); vParTestToggleLED( ulLED1 );
vParTestToggleLED( ulLED2 ); vParTestToggleLED( ulLED2 );
/* Have any errors been latch in ulErrorFound? If so, ensure the gree LEDs /* Have any errors been latch in ulErrorFound? If so, ensure the gree LEDs
are off, then switch to using the red LEDs. */ * are off, then switch to using the red LEDs. */
if( ulErrorFound != pdFALSE ) if( ulErrorFound != pdFALSE )
{ {
if( lChangeToRedLEDsAlready == pdFALSE ) if( lChangeToRedLEDsAlready == pdFALSE )
@ -322,8 +325,8 @@ const unsigned long ulRedLED1 = 6, ulRedLED2 = 9;
static void prvLEDTimerCallback( TimerHandle_t xTimer ) static void prvLEDTimerCallback( TimerHandle_t xTimer )
{ {
const unsigned long ulNumWhiteLEDs = 6; const unsigned long ulNumWhiteLEDs = 6;
static unsigned long ulLit1 = 2, ulLit2 = 1; static unsigned long ulLit1 = 2, ulLit2 = 1;
vParTestSetLED( ulLit2, pdFALSE ); vParTestSetLED( ulLit2, pdFALSE );
@ -338,4 +341,3 @@ static unsigned long ulLit1 = 2, ulLit2 = 1;
vParTestSetLED( ulLit1, pdTRUE ); vParTestSetLED( ulLit1, pdTRUE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -86,7 +86,7 @@
/* The time between cycles of the 'check' task - which depends on whether the /* The time between cycles of the 'check' task - which depends on whether the
check task has detected an error or not. */ * check task has detected an error or not. */
#define mainCHECK_DELAY_NO_ERROR ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY_NO_ERROR ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
#define mainCHECK_DELAY_ERROR ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY_ERROR ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
@ -114,25 +114,25 @@ check task has detected an error or not. */
static void prvSetupHardware( void ); static void prvSetupHardware( void );
/* The 'check' task as described at the top of this file. */ /* The 'check' task as described at the top of this file. */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
/* A simple task that echoes all the characters that are received on COM0 /* A simple task that echoes all the characters that are received on COM0
(USART1). */ * (USART1). */
static void prvUSARTEchoTask( void *pvParameters ); static void prvUSARTEchoTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
{ {
#ifdef DEBUG #ifdef DEBUG
debug(); debug();
#endif #endif
/* Set up the clocks and memory interface. */ /* Set up the clocks and memory interface. */
prvSetupHardware(); prvSetupHardware();
/* Start the standard demo tasks. These are just here to exercise the /* Start the standard demo tasks. These are just here to exercise the
kernel port and provide examples of how the FreeRTOS API can be used. */ * kernel port and provide examples of how the FreeRTOS API can be used. */
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY ); vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
@ -151,25 +151,27 @@ int main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle /* Will only get here if there was insufficient memory to create the idle
task. The idle task is created within vTaskStartScheduler(). */ * task. The idle task is created within vTaskStartScheduler(). */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Described at the top of this file. */ /* Described at the top of this file. */
static void prvCheckTask( void *pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
unsigned long ulTicksToWait = mainCHECK_DELAY_NO_ERROR; unsigned long ulTicksToWait = mainCHECK_DELAY_NO_ERROR;
/* Just to remove the compiler warning about the unused parameter. */ /* Just to remove the compiler warning about the unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise the variable used to control our iteration rate prior to /* Initialise the variable used to control our iteration rate prior to
its first use. */ * its first use. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Wait until it is time to run the tests again. */ /* Wait until it is time to run the tests again. */
vTaskDelayUntil( &xLastExecutionTime, ulTicksToWait ); vTaskDelayUntil( &xLastExecutionTime, ulTicksToWait );
@ -178,8 +180,8 @@ unsigned long ulTicksToWait = mainCHECK_DELAY_NO_ERROR;
if( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
/* Reduce the time between cycles of this task - which has the /* Reduce the time between cycles of this task - which has the
effect of increasing the rate at which the 'check' LED toggles to * effect of increasing the rate at which the 'check' LED toggles to
indicate the existence of an error to an observer. */ * indicate the existence of an error to an observer. */
ulTicksToWait = mainCHECK_DELAY_ERROR; ulTicksToWait = mainCHECK_DELAY_ERROR;
} }
else if( xAreQueuePeekTasksStillRunning() != pdTRUE ) else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
@ -209,26 +211,26 @@ unsigned long ulTicksToWait = mainCHECK_DELAY_NO_ERROR;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Described at the top of this file. */ /* Described at the top of this file. */
static void prvUSARTEchoTask( void *pvParameters ) static void prvUSARTEchoTask( void * pvParameters )
{ {
signed char cChar; signed char cChar;
/* String declared static to ensure it does not end up on the stack, no matter /* String declared static to ensure it does not end up on the stack, no matter
what the optimisation level. */ * what the optimisation level. */
static const char *pcLongishString = static const char * pcLongishString =
"ABBA was a Swedish pop music group formed in Stockholm in 1972, consisting of Anni-Frid Frida Lyngstad, " "ABBA was a Swedish pop music group formed in Stockholm in 1972, consisting of Anni-Frid Frida Lyngstad, "
"Bjrn Ulvaeus, Benny Andersson and Agnetha Fltskog. Throughout the band's existence, Fltskog and Ulvaeus " "Bjrn Ulvaeus, Benny Andersson and Agnetha Fltskog. Throughout the band's existence, Fltskog and Ulvaeus "
"were a married couple, as were Lyngstad and Andersson - although both couples later divorced. They became one " "were a married couple, as were Lyngstad and Andersson - although both couples later divorced. They became one "
"of the most commercially successful acts in the history of popular music, and they topped the charts worldwide " "of the most commercially successful acts in the history of popular music, and they topped the charts worldwide "
"from 1972 to 1983. ABBA gained international popularity employing catchy song hooks, simple lyrics, sound " "from 1972 to 1983. ABBA gained international popularity employing catchy song hooks, simple lyrics, sound "
"effects (reverb, phasing) and a Wall of Sound achieved by overdubbing the female singers' voices in multiple " "effects (reverb, phasing) and a Wall of Sound achieved by overdubbing the female singers' voices in multiple "
"harmonies. As their popularity grew, they were sought after to tour Europe, Australia, and North America, drawing " "harmonies. As their popularity grew, they were sought after to tour Europe, Australia, and North America, drawing "
"crowds of ardent fans, notably in Australia. Touring became a contentious issue, being particularly cumbersome for " "crowds of ardent fans, notably in Australia. Touring became a contentious issue, being particularly cumbersome for "
"Fltskog, but they continued to release studio albums to widespread commercial success. At the height of their " "Fltskog, but they continued to release studio albums to widespread commercial success. At the height of their "
"popularity, however, both relationships began suffering strain that led ultimately to the collapse of first the " "popularity, however, both relationships began suffering strain that led ultimately to the collapse of first the "
"Ulvaeus-Fltskog marriage (in 1979) and then of the Andersson-Lyngstad marriage in 1981. In the late 1970s and early " "Ulvaeus-Fltskog marriage (in 1979) and then of the Andersson-Lyngstad marriage in 1981. In the late 1970s and early "
"1980s these relationship changes began manifesting in the group's music, as they produced more thoughtful, " "1980s these relationship changes began manifesting in the group's music, as they produced more thoughtful, "
"introspective lyrics with different compositions."; "introspective lyrics with different compositions.";
/* Just to avoid compiler warnings. */ /* Just to avoid compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
@ -237,10 +239,10 @@ static const char *pcLongishString =
lCOMPortInit( mainCOM0, mainBAUD_RATE ); lCOMPortInit( mainCOM0, mainBAUD_RATE );
/* Try sending out a string all in one go, as a very basic test of the /* Try sending out a string all in one go, as a very basic test of the
lSerialPutString() function. */ * lSerialPutString() function. */
lSerialPutString( mainCOM0, pcLongishString, strlen( pcLongishString ) ); lSerialPutString( mainCOM0, pcLongishString, strlen( pcLongishString ) );
for( ;; ) for( ; ; )
{ {
/* Block to wait for a character to be received on COM0. */ /* Block to wait for a character to be received on COM0. */
xSerialGetChar( mainCOM0, &cChar, portMAX_DELAY ); xSerialGetChar( mainCOM0, &cChar, portMAX_DELAY );
@ -254,13 +256,15 @@ static const char *pcLongishString =
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* RCC system reset(for debug purpose). */ /* RCC system reset(for debug purpose). */
RCC_DeInit (); RCC_DeInit();
/* Enable HSE. */ /* Enable HSE. */
RCC_HSEConfig( RCC_HSE_ON ); RCC_HSEConfig( RCC_HSE_ON );
/* Wait till HSE is ready. */ /* Wait till HSE is ready. */
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); while( RCC_GetFlagStatus( RCC_FLAG_HSERDY ) == RESET )
{
}
/* HCLK = SYSCLK. */ /* HCLK = SYSCLK. */
RCC_HCLKConfig( RCC_SYSCLK_Div1 ); RCC_HCLKConfig( RCC_SYSCLK_Div1 );
@ -275,7 +279,7 @@ static void prvSetupHardware( void )
RCC_ADCCLKConfig( RCC_PCLK2_Div4 ); RCC_ADCCLKConfig( RCC_PCLK2_Div4 );
/* Flash 2 wait state. */ /* Flash 2 wait state. */
*( volatile unsigned long * )0x40022000 = 0x01; *( volatile unsigned long * ) 0x40022000 = 0x01;
/* PLLCLK = 8MHz * 9 = 72 MHz */ /* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_9 ); RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_9 );
@ -284,16 +288,20 @@ static void prvSetupHardware( void )
RCC_PLLCmd( ENABLE ); RCC_PLLCmd( ENABLE );
/* Wait till PLL is ready. */ /* Wait till PLL is ready. */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY ) == RESET )
{
}
/* Select PLL as system clock source. */ /* Select PLL as system clock source. */
RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK); RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );
/* Wait till PLL is used as system clock source. */ /* Wait till PLL is used as system clock source. */
while (RCC_GetSYSCLKSource() != 0x08); while( RCC_GetSYSCLKSource() != 0x08 )
{
}
/* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */ /* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
| RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE ); | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE );
/* Set the Vector Table base address at 0x08000000. */ /* Set the Vector Table base address at 0x08000000. */
@ -312,24 +320,29 @@ static void prvSetupHardware( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
/* This function will get called if a task overflows its stack. If the /* This function will get called if a task overflows its stack. If the
parameters are corrupt then inspect pxCurrentTCB to find which was the * parameters are corrupt then inspect pxCurrentTCB to find which was the
offending task. */ * offending task. */
( void ) pxTask; ( void ) pxTask;
( void ) pcTaskName; ( void ) pcTaskName;
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void assert_failed( unsigned char *pucFile, unsigned long ulLine ) void assert_failed( unsigned char * pucFile,
unsigned long ulLine )
{ {
( void ) pucFile; ( void ) pucFile;
( void ) ulLine; ( void ) ulLine;
for( ;; ); for( ; ; )
{
}
} }

View file

@ -98,7 +98,7 @@
#define mainCOLUMN_INCREMENT ( 16 ) #define mainCOLUMN_INCREMENT ( 16 )
/* The maximum number of message that can be waiting for display at any one /* The maximum number of message that can be waiting for display at any one
time. */ * time. */
#define mainLCD_QUEUE_SIZE ( 3 ) #define mainLCD_QUEUE_SIZE ( 3 )
/* The check task uses the sprintf function so requires a little more stack. */ /* The check task uses the sprintf function so requires a little more stack. */
@ -117,7 +117,7 @@ time. */
#define mainCOM_TEST_BAUD_RATE ( 115200 ) #define mainCOM_TEST_BAUD_RATE ( 115200 )
/* The LED used by the comtest tasks. See the comtest.c file for more /* The LED used by the comtest tasks. See the comtest.c file for more
information. */ * information. */
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -138,12 +138,13 @@ static void prvConfigureLCD( void );
* access the LCD directly. Other tasks wanting to display a message send * access the LCD directly. Other tasks wanting to display a message send
* the message to the gatekeeper. * the message to the gatekeeper.
*/ */
static void vLCDTask( void *pvParameters ); static void vLCDTask( void * pvParameters );
/* /*
* Retargets the C library printf function to the USART. * Retargets the C library printf function to the USART.
*/ */
int fputc( int ch, FILE *f ); int fputc( int ch,
FILE * f );
/* /*
* Checks the status of all the demo tasks then prints a message to the * Checks the status of all the demo tasks then prints a message to the
@ -155,7 +156,7 @@ int fputc( int ch, FILE *f );
* Messages are not written directly to the terminal, but passed to vLCDTask * Messages are not written directly to the terminal, but passed to vLCDTask
* via a queue. * via a queue.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* Configures the timers and interrupts for the fast interrupt test as * Configures the timers and interrupts for the fast interrupt test as
@ -172,14 +173,14 @@ QueueHandle_t xLCDQueue;
int main( void ) int main( void )
{ {
#ifdef DEBUG #ifdef DEBUG
debug(); debug();
#endif #endif
prvSetupHardware(); prvSetupHardware();
/* Create the queue used by the LCD task. Messages for display on the LCD /* Create the queue used by the LCD task. Messages for display on the LCD
are received via this queue. */ * are received via this queue. */
xLCDQueue = xQueueCreate( mainLCD_QUEUE_SIZE, sizeof( xLCDMessage ) ); xLCDQueue = xQueueCreate( mainLCD_QUEUE_SIZE, sizeof( xLCDMessage ) );
/* Start the standard demo tasks. */ /* Start the standard demo tasks. */
@ -196,8 +197,8 @@ int main( void )
xTaskCreate( vLCDTask, "LCD", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vLCDTask, "LCD", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
/* The suicide tasks must be created last as they need to know how many /* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation in order to ascertain whether * tasks were running prior to their creation in order to ascertain whether
or not the correct/expected number of tasks are running at any given time. */ * or not the correct/expected number of tasks are running at any given time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Configure the timers used by the fast interrupt timer test. */ /* Configure the timers used by the fast interrupt timer test. */
@ -207,23 +208,25 @@ int main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was not enough heap space to create the /* Will only get here if there was not enough heap space to create the
idle task. */ * idle task. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vLCDTask( void *pvParameters ) void vLCDTask( void * pvParameters )
{ {
xLCDMessage xMessage; xLCDMessage xMessage;
/* Initialise the LCD and display a startup message. */ /* Initialise the LCD and display a startup message. */
prvConfigureLCD(); prvConfigureLCD();
LCD_DrawMonoPict( ( unsigned long * ) pcBitmap ); LCD_DrawMonoPict( ( unsigned long * ) pcBitmap );
for( ;; ) for( ; ; )
{ {
/* Wait for a message to arrive that requires displaying. */ /* Wait for a message to arrive that requires displaying. */
while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS ); while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS )
{
}
/* Display the message. Print each message to a different position. */ /* Display the message. Print each message to a different position. */
printf( ( char const * ) xMessage.pcMessage ); printf( ( char const * ) xMessage.pcMessage );
@ -231,17 +234,17 @@ xLCDMessage xMessage;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
xLCDMessage xMessage; xLCDMessage xMessage;
static signed char cPassMessage[ mainMAX_MSG_LEN ]; static signed char cPassMessage[ mainMAX_MSG_LEN ];
extern unsigned short usMaxJitter; extern unsigned short usMaxJitter;
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
xMessage.pcMessage = cPassMessage; xMessage.pcMessage = cPassMessage;
for( ;; ) for( ; ; )
{ {
/* Perform this check every mainCHECK_DELAY milliseconds. */ /* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
@ -319,7 +322,7 @@ static void prvSetupHardware( void )
RCC_PLLCmd( ENABLE ); RCC_PLLCmd( ENABLE );
/* Wait till PLL is ready. */ /* Wait till PLL is ready. */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY ) == RESET )
{ {
} }
@ -332,7 +335,7 @@ static void prvSetupHardware( void )
} }
/* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */ /* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
| RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE ); | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE );
/* SPI2 Periph clock enable */ /* SPI2 Periph clock enable */
@ -353,7 +356,7 @@ static void prvSetupHardware( void )
static void prvConfigureLCD( void ) static void prvConfigureLCD( void )
{ {
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
/* Configure LCD Back Light (PA8) as output push-pull */ /* Configure LCD Back Light (PA8) as output push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
@ -362,7 +365,7 @@ GPIO_InitTypeDef GPIO_InitStructure;
GPIO_Init( GPIOA, &GPIO_InitStructure ); GPIO_Init( GPIOA, &GPIO_InitStructure );
/* Set the Backlight Pin */ /* Set the Backlight Pin */
GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET); GPIO_WriteBit( GPIOA, GPIO_Pin_8, Bit_SET );
/* Initialize the LCD */ /* Initialize the LCD */
LCD_Init(); LCD_Init();
@ -377,10 +380,11 @@ GPIO_InitTypeDef GPIO_InitStructure;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int fputc( int ch, FILE *f ) int fputc( int ch,
FILE * f )
{ {
static unsigned short usColumn = 0, usRefColumn = mainCOLUMN_START; static unsigned short usColumn = 0, usRefColumn = mainCOLUMN_START;
static unsigned char ucLine = 0; static unsigned char ucLine = 0;
if( ( usColumn == 0 ) && ( ucLine == 0 ) ) if( ( usColumn == 0 ) && ( ucLine == 0 ) )
{ {
@ -390,13 +394,14 @@ static unsigned char ucLine = 0;
if( ch != '\n' ) if( ch != '\n' )
{ {
/* Display one character on LCD */ /* Display one character on LCD */
LCD_DisplayChar( ucLine, usRefColumn, (u8) ch ); LCD_DisplayChar( ucLine, usRefColumn, ( u8 ) ch );
/* Decrement the column position by 16 */ /* Decrement the column position by 16 */
usRefColumn -= mainCOLUMN_INCREMENT; usRefColumn -= mainCOLUMN_INCREMENT;
/* Increment the character counter */ /* Increment the character counter */
usColumn++; usColumn++;
if( usColumn == mainMAX_COLUMN ) if( usColumn == mainMAX_COLUMN )
{ {
ucLine += mainROW_INCREMENT; ucLine += mainROW_INCREMENT;
@ -424,10 +429,11 @@ static unsigned char ucLine = 0;
#ifdef DEBUG #ifdef DEBUG
/* Keep the linker happy. */ /* Keep the linker happy. */
void assert_failed( unsigned char* pcFile, unsigned long ulLine ) void assert_failed( unsigned char * pcFile,
{ unsigned long ulLine )
for( ;; ) {
for( ; ; )
{ {
} }
} }
#endif #endif

View file

@ -98,7 +98,7 @@
#define mainCOLUMN_INCREMENT ( 16 ) #define mainCOLUMN_INCREMENT ( 16 )
/* The maximum number of message that can be waiting for display at any one /* The maximum number of message that can be waiting for display at any one
time. */ * time. */
#define mainLCD_QUEUE_SIZE ( 3 ) #define mainLCD_QUEUE_SIZE ( 3 )
/* The check task uses the sprintf function so requires a little more stack. */ /* The check task uses the sprintf function so requires a little more stack. */
@ -117,7 +117,7 @@ time. */
#define mainCOM_TEST_BAUD_RATE ( 115200 ) #define mainCOM_TEST_BAUD_RATE ( 115200 )
/* The LED used by the comtest tasks. See the comtest.c file for more /* The LED used by the comtest tasks. See the comtest.c file for more
information. */ * information. */
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -138,12 +138,13 @@ static void prvConfigureLCD( void );
* access the LCD directly. Other tasks wanting to display a message send * access the LCD directly. Other tasks wanting to display a message send
* the message to the gatekeeper. * the message to the gatekeeper.
*/ */
static void vLCDTask( void *pvParameters ); static void vLCDTask( void * pvParameters );
/* /*
* Retargets the C library printf function to the USART. * Retargets the C library printf function to the USART.
*/ */
int fputc( int ch, FILE *f ); int fputc( int ch,
FILE * f );
/* /*
* Checks the status of all the demo tasks then prints a message to the * Checks the status of all the demo tasks then prints a message to the
@ -155,7 +156,7 @@ int fputc( int ch, FILE *f );
* Messages are not written directly to the terminal, but passed to vLCDTask * Messages are not written directly to the terminal, but passed to vLCDTask
* via a queue. * via a queue.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* Configures the timers and interrupts for the fast interrupt test as * Configures the timers and interrupts for the fast interrupt test as
@ -172,14 +173,14 @@ QueueHandle_t xLCDQueue;
int main( void ) int main( void )
{ {
#ifdef DEBUG #ifdef DEBUG
debug(); debug();
#endif #endif
prvSetupHardware(); prvSetupHardware();
/* Create the queue used by the LCD task. Messages for display on the LCD /* Create the queue used by the LCD task. Messages for display on the LCD
are received via this queue. */ * are received via this queue. */
xLCDQueue = xQueueCreate( mainLCD_QUEUE_SIZE, sizeof( xLCDMessage ) ); xLCDQueue = xQueueCreate( mainLCD_QUEUE_SIZE, sizeof( xLCDMessage ) );
/* Start the standard demo tasks. */ /* Start the standard demo tasks. */
@ -196,8 +197,8 @@ int main( void )
xTaskCreate( vLCDTask, "LCD", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vLCDTask, "LCD", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
/* The suicide tasks must be created last as they need to know how many /* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation in order to ascertain whether * tasks were running prior to their creation in order to ascertain whether
or not the correct/expected number of tasks are running at any given time. */ * or not the correct/expected number of tasks are running at any given time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Configure the timers used by the fast interrupt timer test. */ /* Configure the timers used by the fast interrupt timer test. */
@ -207,23 +208,25 @@ int main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was not enough heap space to create the /* Will only get here if there was not enough heap space to create the
idle task. */ * idle task. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vLCDTask( void *pvParameters ) void vLCDTask( void * pvParameters )
{ {
xLCDMessage xMessage; xLCDMessage xMessage;
/* Initialise the LCD and display a startup message. */ /* Initialise the LCD and display a startup message. */
prvConfigureLCD(); prvConfigureLCD();
LCD_DrawMonoPict( ( unsigned long * ) pcBitmap ); LCD_DrawMonoPict( ( unsigned long * ) pcBitmap );
for( ;; ) for( ; ; )
{ {
/* Wait for a message to arrive that requires displaying. */ /* Wait for a message to arrive that requires displaying. */
while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS ); while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS )
{
}
/* Display the message. Print each message to a different position. */ /* Display the message. Print each message to a different position. */
printf( ( char const * ) xMessage.pcMessage ); printf( ( char const * ) xMessage.pcMessage );
@ -231,17 +234,17 @@ xLCDMessage xMessage;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
xLCDMessage xMessage; xLCDMessage xMessage;
static signed char cPassMessage[ mainMAX_MSG_LEN ]; static signed char cPassMessage[ mainMAX_MSG_LEN ];
extern unsigned short usMaxJitter; extern unsigned short usMaxJitter;
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
xMessage.pcMessage = cPassMessage; xMessage.pcMessage = cPassMessage;
for( ;; ) for( ; ; )
{ {
/* Perform this check every mainCHECK_DELAY milliseconds. */ /* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
@ -319,7 +322,7 @@ static void prvSetupHardware( void )
RCC_PLLCmd( ENABLE ); RCC_PLLCmd( ENABLE );
/* Wait till PLL is ready. */ /* Wait till PLL is ready. */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY ) == RESET )
{ {
} }
@ -332,7 +335,7 @@ static void prvSetupHardware( void )
} }
/* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */ /* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
| RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE ); | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE );
/* SPI2 Periph clock enable */ /* SPI2 Periph clock enable */
@ -353,7 +356,7 @@ static void prvSetupHardware( void )
static void prvConfigureLCD( void ) static void prvConfigureLCD( void )
{ {
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
/* Configure LCD Back Light (PA8) as output push-pull */ /* Configure LCD Back Light (PA8) as output push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
@ -362,7 +365,7 @@ GPIO_InitTypeDef GPIO_InitStructure;
GPIO_Init( GPIOA, &GPIO_InitStructure ); GPIO_Init( GPIOA, &GPIO_InitStructure );
/* Set the Backlight Pin */ /* Set the Backlight Pin */
GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET); GPIO_WriteBit( GPIOA, GPIO_Pin_8, Bit_SET );
/* Initialize the LCD */ /* Initialize the LCD */
LCD_Init(); LCD_Init();
@ -377,10 +380,11 @@ GPIO_InitTypeDef GPIO_InitStructure;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int fputc( int ch, FILE *f ) int fputc( int ch,
FILE * f )
{ {
static unsigned short usColumn = 0, usRefColumn = mainCOLUMN_START; static unsigned short usColumn = 0, usRefColumn = mainCOLUMN_START;
static unsigned char ucLine = 0; static unsigned char ucLine = 0;
if( ( usColumn == 0 ) && ( ucLine == 0 ) ) if( ( usColumn == 0 ) && ( ucLine == 0 ) )
{ {
@ -390,13 +394,14 @@ static unsigned char ucLine = 0;
if( ch != '\n' ) if( ch != '\n' )
{ {
/* Display one character on LCD */ /* Display one character on LCD */
LCD_DisplayChar( ucLine, usRefColumn, (u8) ch ); LCD_DisplayChar( ucLine, usRefColumn, ( u8 ) ch );
/* Decrement the column position by 16 */ /* Decrement the column position by 16 */
usRefColumn -= mainCOLUMN_INCREMENT; usRefColumn -= mainCOLUMN_INCREMENT;
/* Increment the character counter */ /* Increment the character counter */
usColumn++; usColumn++;
if( usColumn == mainMAX_COLUMN ) if( usColumn == mainMAX_COLUMN )
{ {
ucLine += mainROW_INCREMENT; ucLine += mainROW_INCREMENT;
@ -424,10 +429,11 @@ static unsigned char ucLine = 0;
#ifdef DEBUG #ifdef DEBUG
/* Keep the linker happy. */ /* Keep the linker happy. */
void assert_failed( unsigned char* pcFile, unsigned long ulLine ) void assert_failed( unsigned char * pcFile,
{ unsigned long ulLine )
for( ;; ) {
for( ; ; )
{ {
} }
} }
#endif #endif

View file

@ -64,7 +64,7 @@
*/ */
/* CircleOS includes. Some of the CircleOS peripheral functionality is /* CircleOS includes. Some of the CircleOS peripheral functionality is
utilised, although CircleOS itself is not used. */ * utilised, although CircleOS itself is not used. */
#include "circle.h" #include "circle.h"
/* Standard includes. */ /* Standard includes. */
@ -83,9 +83,9 @@ utilised, although CircleOS itself is not used. */
#include "QPeek.h" #include "QPeek.h"
/* The bitmap used to display the FreeRTOS.org logo is stored in 16bit format /* The bitmap used to display the FreeRTOS.org logo is stored in 16bit format
and therefore takes up a large proportion of the Flash space. Setting this * and therefore takes up a large proportion of the Flash space. Setting this
parameter to 0 excludes the bitmap from the build, freeing up Flash space for * parameter to 0 excludes the bitmap from the build, freeing up Flash space for
extra code. */ * extra code. */
#define mainINCLUDE_BITMAP 0 #define mainINCLUDE_BITMAP 0
#if mainINCLUDE_BITMAP == 1 #if mainINCLUDE_BITMAP == 1
@ -111,14 +111,14 @@ extra code. */
#define mainLCD_MAX_Y ( 110 ) #define mainLCD_MAX_Y ( 110 )
/* The maximum number of message that can be waiting for display at any one /* The maximum number of message that can be waiting for display at any one
time. */ * time. */
#define mainLCD_QUEUE_SIZE ( 3 ) #define mainLCD_QUEUE_SIZE ( 3 )
/* The check task uses the sprintf function so requires a little more stack. */ /* The check task uses the sprintf function so requires a little more stack. */
#define mainCHECK_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 50 ) #define mainCHECK_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 50 )
/* The LCD task calls some of the CircleOS functions (for MEMS and LCD access), /* The LCD task calls some of the CircleOS functions (for MEMS and LCD access),
these can require a larger stack. */ * these can require a larger stack. */
#define configLCD_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 50 ) #define configLCD_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 50 )
/* Dimensions the buffer into which the jitter time is written. */ /* Dimensions the buffer into which the jitter time is written. */
@ -144,7 +144,7 @@ these can require a larger stack. */
typedef struct typedef struct
{ {
portBASE_TYPE xMessageType; portBASE_TYPE xMessageType;
signed char *pcMessage; signed char * pcMessage;
} xLCDMessage; } xLCDMessage;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -160,7 +160,7 @@ static void prvSetupHardware( void );
* access the LCD directly. Other tasks wanting to display a message send * access the LCD directly. Other tasks wanting to display a message send
* the message to the gatekeeper. * the message to the gatekeeper.
*/ */
static void prvLCDTask( void *pvParameters ); static void prvLCDTask( void * pvParameters );
/* /*
* Checks the status of all the demo tasks then prints a message to the * Checks the status of all the demo tasks then prints a message to the
@ -175,7 +175,7 @@ static void prvLCDTask( void *pvParameters );
* The check task also receives instructions to update the MEMS input, which * The check task also receives instructions to update the MEMS input, which
* in turn can also lead to the LCD being updated. * in turn can also lead to the LCD being updated.
*/ */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
/* /*
* Configures the timers and interrupts for the fast interrupt test as * Configures the timers and interrupts for the fast interrupt test as
@ -187,12 +187,14 @@ extern void vSetupTimerTest( void );
* A cut down version of sprintf() used to percent the HUGE GCC library * A cut down version of sprintf() used to percent the HUGE GCC library
* equivalent from being included in the binary image. * equivalent from being included in the binary image.
*/ */
extern int sprintf(char *out, const char *format, ...); extern int sprintf( char * out,
const char * format,
... );
/* /*
* Simple toggle the LED periodically for timing verification. * Simple toggle the LED periodically for timing verification.
*/ */
static void prvFlashTask( void *pvParameters ); static void prvFlashTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -210,7 +212,7 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* Create the queue used by the LCD task. Messages for display on the LCD /* Create the queue used by the LCD task. Messages for display on the LCD
are received via this queue. */ * are received via this queue. */
xLCDQueue = xQueueCreate( mainLCD_QUEUE_SIZE, sizeof( xLCDMessage ) ); xLCDQueue = xQueueCreate( mainLCD_QUEUE_SIZE, sizeof( xLCDMessage ) );
/* Start the standard demo tasks. */ /* Start the standard demo tasks. */
@ -232,17 +234,17 @@ int main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was not enough heap space to create the /* Will only get here if there was not enough heap space to create the
idle task. */ * idle task. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void prvLCDTask( void *pvParameters ) void prvLCDTask( void * pvParameters )
{ {
xLCDMessage xMessage; xLCDMessage xMessage;
char cY = mainLCD_CHAR_HEIGHT; char cY = mainLCD_CHAR_HEIGHT;
const char * const pcString = "www.FreeRTOS.org"; const char * const pcString = "www.FreeRTOS.org";
const char * const pcBlankLine = " "; const char * const pcBlankLine = " ";
DRAW_Init(); DRAW_Init();
@ -255,10 +257,12 @@ const char * const pcBlankLine = " ";
vTaskDelay( mainSPLASH_SCREEN_DELAY ); vTaskDelay( mainSPLASH_SCREEN_DELAY );
LCD_FillRect( 0, 0, CHIP_SCREEN_WIDTH, CHIP_SCREEN_HEIGHT, RGB_WHITE ); LCD_FillRect( 0, 0, CHIP_SCREEN_WIDTH, CHIP_SCREEN_HEIGHT, RGB_WHITE );
for( ;; ) for( ; ; )
{ {
/* Wait for a message to arrive that requires displaying. */ /* Wait for a message to arrive that requires displaying. */
while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS ); while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS )
{
}
/* Check the message type. */ /* Check the message type. */
if( xMessage.xMessageType == mainUPDATE_BALL_MESSAGE ) if( xMessage.xMessageType == mainUPDATE_BALL_MESSAGE )
@ -270,10 +274,11 @@ const char * const pcBlankLine = " ";
else else
{ {
/* A text string was sent. First blank off the old text string, then /* A text string was sent. First blank off the old text string, then
draw the new text on the next line down. */ * draw the new text on the next line down. */
DRAW_DisplayString( 0, cY, pcBlankLine, strlen( pcBlankLine ) ); DRAW_DisplayString( 0, cY, pcBlankLine, strlen( pcBlankLine ) );
cY -= mainLCD_CHAR_HEIGHT; cY -= mainLCD_CHAR_HEIGHT;
if( cY <= ( mainLCD_CHAR_HEIGHT - 1 ) ) if( cY <= ( mainLCD_CHAR_HEIGHT - 1 ) )
{ {
/* Wrap the line onto which we are going to write the text. */ /* Wrap the line onto which we are going to write the text. */
@ -287,12 +292,12 @@ const char * const pcBlankLine = " ";
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTask( void *pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
xLCDMessage xMessage; xLCDMessage xMessage;
static signed char cPassMessage[ mainMAX_MSG_LEN ]; static signed char cPassMessage[ mainMAX_MSG_LEN ];
extern unsigned short usMaxJitter; extern unsigned short usMaxJitter;
/* Initialise the xLastExecutionTime variable on task entry. */ /* Initialise the xLastExecutionTime variable on task entry. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
@ -301,18 +306,19 @@ extern unsigned short usMaxJitter;
xMessage.xMessageType = mainWRITE_STRING_MESSAGE; xMessage.xMessageType = mainWRITE_STRING_MESSAGE;
xMessage.pcMessage = cPassMessage; xMessage.pcMessage = cPassMessage;
for( ;; ) for( ; ; )
{ {
/* Perform this check every mainCHECK_DELAY milliseconds. */ /* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
/* Has an error been found in any task? If so then point the text /* Has an error been found in any task? If so then point the text
we are going to send to the LCD task to an error message instead of * we are going to send to the LCD task to an error message instead of
the PASS message. */ * the PASS message. */
if( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
xMessage.pcMessage = "ERROR IN GEN Q"; xMessage.pcMessage = "ERROR IN GEN Q";
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
xMessage.pcMessage = "ERROR IN BLOCK Q"; xMessage.pcMessage = "ERROR IN BLOCK Q";
@ -332,9 +338,9 @@ extern unsigned short usMaxJitter;
else else
{ {
/* No errors were found in any task, so send a pass message /* No errors were found in any task, so send a pass message
with the max measured jitter time also included (as per the * with the max measured jitter time also included (as per the
fast interrupt test described at the top of this file and on * fast interrupt test described at the top of this file and on
the online documentation page for this demo application). */ * the online documentation page for this demo application). */
sprintf( ( char * ) cPassMessage, "PASS [%uns]", ( ( unsigned long ) usMaxJitter ) * mainNS_PER_CLOCK ); sprintf( ( char * ) cPassMessage, "PASS [%uns]", ( ( unsigned long ) usMaxJitter ) * mainNS_PER_CLOCK );
} }
@ -346,13 +352,14 @@ extern unsigned short usMaxJitter;
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
static unsigned long ulCallCount; static unsigned long ulCallCount;
static const xLCDMessage xMemsMessage = { mainUPDATE_BALL_MESSAGE, NULL }; static const xLCDMessage xMemsMessage = { mainUPDATE_BALL_MESSAGE, NULL };
static portBASE_TYPE xHigherPriorityTaskWoken; static portBASE_TYPE xHigherPriorityTaskWoken;
/* Periodically send a message to the LCD task telling it to update /* Periodically send a message to the LCD task telling it to update
the MEMS input, and then if necessary the LCD. */ * the MEMS input, and then if necessary the LCD. */
ulCallCount++; ulCallCount++;
if( ulCallCount >= mainMEMS_DELAY ) if( ulCallCount >= mainMEMS_DELAY )
{ {
ulCallCount = 0; ulCallCount = 0;
@ -394,7 +401,7 @@ static void prvSetupHardware( void )
RCC_PLLCmd( ENABLE ); RCC_PLLCmd( ENABLE );
/* Wait till PLL is ready. */ /* Wait till PLL is ready. */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY ) == RESET )
{ {
} }
@ -407,7 +414,7 @@ static void prvSetupHardware( void )
} }
/* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */ /* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
| RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE ); | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE );
/* SPI2 Periph clock enable */ /* SPI2 Periph clock enable */
@ -423,7 +430,7 @@ static void prvSetupHardware( void )
SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK ); SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK );
/* Misc initialisation, including some of the CircleOS features. Note /* Misc initialisation, including some of the CircleOS features. Note
that CircleOS itself is not used. */ * that CircleOS itself is not used. */
vParTestInitialise(); vParTestInitialise();
MEMS_Init(); MEMS_Init();
POINTER_Init(); POINTER_Init();
@ -431,17 +438,17 @@ static void prvSetupHardware( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvFlashTask( void *pvParameters ) static void prvFlashTask( void * pvParameters )
{ {
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
/* Initialise the xLastExecutionTime variable on task entry. */ /* Initialise the xLastExecutionTime variable on task entry. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Simple toggle the LED periodically. This just provides some timing /* Simple toggle the LED periodically. This just provides some timing
verification. */ * verification. */
vTaskDelayUntil( &xLastExecutionTime, mainFLASH_DELAY ); vTaskDelayUntil( &xLastExecutionTime, mainFLASH_DELAY );
vParTestToggleLED( 0 ); vParTestToggleLED( 0 );
} }
@ -452,6 +459,3 @@ void starting_delay( unsigned long ul )
{ {
vTaskDelay( ( TickType_t ) ul ); vTaskDelay( ( TickType_t ) ul );
} }

View file

@ -61,10 +61,11 @@ extern void main_low_power( void );
extern void main_full( void ); extern void main_full( void );
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -75,7 +76,7 @@ int main( void )
prvSetupHardware(); prvSetupHardware();
/* The configCREATE_LOW_POWER_DEMO setting is described at the top of /* The configCREATE_LOW_POWER_DEMO setting is described at the top of
this file. */ * this file. */
#if configCREATE_LOW_POWER_DEMO == 1 #if configCREATE_LOW_POWER_DEMO == 1
{ {
main_low_power(); main_low_power();
@ -94,10 +95,11 @@ int main( void )
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* GPIO, EXTI and NVIC Init structure declaration */ /* GPIO, EXTI and NVIC Init structure declaration */
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
void SystemCoreClockUpdate( void );
void SystemCoreClockUpdate( void );
/* System function that updates the SystemCoreClock variable. */ /* System function that updates the SystemCoreClock variable. */
SystemCoreClockUpdate(); SystemCoreClockUpdate();
@ -112,19 +114,21 @@ void SystemCoreClockUpdate( void );
RCC_MSIRangeConfig( RCC_MSIRange_6 ); RCC_MSIRangeConfig( RCC_MSIRange_6 );
/* Enable the GPIOs clocks. */ /* Enable the GPIOs clocks. */
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC| RCC_AHBPeriph_GPIOD| RCC_AHBPeriph_GPIOE| RCC_AHBPeriph_GPIOH, ENABLE ); RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOH, ENABLE );
/* Enable comparator clocks. */ /* Enable comparator clocks. */
RCC_APB1PeriphClockCmd( RCC_APB1Periph_COMP, ENABLE ); RCC_APB1PeriphClockCmd( RCC_APB1Periph_COMP, ENABLE );
/* Enable SYSCFG clocks. */ /* Enable SYSCFG clocks. */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG , ENABLE ); RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG, ENABLE );
/* Set internal voltage regulator to 1.5V. */ /* Set internal voltage regulator to 1.5V. */
PWR_VoltageScalingConfig( PWR_VoltageScaling_Range2 ); PWR_VoltageScalingConfig( PWR_VoltageScaling_Range2 );
/* Wait Until the Voltage Regulator is ready. */ /* Wait Until the Voltage Regulator is ready. */
while( PWR_GetFlagStatus( PWR_FLAG_VOS ) != RESET ); while( PWR_GetFlagStatus( PWR_FLAG_VOS ) != RESET )
{
}
/* Configure User Button pin as input */ /* Configure User Button pin as input */
GPIO_InitStructure.GPIO_Pin = USERBUTTON_GPIO_PIN; GPIO_InitStructure.GPIO_Pin = USERBUTTON_GPIO_PIN;
@ -137,7 +141,7 @@ void SystemCoreClockUpdate( void );
SYSCFG_EXTILineConfig( EXTI_PortSourceGPIOA, EXTI_PinSource0 ); SYSCFG_EXTILineConfig( EXTI_PortSourceGPIOA, EXTI_PinSource0 );
/* Configure EXT1 Line 0 in interrupt mode triggered on Rising edge */ /* Configure EXT1 Line 0 in interrupt mode triggered on Rising edge */
EXTI_InitStructure.EXTI_Line = EXTI_Line0 ; /* PA0 for User button AND IDD_WakeUP */ EXTI_InitStructure.EXTI_Line = EXTI_Line0; /* PA0 for User button AND IDD_WakeUP */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_InitStructure.EXTI_LineCmd = ENABLE;
@ -167,60 +171,68 @@ void SystemCoreClockUpdate( void );
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* This function will be called by each tick interrupt if /* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be * configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so * added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API * code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */ * functions can be used (those that end in FromISR()). */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( unsigned long ulLine, const char * const pcFileName ) void vAssertCalled( unsigned long ulLine,
const char * const pcFileName )
{ {
volatile unsigned long ulSetToNonZeroInDebuggerToContinue = 0; volatile unsigned long ulSetToNonZeroInDebuggerToContinue = 0;
/* Parameters are not used. */ /* Parameters are not used. */
( void ) ulLine; ( void ) ulLine;
@ -231,12 +243,11 @@ volatile unsigned long ulSetToNonZeroInDebuggerToContinue = 0;
while( ulSetToNonZeroInDebuggerToContinue == 0 ) while( ulSetToNonZeroInDebuggerToContinue == 0 )
{ {
/* Use the debugger to set ulSetToNonZeroInDebuggerToContinue to a /* Use the debugger to set ulSetToNonZeroInDebuggerToContinue to a
non zero value to step out of this function to the point that raised * non zero value to step out of this function to the point that raised
this assert(). */ * this assert(). */
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
} }

View file

@ -94,13 +94,13 @@
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The period after which the check timer will expire providing no errors /* The period after which the check timer will expire providing no errors
have been reported by any of the standard demo tasks. ms are converted to the * have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been /* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -119,14 +119,14 @@ static void prvConfigureLCD( void );
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xCheckTimer = NULL; TimerHandle_t xCheckTimer = NULL;
/* The LCD is only used in the Full demo. */ /* The LCD is only used in the Full demo. */
prvConfigureLCD(); prvConfigureLCD();
/* Start all the other standard demo/test tasks. They have no particular /* Start all the other standard demo/test tasks. They have no particular
functionality, but do demonstrate how to use the FreeRTOS API and test the * functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */ * kernel port. */
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
@ -137,7 +137,7 @@ TimerHandle_t xCheckTimer = NULL;
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
@ -154,21 +154,23 @@ TimerHandle_t xCheckTimer = NULL;
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangedTimerPeriodAlready = pdFALSE; static long lChangedTimerPeriodAlready = pdFALSE;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Check all the demo tasks to ensure they are all still running, and that /* Check all the demo tasks to ensure they are all still running, and that
none have detected an error. */ * none have detected an error. */
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
@ -180,17 +182,17 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
@ -206,14 +208,14 @@ unsigned long ulErrorFound = pdFALSE;
} }
/* Toggle the check LED to give an indication of the system status. If /* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */ * everything is ok. A faster toggle indicates an error. */
GPIO_TOGGLE( LD_GPIO_PORT, LD_GREEN_GPIO_PIN ); GPIO_TOGGLE( LD_GPIO_PORT, LD_GREEN_GPIO_PIN );
/* Have any errors been latch in ulErrorFound? If so, shorten the /* Have any errors been latch in ulErrorFound? If so, shorten the
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. * period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
This will result in an increase in the rate at which mainCHECK_LED * This will result in an increase in the rate at which mainCHECK_LED
toggles. */ * toggles. */
if( ulErrorFound != pdFALSE ) if( ulErrorFound != pdFALSE )
{ {
if( lChangedTimerPeriodAlready == pdFALSE ) if( lChangedTimerPeriodAlready == pdFALSE )
@ -221,8 +223,8 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE; lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time. /* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must * Functions called from inside of a timer callback function must
*never* attempt to block. */ * never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
} }
} }
@ -231,7 +233,7 @@ unsigned long ulErrorFound = pdFALSE;
static void prvConfigureLCD( void ) static void prvConfigureLCD( void )
{ {
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
/* Enable necessary clocks. */ /* Enable necessary clocks. */
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC, ENABLE ); RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC, ENABLE );
@ -242,7 +244,7 @@ GPIO_InitTypeDef GPIO_InitStructure;
RCC_RTCCLKCmd( ENABLE ); RCC_RTCCLKCmd( ENABLE );
/* Configure Port A LCD Output pins as alternate function. */ /* Configure Port A LCD Output pins as alternate function. */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9 |GPIO_Pin_10 |GPIO_Pin_15; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init( GPIOA, &GPIO_InitStructure ); GPIO_Init( GPIOA, &GPIO_InitStructure );
@ -274,7 +276,7 @@ GPIO_InitTypeDef GPIO_InitStructure;
GPIO_PinAFConfig( GPIOB, GPIO_PinSource15, GPIO_AF_LCD ); GPIO_PinAFConfig( GPIOB, GPIO_PinSource15, GPIO_AF_LCD );
/* Configure Port C LCD Output pins as alternate function */ /* Configure Port C LCD Output pins as alternate function */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |GPIO_Pin_11 ; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init( GPIOC, &GPIO_InitStructure ); GPIO_Init( GPIOC, &GPIO_InitStructure );
@ -293,4 +295,3 @@ GPIO_InitTypeDef GPIO_InitStructure;
LCD_GLASS_Init(); LCD_GLASS_Init();
LCD_GLASS_DisplayString( "F'RTOS" ); LCD_GLASS_DisplayString( "F'RTOS" );
} }

View file

@ -124,8 +124,8 @@
#define configQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define configQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* The number of items the queue can hold. This is 1 as the Rx task will /* The number of items the queue can hold. This is 1 as the Rx task will
remove items as they are added so the Tx task should always find the queue * remove items as they are added so the Tx task should always find the queue
empty. */ * empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* A block time of zero simply means "don't block". */ /* A block time of zero simply means "don't block". */
@ -142,8 +142,8 @@ empty. */
/* /*
* The Rx and Tx tasks as described at the top of this file. * The Rx and Tx tasks as described at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -156,7 +156,7 @@ static QueueHandle_t xQueue = NULL;
TickType_t xSendBlockTime = ( 100UL / portTICK_PERIOD_MS ); TickType_t xSendBlockTime = ( 100UL / portTICK_PERIOD_MS );
/* The lower an upper limits of the block time. An infinite block time is used /* The lower an upper limits of the block time. An infinite block time is used
if xSendBlockTime is incremented past xMaxBlockTime. */ * if xSendBlockTime is incremented past xMaxBlockTime. */
static const TickType_t xMaxBlockTime = ( 500L / portTICK_PERIOD_MS ), xMinBlockTime = ( 100L / portTICK_PERIOD_MS ); static const TickType_t xMaxBlockTime = ( 500L / portTICK_PERIOD_MS ), xMinBlockTime = ( 100L / portTICK_PERIOD_MS );
/* The semaphore on which the Tx task blocks. */ /* The semaphore on which the Tx task blocks. */
@ -183,25 +183,27 @@ void main_low_power( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well the next line of code will not be reached as the /* If all is well the next line of code will not be reached as the
scheduler will be running. If the next line is reached then it is likely * scheduler will be running. If the next line is reached then it is likely
there was insufficient FreeRTOS heap available for the idle task and/or * there was insufficient FreeRTOS heap available for the idle task and/or
timer task to be created. See http://www.freertos.org/a00111.html. */ * timer task to be created. See http://www.freertos.org/a00111.html. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
const unsigned long ulValueToSend = mainQUEUED_VALUE; const unsigned long ulValueToSend = mainQUEUED_VALUE;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
/* Enter the Blocked state to wait for the semaphore. The task will /* Enter the Blocked state to wait for the semaphore. The task will
leave the Blocked state if either the semaphore is received or * leave the Blocked state if either the semaphore is received or
xSendBlockTime ticks pass without the semaphore being received. */ * xSendBlockTime ticks pass without the semaphore being received. */
xSemaphoreTake( xTxSemaphore, xSendBlockTime ); xSemaphoreTake( xTxSemaphore, xSendBlockTime );
/* Send to the queue - causing the Tx task to flash its LED. */ /* Send to the queue - causing the Tx task to flash its LED. */
@ -210,20 +212,20 @@ const unsigned long ulValueToSend = mainQUEUED_VALUE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue. */ /* Wait until something arrives in the queue. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have arrived, but is it the expected /* To get here something must have arrived, but is it the expected
value? If it is, turn the LED on for a short while. */ * value? If it is, turn the LED on for a short while. */
if( ulReceivedValue == mainQUEUED_VALUE ) if( ulReceivedValue == mainQUEUED_VALUE )
{ {
/* LED on... */ /* LED on... */
@ -240,13 +242,13 @@ unsigned long ulReceivedValue;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Handles interrupts generated by pressing the USER button. */ /* Handles interrupts generated by pressing the USER button. */
void EXTI0_IRQHandler(void) void EXTI0_IRQHandler( void )
{ {
static const TickType_t xIncrement = 200UL / portTICK_PERIOD_MS; static const TickType_t xIncrement = 200UL / portTICK_PERIOD_MS;
/* If xSendBlockTime is already portMAX_DELAY then the Tx task was blocked /* If xSendBlockTime is already portMAX_DELAY then the Tx task was blocked
indefinitely, and this interrupt is bringing the MCU out of STOP low power * indefinitely, and this interrupt is bringing the MCU out of STOP low power
mode. */ * mode. */
if( xSendBlockTime == portMAX_DELAY ) if( xSendBlockTime == portMAX_DELAY )
{ {
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
@ -255,24 +257,24 @@ static const TickType_t xIncrement = 200UL / portTICK_PERIOD_MS;
xSemaphoreGiveFromISR( xTxSemaphore, &xHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xTxSemaphore, &xHigherPriorityTaskWoken );
/* Start over with the 'short' block time as described at the top of /* Start over with the 'short' block time as described at the top of
this file. */ * this file. */
xSendBlockTime = xMinBlockTime; xSendBlockTime = xMinBlockTime;
/* Request a yield if calling xSemaphoreGiveFromISR() caused a task to /* Request a yield if calling xSemaphoreGiveFromISR() caused a task to
leave the Blocked state (which it will have done) and the task that left * leave the Blocked state (which it will have done) and the task that left
the Blocked state has a priority higher than the currently running task * the Blocked state has a priority higher than the currently running task
(which it will have). */ * (which it will have). */
portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} }
else else
{ {
/* Increase the block time used by the Tx task, as described at the top /* Increase the block time used by the Tx task, as described at the top
of this file. */ * of this file. */
xSendBlockTime += xIncrement; xSendBlockTime += xIncrement;
/* If the block time has gone over the configured maximum then set it to /* If the block time has gone over the configured maximum then set it to
an infinite block time to allow the MCU to go into its STOP low power * an infinite block time to allow the MCU to go into its STOP low power
mode. */ * mode. */
if( xSendBlockTime > xMaxBlockTime ) if( xSendBlockTime > xMaxBlockTime )
{ {
xSendBlockTime = portMAX_DELAY; xSendBlockTime = portMAX_DELAY;
@ -284,14 +286,14 @@ static const TickType_t xIncrement = 200UL / portTICK_PERIOD_MS;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The configPOST_STOP_PROCESSING() macro is called when the MCU leaves its /* The configPOST_STOP_PROCESSING() macro is called when the MCU leaves its
STOP low power mode. The macro is set in FreeRTOSConfig.h to call * STOP low power mode. The macro is set in FreeRTOSConfig.h to call
vMainPostStopProcessing(). */ * vMainPostStopProcessing(). */
void vMainPostStopProcessing( void ) void vMainPostStopProcessing( void )
{ {
extern void SetSysClock( void ); extern void SetSysClock( void );
/* The STOP low power mode has been exited. Reconfigure the system clocks /* The STOP low power mode has been exited. Reconfigure the system clocks
ready for normally running again. */ * ready for normally running again. */
SetSysClock(); SetSysClock();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -87,7 +87,7 @@
* code and displays an appropriate message - which will be PASS if no tasks * code and displays an appropriate message - which will be PASS if no tasks
* have reported any errors, or a message stating which task has reported an * have reported any errors, or a message stating which task has reported an
* error. * error.
*/ */
/* Standard includes. */ /* Standard includes. */
#include <stdio.h> #include <stdio.h>
@ -115,19 +115,19 @@
#define mainGENERIC_QUEUE_TEST_PRIORITY ( tskIDLE_PRIORITY ) #define mainGENERIC_QUEUE_TEST_PRIORITY ( tskIDLE_PRIORITY )
/* The length of the queue (the number of items the queue can hold) that is used /* The length of the queue (the number of items the queue can hold) that is used
to send messages from tasks and interrupts the the LCD task. */ * to send messages from tasks and interrupts the the LCD task. */
#define mainQUEUE_LENGTH ( 5 ) #define mainQUEUE_LENGTH ( 5 )
/* Codes sent within messages to the LCD task so the LCD task can interpret /* Codes sent within messages to the LCD task so the LCD task can interpret
exactly what the message it just received was. These are sent in the * exactly what the message it just received was. These are sent in the
cMessageID member of the message structure (defined below). */ * cMessageID member of the message structure (defined below). */
#define mainMESSAGE_BUTTON_UP ( 1 ) #define mainMESSAGE_BUTTON_UP ( 1 )
#define mainMESSAGE_BUTTON_SEL ( 2 ) #define mainMESSAGE_BUTTON_SEL ( 2 )
#define mainMESSAGE_STATUS ( 3 ) #define mainMESSAGE_STATUS ( 3 )
/* When the cMessageID member of the message sent to the LCD task is /* When the cMessageID member of the message sent to the LCD task is
mainMESSAGE_STATUS then these definitions are sent in the lMessageValue member * mainMESSAGE_STATUS then these definitions are sent in the lMessageValue member
of the same message and indicate what the status actually is. */ * of the same message and indicate what the status actually is. */
#define mainERROR_DYNAMIC_TASKS ( pdPASS + 1 ) #define mainERROR_DYNAMIC_TASKS ( pdPASS + 1 )
#define mainERROR_COM_TEST ( pdPASS + 2 ) #define mainERROR_COM_TEST ( pdPASS + 2 )
#define mainERROR_GEN_QUEUE_TEST ( pdPASS + 3 ) #define mainERROR_GEN_QUEUE_TEST ( pdPASS + 3 )
@ -136,11 +136,11 @@ of the same message and indicate what the status actually is. */
#define mainCOM_TEST_BAUD_RATE ( 115200 ) #define mainCOM_TEST_BAUD_RATE ( 115200 )
/* The LED used by the comtest tasks. See the comtest.c file for more /* The LED used by the comtest tasks. See the comtest.c file for more
information. */ * information. */
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
/* The LCD task uses printf() so requires more stack than most of the other /* The LCD task uses printf() so requires more stack than most of the other
tasks. */ * tasks. */
#define mainLCD_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) #define mainLCD_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -155,37 +155,38 @@ static void prvSetupHardware( void );
* Definition of the LCD/controller task described in the comments at the top * Definition of the LCD/controller task described in the comments at the top
* of this file. * of this file.
*/ */
static void prvLCDTask( void *pvParameters ); static void prvLCDTask( void * pvParameters );
/* /*
* Definition of the button poll task described in the comments at the top of * Definition of the button poll task described in the comments at the top of
* this file. * this file.
*/ */
static void prvButtonPollTask( void *pvParameters ); static void prvButtonPollTask( void * pvParameters );
/* /*
* Converts a status message value into an appropriate string for display on * Converts a status message value into an appropriate string for display on
* the LCD. The string is written to pcBuffer. * the LCD. The string is written to pcBuffer.
*/ */
static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue ); static void prvGenerateStatusMessage( char * pcBuffer,
long lStatusValue );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The time base for the run time stats is generated by the 16 bit timer 6. /* The time base for the run time stats is generated by the 16 bit timer 6.
Each time the timer overflows ulTIM6_OverflowCount is incremented. Therefore, * Each time the timer overflows ulTIM6_OverflowCount is incremented. Therefore,
when converting the total run time to a 32 bit number, the most significant two * when converting the total run time to a 32 bit number, the most significant two
bytes are given by ulTIM6_OverflowCount and the least significant two bytes are * bytes are given by ulTIM6_OverflowCount and the least significant two bytes are
given by the current TIM6 counter value. Care must be taken with data * given by the current TIM6 counter value. Care must be taken with data
consistency when combining the two in case a timer overflow occurs as the * consistency when combining the two in case a timer overflow occurs as the
value is being read. */ * value is being read. */
unsigned long ulTIM6_OverflowCount = 0UL; unsigned long ulTIM6_OverflowCount = 0UL;
/* The handle of the queue used to send messages from tasks and interrupts to /* The handle of the queue used to send messages from tasks and interrupts to
the LCD task. */ * the LCD task. */
static QueueHandle_t xLCDQueue = NULL; static QueueHandle_t xLCDQueue = NULL;
/* The definition of each message sent from tasks and interrupts to the LCD /* The definition of each message sent from tasks and interrupts to the LCD
task. */ * task. */
typedef struct typedef struct
{ {
char cMessageID; /* << States what the message is. */ char cMessageID; /* << States what the message is. */
@ -197,23 +198,23 @@ typedef struct
void main( void ) void main( void )
{ {
/* Configure the peripherals used by this demo application. This includes /* Configure the peripherals used by this demo application. This includes
configuring the joystick input select button to generate interrupts. */ * configuring the joystick input select button to generate interrupts. */
prvSetupHardware(); prvSetupHardware();
/* Create the queue used by tasks and interrupts to send strings to the LCD /* Create the queue used by tasks and interrupts to send strings to the LCD
task. */ * task. */
xLCDQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( xQueueMessage ) ); xLCDQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( xQueueMessage ) );
/* If the queue could not be created then don't create any tasks that might /* If the queue could not be created then don't create any tasks that might
attempt to use the queue. */ * attempt to use the queue. */
if( xLCDQueue != NULL ) if( xLCDQueue != NULL )
{ {
/* Add the created queue to the queue registry so it can be viewed in /* Add the created queue to the queue registry so it can be viewed in
the IAR FreeRTOS state viewer plug-in. */ * the IAR FreeRTOS state viewer plug-in. */
vQueueAddToRegistry( xLCDQueue, "LCDQueue" ); vQueueAddToRegistry( xLCDQueue, "LCDQueue" );
/* Create the LCD and button poll tasks, as described at the top of this /* Create the LCD and button poll tasks, as described at the top of this
file. */ * file. */
xTaskCreate( prvLCDTask, "LCD", mainLCD_TASK_STACK_SIZE, NULL, mainLCD_TASK_PRIORITY, NULL ); xTaskCreate( prvLCDTask, "LCD", mainLCD_TASK_STACK_SIZE, NULL, mainLCD_TASK_PRIORITY, NULL );
xTaskCreate( prvButtonPollTask, "ButPoll", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( prvButtonPollTask, "ButPoll", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
@ -228,42 +229,44 @@ void main( void )
} }
/* If all is well then this line will never be reached. If it is reached /* If all is well then this line will never be reached. If it is reached
then it is likely that there was insufficient (FreeRTOS) heap memory space * then it is likely that there was insufficient (FreeRTOS) heap memory space
to create the idle task. This may have been trapped by the malloc() failed * to create the idle task. This may have been trapped by the malloc() failed
hook function, if one is configured. */ * hook function, if one is configured. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvLCDTask( void *pvParameters ) static void prvLCDTask( void * pvParameters )
{ {
xQueueMessage xReceivedMessage; xQueueMessage xReceivedMessage;
long lLine = Line1; long lLine = Line1;
const long lFontHeight = (((sFONT *)LCD_GetFont())->Height); const long lFontHeight = ( ( ( sFONT * ) LCD_GetFont() )->Height );
/* Buffer into which strings are formatted and placed ready for display on the /* Buffer into which strings are formatted and placed ready for display on the
LCD. Note this is a static variable to prevent it being allocated on the task * LCD. Note this is a static variable to prevent it being allocated on the task
stack, which is too small to hold such a variable. The stack size is configured * stack, which is too small to hold such a variable. The stack size is configured
when the task is created. */ * when the task is created. */
static char cBuffer[ 512 ]; static char cBuffer[ 512 ];
/* This function is the only function that uses printf(). If printf() is /* This function is the only function that uses printf(). If printf() is
used from any other function then some sort of mutual exclusion on stdout * used from any other function then some sort of mutual exclusion on stdout
will be necessary. * will be necessary.
*
This is also the only function that is permitted to access the LCD. * This is also the only function that is permitted to access the LCD.
*
First print out the number of bytes that remain in the FreeRTOS heap. This * First print out the number of bytes that remain in the FreeRTOS heap. This
can be viewed in the terminal IO window within the IAR Embedded Workbench. */ * can be viewed in the terminal IO window within the IAR Embedded Workbench. */
printf( "%d bytes of heap space remain unallocated\n", xPortGetFreeHeapSize() ); printf( "%d bytes of heap space remain unallocated\n", xPortGetFreeHeapSize() );
for( ;; ) for( ; ; )
{ {
/* Wait for a message to be received. Using portMAX_DELAY as the block /* Wait for a message to be received. Using portMAX_DELAY as the block
time will result in an indefinite wait provided INCLUDE_vTaskSuspend is * time will result in an indefinite wait provided INCLUDE_vTaskSuspend is
set to 1 in FreeRTOSConfig.h, therefore there is no need to check the * set to 1 in FreeRTOSConfig.h, therefore there is no need to check the
function return value and the function will only return when a value * function return value and the function will only return when a value
has been received. */ * has been received. */
xQueueReceive( xLCDQueue, &xReceivedMessage, portMAX_DELAY ); xQueueReceive( xLCDQueue, &xReceivedMessage, portMAX_DELAY );
/* Clear the LCD if no room remains for any more text output. */ /* Clear the LCD if no room remains for any more text output. */
@ -276,73 +279,84 @@ static char cBuffer[ 512 ];
/* What is this message? What does it contain? */ /* What is this message? What does it contain? */
switch( xReceivedMessage.cMessageID ) switch( xReceivedMessage.cMessageID )
{ {
case mainMESSAGE_BUTTON_UP : /* The button poll task has just case mainMESSAGE_BUTTON_UP: /* The button poll task has just
informed this task that the up * informed this task that the up
button on the joystick input has * button on the joystick input has
been pressed or released. */ * been pressed or released. */
sprintf( cBuffer, "Button up = %d", xReceivedMessage.lMessageValue ); sprintf( cBuffer, "Button up = %d", xReceivedMessage.lMessageValue );
break; break;
case mainMESSAGE_BUTTON_SEL : /* The select button interrupt case mainMESSAGE_BUTTON_SEL: /* The select button interrupt
just informed this task that the * just informed this task that the
select button was pressed. * select button was pressed.
Generate a table of task run time * Generate a table of task run time
statistics and output this to * statistics and output this to
the terminal IO window in the IAR * the terminal IO window in the IAR
embedded workbench. */ * embedded workbench. */
printf( "\nTask\t Abs Time\t %%Time\n*****************************************" ); printf( "\nTask\t Abs Time\t %%Time\n*****************************************" );
vTaskGetRunTimeStats( cBuffer ); vTaskGetRunTimeStats( cBuffer );
printf( cBuffer ); printf( cBuffer );
/* Also print out a message to /* Also print out a message to
the LCD - in this case the * the LCD - in this case the
pointer to the string to print * pointer to the string to print
is sent directly in the * is sent directly in the
lMessageValue member of the * lMessageValue member of the
message. This just demonstrates * message. This just demonstrates
a different communication * a different communication
technique. */ * technique. */
sprintf( cBuffer, "%s", ( char * ) xReceivedMessage.lMessageValue ); sprintf( cBuffer, "%s", ( char * ) xReceivedMessage.lMessageValue );
break; break;
case mainMESSAGE_STATUS : /* The tick interrupt hook case mainMESSAGE_STATUS: /* The tick interrupt hook
function has just informed this * function has just informed this
task of the system status. * task of the system status.
Generate a string in accordance * Generate a string in accordance
with the status value. */ * with the status value. */
prvGenerateStatusMessage( cBuffer, xReceivedMessage.lMessageValue ); prvGenerateStatusMessage( cBuffer, xReceivedMessage.lMessageValue );
break; break;
default : sprintf( cBuffer, "Unknown message" ); default:
sprintf( cBuffer, "Unknown message" );
break; break;
} }
/* Output the message that was placed into the cBuffer array within the /* Output the message that was placed into the cBuffer array within the
switch statement above. */ * switch statement above. */
LCD_DisplayStringLine( lLine, ( uint8_t * ) cBuffer ); LCD_DisplayStringLine( lLine, ( uint8_t * ) cBuffer );
/* Move onto the next LCD line, ready for the next iteration of this /* Move onto the next LCD line, ready for the next iteration of this
loop. */ * loop. */
lLine += lFontHeight; lLine += lFontHeight;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue ) static void prvGenerateStatusMessage( char * pcBuffer,
long lStatusValue )
{ {
/* Just a utility function to convert a status value into a meaningful /* Just a utility function to convert a status value into a meaningful
string for output onto the LCD. */ * string for output onto the LCD. */
switch( lStatusValue ) switch( lStatusValue )
{ {
case pdPASS : sprintf( pcBuffer, "Task status = PASS" ); case pdPASS:
sprintf( pcBuffer, "Task status = PASS" );
break; break;
case mainERROR_DYNAMIC_TASKS : sprintf( pcBuffer, "Error: Dynamic tasks" );
case mainERROR_DYNAMIC_TASKS:
sprintf( pcBuffer, "Error: Dynamic tasks" );
break; break;
case mainERROR_COM_TEST : sprintf( pcBuffer, "Err: loop connected?" ); /* Error in COM test - is the Loopback connector connected? */
case mainERROR_COM_TEST:
sprintf( pcBuffer, "Err: loop connected?" ); /* Error in COM test - is the Loopback connector connected? */
break; break;
case mainERROR_GEN_QUEUE_TEST : sprintf( pcBuffer, "Error: Gen Q test" );
case mainERROR_GEN_QUEUE_TEST:
sprintf( pcBuffer, "Error: Gen Q test" );
break; break;
default : sprintf( pcBuffer, "Unknown status" );
default:
sprintf( pcBuffer, "Unknown status" );
break; break;
} }
} }
@ -351,44 +365,45 @@ static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue )
void EXTI9_5_IRQHandler( void ) void EXTI9_5_IRQHandler( void )
{ {
/* Define the message sent to the LCD task from this interrupt. */ /* Define the message sent to the LCD task from this interrupt. */
const xQueueMessage xMessage = { mainMESSAGE_BUTTON_SEL, ( unsigned long ) "Select Interrupt!" }; const xQueueMessage xMessage = { mainMESSAGE_BUTTON_SEL, ( unsigned long ) "Select Interrupt!" };
long lHigherPriorityTaskWoken = pdFALSE; long lHigherPriorityTaskWoken = pdFALSE;
/* This is the interrupt handler for the joystick select button input. /* This is the interrupt handler for the joystick select button input.
The button has been pushed, write a message to the LCD via the LCD task. */ * The button has been pushed, write a message to the LCD via the LCD task. */
xQueueSendFromISR( xLCDQueue, &xMessage, &lHigherPriorityTaskWoken ); xQueueSendFromISR( xLCDQueue, &xMessage, &lHigherPriorityTaskWoken );
EXTI_ClearITPendingBit( SEL_BUTTON_EXTI_LINE ); EXTI_ClearITPendingBit( SEL_BUTTON_EXTI_LINE );
/* If writing to xLCDQueue caused a task to unblock, and the unblocked task /* If writing to xLCDQueue caused a task to unblock, and the unblocked task
has a priority equal to or above the task that this interrupt interrupted, * has a priority equal to or above the task that this interrupt interrupted,
then lHigherPriorityTaskWoken will have been set to pdTRUE internally within * then lHigherPriorityTaskWoken will have been set to pdTRUE internally within
xQueuesendFromISR(), and portEND_SWITCHING_ISR() will ensure that this * xQueuesendFromISR(), and portEND_SWITCHING_ISR() will ensure that this
interrupt returns directly to the higher priority unblocked task. */ * interrupt returns directly to the higher priority unblocked task. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
static unsigned long ulCounter = 0; static unsigned long ulCounter = 0;
static const unsigned long ulCheckFrequency = 5000UL / portTICK_PERIOD_MS; static const unsigned long ulCheckFrequency = 5000UL / portTICK_PERIOD_MS;
long lHigherPriorityTaskWoken = pdFALSE; long lHigherPriorityTaskWoken = pdFALSE;
/* Define the status message that is sent to the LCD task. By default the /* Define the status message that is sent to the LCD task. By default the
status is PASS. */ * status is PASS. */
static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS }; static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };
/* This is called from within the tick interrupt and performs the 'check' /* This is called from within the tick interrupt and performs the 'check'
functionality as described in the comments at the top of this file. * functionality as described in the comments at the top of this file.
*
Is it time to perform the 'check' functionality again? */ * Is it time to perform the 'check' functionality again? */
ulCounter++; ulCounter++;
if( ulCounter >= ulCheckFrequency ) if( ulCounter >= ulCheckFrequency )
{ {
/* See if the standard demo tasks are executing as expected, changing /* See if the standard demo tasks are executing as expected, changing
the message that is sent to the LCD task from PASS to an error code if * the message that is sent to the LCD task from PASS to an error code if
any tasks set reports an error. */ * any tasks set reports an error. */
if( xAreDynamicPriorityTasksStillRunning() != pdPASS ) if( xAreDynamicPriorityTasksStillRunning() != pdPASS )
{ {
xStatusMessage.lMessageValue = mainERROR_DYNAMIC_TASKS; xStatusMessage.lMessageValue = mainERROR_DYNAMIC_TASKS;
@ -405,26 +420,27 @@ static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };
} }
/* As this is the tick hook the lHigherPriorityTaskWoken parameter is not /* As this is the tick hook the lHigherPriorityTaskWoken parameter is not
needed (a context switch is going to be performed anyway), but it must * needed (a context switch is going to be performed anyway), but it must
still be provided. */ * still be provided. */
xQueueSendFromISR( xLCDQueue, &xStatusMessage, &lHigherPriorityTaskWoken ); xQueueSendFromISR( xLCDQueue, &xStatusMessage, &lHigherPriorityTaskWoken );
ulCounter = 0; ulCounter = 0;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvButtonPollTask( void *pvParameters ) static void prvButtonPollTask( void * pvParameters )
{ {
long lLastState = pdTRUE; long lLastState = pdTRUE;
long lState; long lState;
xQueueMessage xMessage; xQueueMessage xMessage;
/* This tasks performs the button polling functionality as described at the /* This tasks performs the button polling functionality as described at the
top of this file. */ * top of this file. */
for( ;; ) for( ; ; )
{ {
/* Check the button state. */ /* Check the button state. */
lState = STM_EVAL_PBGetState( BUTTON_UP ); lState = STM_EVAL_PBGetState( BUTTON_UP );
if( lState != lLastState ) if( lState != lLastState )
{ {
/* The state has changed, send a message to the LCD task. */ /* The state has changed, send a message to the LCD task. */
@ -435,7 +451,7 @@ xQueueMessage xMessage;
} }
/* Block for 10 milliseconds so this task does not utilise all the CPU /* Block for 10 milliseconds so this task does not utilise all the CPU
time and debouncing of the button is not necessary. */ * time and debouncing of the button is not necessary. */
vTaskDelay( 10 / portTICK_PERIOD_MS ); vTaskDelay( 10 / portTICK_PERIOD_MS );
} }
} }
@ -444,7 +460,7 @@ xQueueMessage xMessage;
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Ensure that all 4 interrupt priority bits are used as the pre-emption /* Ensure that all 4 interrupt priority bits are used as the pre-emption
priority. */ * priority. */
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
/* Initialise the LEDs. */ /* Initialise the LEDs. */
@ -457,11 +473,11 @@ static void prvSetupHardware( void )
STM_EVAL_PBInit( BUTTON_RIGHT, BUTTON_MODE_GPIO ); STM_EVAL_PBInit( BUTTON_RIGHT, BUTTON_MODE_GPIO );
/* The select button in the middle of the joystick is configured to generate /* The select button in the middle of the joystick is configured to generate
an interrupt. The Eval board library will configure the interrupt * an interrupt. The Eval board library will configure the interrupt
priority to be the lowest priority available so the priority need not be * priority to be the lowest priority available so the priority need not be
set here explicitly. It is important that the priority is equal to or * set here explicitly. It is important that the priority is equal to or
below that set by the configMAX_SYSCALL_INTERRUPT_PRIORITY value set in * below that set by the configMAX_SYSCALL_INTERRUPT_PRIORITY value set in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
STM_EVAL_PBInit( BUTTON_SEL, BUTTON_MODE_EXTI ); STM_EVAL_PBInit( BUTTON_SEL, BUTTON_MODE_EXTI );
/* Initialize the LCD */ /* Initialize the LCD */
@ -475,26 +491,26 @@ static void prvSetupHardware( void )
void vConfigureTimerForRunTimeStats( void ) void vConfigureTimerForRunTimeStats( void )
{ {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
/* The time base for the run time stats is generated by the 16 bit timer 6. /* The time base for the run time stats is generated by the 16 bit timer 6.
Each time the timer overflows ulTIM6_OverflowCount is incremented. * Each time the timer overflows ulTIM6_OverflowCount is incremented.
Therefore, when converting the total run time to a 32 bit number, the most * Therefore, when converting the total run time to a 32 bit number, the most
significant two bytes are given by ulTIM6_OverflowCount and the least * significant two bytes are given by ulTIM6_OverflowCount and the least
significant two bytes are given by the current TIM6 counter value. Care * significant two bytes are given by the current TIM6 counter value. Care
must be taken with data consistency when combining the two in case a timer * must be taken with data consistency when combining the two in case a timer
overflow occurs as the value is being read. * overflow occurs as the value is being read.
*
The portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro (in FreeRTOSConfig.h) is * The portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro (in FreeRTOSConfig.h) is
defined to call this function, so the kernel will call this function * defined to call this function, so the kernel will call this function
automatically at the appropriate time. */ * automatically at the appropriate time. */
/* TIM6 clock enable */ /* TIM6 clock enable */
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM6, ENABLE ); RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM6, ENABLE );
/* The 32MHz clock divided by 5000 should tick (very) approximately every /* The 32MHz clock divided by 5000 should tick (very) approximately every
150uS and overflow a 16bit timer (very) approximately every 10 seconds. */ * 150uS and overflow a 16bit timer (very) approximately every 10 seconds. */
TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 5000; TIM_TimeBaseStructure.TIM_Prescaler = 5000;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
@ -513,7 +529,7 @@ NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; /* Not used as 4 bits are used for the pre-emption priority. */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; /* Not used as 4 bits are used for the pre-emption priority. */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); NVIC_Init( &NVIC_InitStructure );
TIM_ClearITPendingBit( TIM6, TIM_IT_Update ); TIM_ClearITPendingBit( TIM6, TIM_IT_Update );
TIM_Cmd( TIM6, ENABLE ); TIM_Cmd( TIM6, ENABLE );
@ -523,15 +539,15 @@ NVIC_InitTypeDef NVIC_InitStructure;
void TIM6_IRQHandler( void ) void TIM6_IRQHandler( void )
{ {
/* Interrupt handler for TIM 6 /* Interrupt handler for TIM 6
*
The time base for the run time stats is generated by the 16 bit timer 6. * The time base for the run time stats is generated by the 16 bit timer 6.
Each time the timer overflows ulTIM6_OverflowCount is incremented. * Each time the timer overflows ulTIM6_OverflowCount is incremented.
Therefore, when converting the total run time to a 32 bit number, the most * Therefore, when converting the total run time to a 32 bit number, the most
significant two bytes are given by ulTIM6_OverflowCount and the least * significant two bytes are given by ulTIM6_OverflowCount and the least
significant two bytes are given by the current TIM6 counter value. Care * significant two bytes are given by the current TIM6 counter value. Care
must be taken with data consistency when combining the two in case a timer * must be taken with data consistency when combining the two in case a timer
overflow occurs as the value is being read. */ * overflow occurs as the value is being read. */
if( TIM_GetITStatus( TIM6, TIM_IT_Update) != RESET) if( TIM_GetITStatus( TIM6, TIM_IT_Update ) != RESET )
{ {
ulTIM6_OverflowCount++; ulTIM6_OverflowCount++;
TIM_ClearITPendingBit( TIM6, TIM_IT_Update ); TIM_ClearITPendingBit( TIM6, TIM_IT_Update );
@ -539,34 +555,36 @@ void TIM6_IRQHandler( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues or * internally by FreeRTOS API functions that create tasks, queues or
semaphores. */ * semaphores. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* Called on each iteration of the idle task. In this case the idle task /* Called on each iteration of the idle task. In this case the idle task
just enters a low(ish) power mode. */ * just enters a low(ish) power mode. */
PWR_EnterSleepMode( PWR_Regulator_ON, PWR_SLEEPEntry_WFI ); PWR_EnterSleepMode( PWR_Regulator_ON, PWR_SLEEPEntry_WFI );
} }

View file

@ -76,11 +76,11 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The time between cycles of the 'check' functionality - as described at the /* The time between cycles of the 'check' functionality - as described at the
top of this file. */ * top of this file. */
#define mainNO_ERROR_PERIOD ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainNO_ERROR_PERIOD ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* The rate at which the LED controlled by the 'check' task will flash should an /* The rate at which the LED controlled by the 'check' task will flash should an
error have been detected. */ * error have been detected. */
#define mainERROR_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainERROR_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
/* The LED controlled by the 'check' task. */ /* The LED controlled by the 'check' task. */
@ -110,13 +110,13 @@ static void prvSetupHardware( void );
* Implements the 'check' task functionality as described at the top of this * Implements the 'check' task functionality as described at the top of this
* file. * file.
*/ */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
/* /*
* Implement the 'Reg test' functionality as described at the top of this file. * Implement the 'Reg test' functionality as described at the top of this file.
*/ */
static void vRegTest1Task( void *pvParameters ); static void vRegTest1Task( void * pvParameters );
static void vRegTest2Task( void *pvParameters ); static void vRegTest2Task( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -127,11 +127,11 @@ static volatile unsigned long ulRegTest1Counter = 0x11111111, ulRegTest2Counter
int main( void ) int main( void )
{ {
extern void vBasicWEBServer( void *pv ); extern void vBasicWEBServer( void * pv );
/* Setup the hardware ready for this demo. */ /* Setup the hardware ready for this demo. */
prvSetupHardware(); prvSetupHardware();
( void )sys_thread_new("HTTPD", vBasicWEBServer, NULL, 320, mainWEB_TASK_PRIORITY ); ( void ) sys_thread_new( "HTTPD", vBasicWEBServer, NULL, 320, mainWEB_TASK_PRIORITY );
/* Start the standard demo tasks. */ /* Start the standard demo tasks. */
vStartLEDFlashTasks( tskIDLE_PRIORITY ); vStartLEDFlashTasks( tskIDLE_PRIORITY );
@ -150,33 +150,33 @@ extern void vBasicWEBServer( void *pv );
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* The suicide tasks must be created last as they need to know how many /* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation in order to ascertain whether * tasks were running prior to their creation in order to ascertain whether
or not the correct/expected number of tasks are running at any given time. */ * or not the correct/expected number of tasks are running at any given time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle /* Will only get here if there was insufficient memory to create the idle
task. */ * task. */
for( ;; ) for( ; ; )
{ {
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTask( void *pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
unsigned ulTicksToWait = mainNO_ERROR_PERIOD, ulError = 0, ulLastRegTest1Count = 0, ulLastRegTest2Count = 0; unsigned ulTicksToWait = mainNO_ERROR_PERIOD, ulError = 0, ulLastRegTest1Count = 0, ulLastRegTest2Count = 0;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
( void ) pvParameters; ( void ) pvParameters;
/* Initialise the variable used to control our iteration rate prior to /* Initialise the variable used to control our iteration rate prior to
its first use. */ * its first use. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Wait until it is time to run the tests again. */ /* Wait until it is time to run the tests again. */
vTaskDelayUntil( &xLastExecutionTime, ulTicksToWait ); vTaskDelayUntil( &xLastExecutionTime, ulTicksToWait );
@ -231,7 +231,7 @@ TickType_t xLastExecutionTime;
ulLastRegTest2Count = ulRegTest2Counter; ulLastRegTest2Count = ulRegTest2Counter;
/* If an error has been found then increase our cycle rate, and in so /* If an error has been found then increase our cycle rate, and in so
going increase the rate at which the check task LED toggles. */ * going increase the rate at which the check task LED toggles. */
if( ulError != 0 ) if( ulError != 0 )
{ {
ulTicksToWait = mainERROR_PERIOD; ulTicksToWait = mainERROR_PERIOD;
@ -252,37 +252,38 @@ void prvSetupHardware( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
/* This will get called if a stack overflow is detected during the context /* This will get called if a stack overflow is detected during the context
switch. Set configCHECK_FOR_STACK_OVERFLOWS to 2 to also check for stack * switch. Set configCHECK_FOR_STACK_OVERFLOWS to 2 to also check for stack
problems within nested interrupts, but only do this for debug purposes as * problems within nested interrupts, but only do this for debug purposes as
it will increase the context switch time. */ * it will increase the context switch time. */
( void ) pxTask; ( void ) pxTask;
( void ) pcTaskName; ( void ) pcTaskName;
for( ;; ) for( ; ; )
{ {
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vRegTest1Task( void *pvParameters ) static void vRegTest1Task( void * pvParameters )
{ {
/* Sanity check - did we receive the parameter expected? */ /* Sanity check - did we receive the parameter expected? */
if( pvParameters != &ulRegTest1Counter ) if( pvParameters != &ulRegTest1Counter )
{ {
/* Change here so the check task can detect that an error occurred. */ /* Change here so the check task can detect that an error occurred. */
for( ;; ) for( ; ; )
{ {
} }
} }
/* Set all the registers to known values, then check that each retains its /* Set all the registers to known values, then check that each retains its
expected value - as described at the top of this file. If an error is * expected value - as described at the top of this file. If an error is
found then the loop counter will no longer be incremented allowing the check * found then the loop counter will no longer be incremented allowing the check
task to recognise the error. */ * task to recognise the error. */
asm volatile ( "reg_test_1_start: \n\t" asm volatile ( "reg_test_1_start: \n\t"
" moveq #1, d0 \n\t" " moveq #1, d0 \n\t"
" moveq #2, d1 \n\t" " moveq #2, d1 \n\t"
@ -347,21 +348,21 @@ static void vRegTest1Task( void *pvParameters )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vRegTest2Task( void *pvParameters ) static void vRegTest2Task( void * pvParameters )
{ {
/* Sanity check - did we receive the parameter expected? */ /* Sanity check - did we receive the parameter expected? */
if( pvParameters != &ulRegTest2Counter ) if( pvParameters != &ulRegTest2Counter )
{ {
/* Change here so the check task can detect that an error occurred. */ /* Change here so the check task can detect that an error occurred. */
for( ;; ) for( ; ; )
{ {
} }
} }
/* Set all the registers to known values, then check that each retains its /* Set all the registers to known values, then check that each retains its
expected value - as described at the top of this file. If an error is * expected value - as described at the top of this file. If an error is
found then the loop counter will no longer be incremented allowing the check * found then the loop counter will no longer be incremented allowing the check
task to recognise the error. */ * task to recognise the error. */
asm volatile ( "reg_test_2_start: \n\t" asm volatile ( "reg_test_2_start: \n\t"
" moveq #10, d0 \n\t" " moveq #10, d0 \n\t"
" moveq #20, d1 \n\t" " moveq #20, d1 \n\t"
@ -425,6 +426,3 @@ static void vRegTest2Task( void *pvParameters )
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -104,7 +104,7 @@
#define mainSELECT_PLL_AS_SOURCE ( ( unsigned char ) 0x02 ) #define mainSELECT_PLL_AS_SOURCE ( ( unsigned char ) 0x02 )
/* Toggle rate for the on board LED - which is dependent on whether or not /* Toggle rate for the on board LED - which is dependent on whether or not
an error has been detected. */ * an error has been detected. */
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 5000 ) #define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 5000 )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 250 ) #define mainERROR_FLASH_PERIOD ( ( TickType_t ) 250 )
@ -112,8 +112,8 @@ an error has been detected. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 )
/* Pass an invalid LED number to the COM test task as we don't want it to flash /* Pass an invalid LED number to the COM test task as we don't want it to flash
an LED. There are only 8 LEDs (excluding the on board LED) wired in and these * an LED. There are only 8 LEDs (excluding the on board LED) wired in and these
are all used by the flash tasks. */ * are all used by the flash tasks. */
#define mainCOM_TEST_LED ( 200 ) #define mainCOM_TEST_LED ( 200 )
/* We want the Cygnal to act as much as possible as a standard 8052. */ /* We want the Cygnal to act as much as possible as a standard 8052. */
@ -124,18 +124,18 @@ are all used by the flash tasks. */
#define mainCOMS_LINES_TO_PUSH_PULL ( ( unsigned char ) 0x03 ) #define mainCOMS_LINES_TO_PUSH_PULL ( ( unsigned char ) 0x03 )
/* Pointer passed as a parameter to vRegisterCheck() just so it has some know /* Pointer passed as a parameter to vRegisterCheck() just so it has some know
values to check for in the DPH, DPL and B registers. */ * values to check for in the DPH, DPL and B registers. */
#define mainDUMMY_POINTER ( ( xdata void * ) 0xabcd ) #define mainDUMMY_POINTER ( ( xdata void * ) 0xabcd )
/* Macro that lets vErrorChecks() know that one of the tasks defined in /* Macro that lets vErrorChecks() know that one of the tasks defined in
main. c has detected an error. A critical region is used around xLatchError * main. c has detected an error. A critical region is used around xLatchError
as it is accessed from vErrorChecks(), which has a higher priority. */ * as it is accessed from vErrorChecks(), which has a higher priority. */
#define mainLATCH_ERROR() \ #define mainLATCH_ERROR() \
{ \ { \
portENTER_CRITICAL(); \ portENTER_CRITICAL(); \
xLatchedError = pdTRUE; \ xLatchedError = pdTRUE; \
portEXIT_CRITICAL(); \ portEXIT_CRITICAL(); \
} }
/* /*
* Setup the Cygnal microcontroller for its fastest operation. * Setup the Cygnal microcontroller for its fastest operation.
@ -155,25 +155,25 @@ static void prvToggleOnBoardLED( void );
/* /*
* See comments at the top of the file for details. * See comments at the top of the file for details.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* See comments at the top of the file for details. * See comments at the top of the file for details.
*/ */
static void vRegisterCheck( void *pvParameters ); static void vRegisterCheck( void * pvParameters );
/* /*
* See comments at the top of the file for details. * See comments at the top of the file for details.
*/ */
static void vFLOPCheck1( void *pvParameters ); static void vFLOPCheck1( void * pvParameters );
/* /*
* See comments at the top of the file for details. * See comments at the top of the file for details.
*/ */
static void vFLOPCheck2( void *pvParameters ); static void vFLOPCheck2( void * pvParameters );
/* File scope variable used to communicate the occurrence of an error between /* File scope variable used to communicate the occurrence of an error between
tasks. */ * tasks. */
static portBASE_TYPE xLatchedError = pdFALSE; static portBASE_TYPE xLatchedError = pdFALSE;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -184,11 +184,11 @@ static portBASE_TYPE xLatchedError = pdFALSE;
void main( void ) void main( void )
{ {
/* Initialise the hardware including the system clock and on board /* Initialise the hardware including the system clock and on board
LED. */ * LED. */
prvSetupHardware(); prvSetupHardware();
/* Initialise the port that controls the external LED's utilized by the /* Initialise the port that controls the external LED's utilized by the
flash tasks. */ * flash tasks. */
vParTestInitialise(); vParTestInitialise();
/* Start the used standard demo tasks. */ /* Start the used standard demo tasks. */
@ -199,7 +199,7 @@ void main( void )
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
/* Start the tasks defined in this file. The first three never block so /* Start the tasks defined in this file. The first three never block so
must not be used with the co-operative scheduler. */ * must not be used with the co-operative scheduler. */
#if configUSE_PREEMPTION == 1 #if configUSE_PREEMPTION == 1
{ {
xTaskCreate( vRegisterCheck, "RegChck", configMINIMAL_STACK_SIZE, mainDUMMY_POINTER, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL ); xTaskCreate( vRegisterCheck, "RegChck", configMINIMAL_STACK_SIZE, mainDUMMY_POINTER, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL );
@ -214,7 +214,7 @@ void main( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Should never reach here as the tasks will now be executing under control /* Should never reach here as the tasks will now be executing under control
of the scheduler. */ * of the scheduler. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -225,17 +225,17 @@ void main( void )
*/ */
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
unsigned char ucOriginalSFRPage; unsigned char ucOriginalSFRPage;
/* Remember the SFR page before it is changed so it can get set back /* Remember the SFR page before it is changed so it can get set back
before the function exits. */ * before the function exits. */
ucOriginalSFRPage = SFRPAGE; ucOriginalSFRPage = SFRPAGE;
/* Setup the SFR page to access the config SFR's. */ /* Setup the SFR page to access the config SFR's. */
SFRPAGE = CONFIG_PAGE; SFRPAGE = CONFIG_PAGE;
/* Don't allow the microcontroller to automatically switch SFR page, as the /* Don't allow the microcontroller to automatically switch SFR page, as the
SFR page is not stored as part of the task context. */ * SFR page is not stored as part of the task context. */
SFRPGCN = mainAUTO_SFR_OFF; SFRPGCN = mainAUTO_SFR_OFF;
/* Disable the watchdog. */ /* Disable the watchdog. */
@ -246,7 +246,7 @@ unsigned char ucOriginalSFRPage;
P1MDOUT |= mainPORT_1_BIT_6; P1MDOUT |= mainPORT_1_BIT_6;
/* Setup the cross bar to enable serial comms here as it is not part of the /* Setup the cross bar to enable serial comms here as it is not part of the
standard 8051 setup and therefore is not in the driver code. */ * standard 8051 setup and therefore is not in the driver code. */
XBR0 |= mainENABLE_COMS; XBR0 |= mainENABLE_COMS;
P0MDOUT |= mainCOMS_LINES_TO_PUSH_PULL; P0MDOUT |= mainCOMS_LINES_TO_PUSH_PULL;
@ -263,9 +263,9 @@ unsigned char ucOriginalSFRPage;
static void prvSetupSystemClock( void ) static void prvSetupSystemClock( void )
{ {
volatile unsigned short usWait; volatile unsigned short usWait;
const unsigned short usWaitTime = ( unsigned short ) 0x2ff; const unsigned short usWaitTime = ( unsigned short ) 0x2ff;
unsigned char ucOriginalSFRPage; unsigned char ucOriginalSFRPage;
/* Remember the SFR page so we can set it back at the end. */ /* Remember the SFR page so we can set it back at the end. */
ucOriginalSFRPage = SFRPAGE; ucOriginalSFRPage = SFRPAGE;
@ -275,7 +275,9 @@ unsigned char ucOriginalSFRPage;
OSCICN = mainSELECT_INTERNAL_OSC | mainDIVIDE_CLOCK_BY_1; OSCICN = mainSELECT_INTERNAL_OSC | mainDIVIDE_CLOCK_BY_1;
/* Ensure the clock is stable. */ /* Ensure the clock is stable. */
for( usWait = 0; usWait < usWaitTime; usWait++ ); for( usWait = 0; usWait < usWaitTime; usWait++ )
{
}
/* Setup the clock source for the PLL. */ /* Setup the clock source for the PLL. */
PLL0CN &= ~mainPLL_USES_INTERNAL_OSC; PLL0CN &= ~mainPLL_USES_INTERNAL_OSC;
@ -296,10 +298,13 @@ unsigned char ucOriginalSFRPage;
PLL0MUL = mainPLL_MULTIPLICATION; PLL0MUL = mainPLL_MULTIPLICATION;
/* Ensure the clock is stable. */ /* Ensure the clock is stable. */
for( usWait = 0; usWait < usWaitTime; usWait++ ); for( usWait = 0; usWait < usWaitTime; usWait++ )
{
}
/* Enable the PLL and wait for it to lock. */ /* Enable the PLL and wait for it to lock. */
PLL0CN |= mainENABLE_PLL; PLL0CN |= mainENABLE_PLL;
for( usWait = 0; usWait < usWaitTime; usWait++ ) for( usWait = 0; usWait < usWaitTime; usWait++ )
{ {
if( PLL0CN & mainPLL_LOCKED ) if( PLL0CN & mainPLL_LOCKED )
@ -333,34 +338,32 @@ static void prvToggleOnBoardLED( void )
/* /*
* See the documentation at the top of this file. * See the documentation at the top of this file.
*/ */
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
portBASE_TYPE xErrorHasOccurred = pdFALSE; portBASE_TYPE xErrorHasOccurred = pdFALSE;
/* Just to prevent compiler warnings. */ /* Just to prevent compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The delay period depends on whether an error * operating without error. The delay period depends on whether an error
has ever been detected. */ * has ever been detected. */
for( ;; ) for( ; ; )
{ {
if( xLatchedError == pdFALSE ) if( xLatchedError == pdFALSE )
{ {
/* No errors have been detected so delay for a longer period. The /* No errors have been detected so delay for a longer period. The
on board LED will get toggled every mainNO_ERROR_FLASH_PERIOD ms. */ * on board LED will get toggled every mainNO_ERROR_FLASH_PERIOD ms. */
vTaskDelay( mainNO_ERROR_FLASH_PERIOD ); vTaskDelay( mainNO_ERROR_FLASH_PERIOD );
} }
else else
{ {
/* We have at some time recognised an error in one of the demo /* We have at some time recognised an error in one of the demo
application tasks, delay for a shorter period. The on board LED * application tasks, delay for a shorter period. The on board LED
will get toggled every mainERROR_FLASH_PERIOD ms. */ * will get toggled every mainERROR_FLASH_PERIOD ms. */
vTaskDelay( mainERROR_FLASH_PERIOD ); vTaskDelay( mainERROR_FLASH_PERIOD );
} }
/* Check the demo application tasks for errors. */ /* Check the demo application tasks for errors. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
@ -384,15 +387,15 @@ portBASE_TYPE xErrorHasOccurred = pdFALSE;
} }
/* If an error has occurred, latch it to cause the LED flash rate to /* If an error has occurred, latch it to cause the LED flash rate to
increase. */ * increase. */
if( xErrorHasOccurred == pdTRUE ) if( xErrorHasOccurred == pdTRUE )
{ {
xLatchedError = pdTRUE; xLatchedError = pdTRUE;
} }
/* Toggle the LED to indicate the completion of a check cycle. The /* Toggle the LED to indicate the completion of a check cycle. The
frequency of check cycles is dependent on whether or not we have * frequency of check cycles is dependent on whether or not we have
latched an error. */ * latched an error. */
prvToggleOnBoardLED(); prvToggleOnBoardLED();
} }
} }
@ -402,25 +405,27 @@ portBASE_TYPE xErrorHasOccurred = pdFALSE;
* See the documentation at the top of this file. Also see the standard FLOP * See the documentation at the top of this file. Also see the standard FLOP
* demo task documentation for the rationale of these tasks. * demo task documentation for the rationale of these tasks.
*/ */
static void vFLOPCheck1( void *pvParameters ) static void vFLOPCheck1( void * pvParameters )
{ {
volatile portFLOAT fVal1, fVal2, fResult; volatile portFLOAT fVal1, fVal2, fResult;
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
fVal1 = ( portFLOAT ) -1234.5678; fVal1 = ( portFLOAT ) - 1234.5678;
fVal2 = ( portFLOAT ) 2345.6789; fVal2 = ( portFLOAT ) 2345.6789;
fResult = fVal1 + fVal2; fResult = fVal1 + fVal2;
if( ( fResult > ( portFLOAT ) 1111.15 ) || ( fResult < ( portFLOAT ) 1111.05 ) ) if( ( fResult > ( portFLOAT ) 1111.15 ) || ( fResult < ( portFLOAT ) 1111.05 ) )
{ {
mainLATCH_ERROR(); mainLATCH_ERROR();
} }
fResult = fVal1 / fVal2; fResult = fVal1 / fVal2;
if( ( fResult > ( portFLOAT ) -0.51 ) || ( fResult < ( portFLOAT ) -0.53 ) )
if( ( fResult > ( portFLOAT ) - 0.51 ) || ( fResult < ( portFLOAT ) - 0.53 ) )
{ {
mainLATCH_ERROR(); mainLATCH_ERROR();
} }
@ -431,24 +436,26 @@ volatile portFLOAT fVal1, fVal2, fResult;
/* /*
* See the documentation at the top of this file. * See the documentation at the top of this file.
*/ */
static void vFLOPCheck2( void *pvParameters ) static void vFLOPCheck2( void * pvParameters )
{ {
volatile portFLOAT fVal1, fVal2, fResult; volatile portFLOAT fVal1, fVal2, fResult;
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
fVal1 = ( portFLOAT ) -12340.5678; fVal1 = ( portFLOAT ) - 12340.5678;
fVal2 = ( portFLOAT ) 23450.6789; fVal2 = ( portFLOAT ) 23450.6789;
fResult = fVal1 + fVal2; fResult = fVal1 + fVal2;
if( ( fResult > ( portFLOAT ) 11110.15 ) || ( fResult < ( portFLOAT ) 11110.05 ) ) if( ( fResult > ( portFLOAT ) 11110.15 ) || ( fResult < ( portFLOAT ) 11110.05 ) )
{ {
mainLATCH_ERROR(); mainLATCH_ERROR();
} }
fResult = fVal1 / -fVal2; fResult = fVal1 / -fVal2;
if( ( fResult > ( portFLOAT ) 0.53 ) || ( fResult < ( portFLOAT ) 0.51 ) ) if( ( fResult > ( portFLOAT ) 0.53 ) || ( fResult < ( portFLOAT ) 0.51 ) )
{ {
mainLATCH_ERROR(); mainLATCH_ERROR();
@ -460,11 +467,11 @@ volatile portFLOAT fVal1, fVal2, fResult;
/* /*
* See the documentation at the top of this file. * See the documentation at the top of this file.
*/ */
static void vRegisterCheck( void *pvParameters ) static void vRegisterCheck( void * pvParameters )
{ {
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
if( SP != configSTACK_START ) if( SP != configSTACK_START )
{ {
@ -488,6 +495,7 @@ static void vRegisterCheck( void *pvParameters )
{ {
mainLATCH_ERROR(); mainLATCH_ERROR();
} }
_asm _asm
MOV ACC, ar2 MOV ACC, ar2
_endasm; _endasm;
@ -496,6 +504,7 @@ static void vRegisterCheck( void *pvParameters )
{ {
mainLATCH_ERROR(); mainLATCH_ERROR();
} }
_asm _asm
MOV ACC, ar3 MOV ACC, ar3
_endasm; _endasm;
@ -504,6 +513,7 @@ static void vRegisterCheck( void *pvParameters )
{ {
mainLATCH_ERROR(); mainLATCH_ERROR();
} }
_asm _asm
MOV ACC, ar4 MOV ACC, ar4
_endasm; _endasm;
@ -512,6 +522,7 @@ static void vRegisterCheck( void *pvParameters )
{ {
mainLATCH_ERROR(); mainLATCH_ERROR();
} }
_asm _asm
MOV ACC, ar5 MOV ACC, ar5
_endasm; _endasm;
@ -520,6 +531,7 @@ static void vRegisterCheck( void *pvParameters )
{ {
mainLATCH_ERROR(); mainLATCH_ERROR();
} }
_asm _asm
MOV ACC, ar6 MOV ACC, ar6
_endasm; _endasm;
@ -528,6 +540,7 @@ static void vRegisterCheck( void *pvParameters )
{ {
mainLATCH_ERROR(); mainLATCH_ERROR();
} }
_asm _asm
MOV ACC, ar7 MOV ACC, ar7
_endasm; _endasm;
@ -553,5 +566,3 @@ static void vRegisterCheck( void *pvParameters )
} }
} }
} }

View file

@ -56,27 +56,27 @@
*/ */
/* /*
Changes from V1.01: * Changes from V1.01:
*
+ Previously, if an error occurred in a task the on board LED was stopped from + Previously, if an error occurred in a task the on board LED was stopped from
toggling. Now if an error occurs the check task enters an infinite loop, + toggling. Now if an error occurs the check task enters an infinite loop,
toggling the LED rapidly. + toggling the LED rapidly.
+
Changes from V1.2.3 + Changes from V1.2.3
+
+ The integer and comtest tasks are now used when the cooperative scheduler + The integer and comtest tasks are now used when the cooperative scheduler
is being used. Previously they were only used with the preemptive + is being used. Previously they were only used with the preemptive
scheduler. + scheduler.
+
Changes from V1.2.5 + Changes from V1.2.5
+
+ Made the communications RX task a higher priority. + Made the communications RX task a higher priority.
+
Changes from V2.0.0 + Changes from V2.0.0
+
+ Delay periods are now specified using variables and constants of + Delay periods are now specified using variables and constants of
TickType_t rather than unsigned long. + TickType_t rather than unsigned long.
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <conio.h> #include <conio.h>
@ -113,14 +113,14 @@ Changes from V2.0.0
#define mainLED_REG ( ( unsigned short ) 0xff7a ) #define mainLED_REG ( ( unsigned short ) 0xff7a )
/* If an error is detected in a task then the vErrorChecks() task will enter /* If an error is detected in a task then the vErrorChecks() task will enter
an infinite loop flashing the LED at this rate. */ * an infinite loop flashing the LED at this rate. */
#define mainERROR_FLASH_RATE ( ( TickType_t ) 100 / portTICK_PERIOD_MS ) #define mainERROR_FLASH_RATE ( ( TickType_t ) 100 / portTICK_PERIOD_MS )
/* Task function for the "Print" task as described at the top of the file. */ /* Task function for the "Print" task as described at the top of the file. */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* Function that checks the unique count of all the other tasks as described at /* Function that checks the unique count of all the other tasks as described at
the top of the file. */ * the top of the file. */
static void prvCheckOtherTasksAreStillRunning( void ); static void prvCheckOtherTasksAreStillRunning( void );
/* Functions to setup and use the built in LED on the Flashlite 186 board. */ /* Functions to setup and use the built in LED on the Flashlite 186 board. */
@ -128,7 +128,7 @@ static void prvToggleLED( void );
static void prvInitLED( void ); static void prvInitLED( void );
/* Key presses can be used to start/stop the trace visualisation utility or stop /* Key presses can be used to start/stop the trace visualisation utility or stop
the scheduler. */ * the scheduler. */
static void prvCheckForKeyPresses( void ); static void prvCheckForKeyPresses( void );
/* Buffer used by the trace visualisation utility. */ /* Buffer used by the trace visualisation utility. */
@ -155,54 +155,54 @@ short main( void )
xTaskCreate( vErrorChecks, "Print", mainPRINT_STACK_SIZE, NULL, mainPRINT_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Print", mainPRINT_STACK_SIZE, NULL, mainPRINT_TASK_PRIORITY, NULL );
/* This task has to be created last as it keeps account of the number of tasks /* This task has to be created last as it keeps account of the number of tasks
it expects to see running. */ * it expects to see running. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Set the scheduler running. This function will not return unless a task /* Set the scheduler running. This function will not return unless a task
calls vTaskEndScheduler(). */ * calls vTaskEndScheduler(). */
vTaskStartScheduler(); vTaskStartScheduler();
return 1; return 1;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xExpectedWakeTime; TickType_t xExpectedWakeTime;
const TickType_t xPrintRate = ( TickType_t ) 5000 / portTICK_PERIOD_MS; const TickType_t xPrintRate = ( TickType_t ) 5000 / portTICK_PERIOD_MS;
const long lMaxAllowableTimeDifference = ( long ) 0; const long lMaxAllowableTimeDifference = ( long ) 0;
TickType_t xWakeTime; TickType_t xWakeTime;
long lTimeDifference; long lTimeDifference;
const char *pcReceivedMessage; const char * pcReceivedMessage;
const char * const pcTaskBlockedTooLongMsg = "Print task blocked too long!\r\n"; const char * const pcTaskBlockedTooLongMsg = "Print task blocked too long!\r\n";
/* Stop warnings. */ /* Stop warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Loop continuously, blocking, then checking all the other tasks are still /* Loop continuously, blocking, then checking all the other tasks are still
running, before blocking once again. This task blocks on the queue of messages * running, before blocking once again. This task blocks on the queue of messages
that require displaying so will wake either by its time out expiring, or a * that require displaying so will wake either by its time out expiring, or a
message becoming available. */ * message becoming available. */
for( ;; ) for( ; ; )
{ {
/* Calculate the time we will unblock if no messages are received /* Calculate the time we will unblock if no messages are received
on the queue. This is used to check that we have not blocked for too long. */ * on the queue. This is used to check that we have not blocked for too long. */
xExpectedWakeTime = xTaskGetTickCount(); xExpectedWakeTime = xTaskGetTickCount();
xExpectedWakeTime += xPrintRate; xExpectedWakeTime += xPrintRate;
/* Block waiting for either a time out or a message to be posted that /* Block waiting for either a time out or a message to be posted that
required displaying. */ * required displaying. */
pcReceivedMessage = pcPrintGetNextMessage( xPrintRate ); pcReceivedMessage = pcPrintGetNextMessage( xPrintRate );
/* Was a message received? */ /* Was a message received? */
if( pcReceivedMessage == NULL ) if( pcReceivedMessage == NULL )
{ {
/* A message was not received so we timed out, did we unblock at the /* A message was not received so we timed out, did we unblock at the
expected time? */ * expected time? */
xWakeTime = xTaskGetTickCount(); xWakeTime = xTaskGetTickCount();
/* Calculate the difference between the time we unblocked and the /* Calculate the difference between the time we unblocked and the
time we should have unblocked. */ * time we should have unblocked. */
if( xWakeTime > xExpectedWakeTime ) if( xWakeTime > xExpectedWakeTime )
{ {
lTimeDifference = ( long ) ( xWakeTime - xExpectedWakeTime ); lTimeDifference = ( long ) ( xWakeTime - xExpectedWakeTime );
@ -215,7 +215,7 @@ const char * const pcTaskBlockedTooLongMsg = "Print task blocked too long!\r\n";
if( lTimeDifference > lMaxAllowableTimeDifference ) if( lTimeDifference > lMaxAllowableTimeDifference )
{ {
/* We blocked too long - create a message that will get /* We blocked too long - create a message that will get
printed out the next time around. */ * printed out the next time around. */
vPrintDisplayMessage( &pcTaskBlockedTooLongMsg ); vPrintDisplayMessage( &pcTaskBlockedTooLongMsg );
} }
@ -225,12 +225,12 @@ const char * const pcTaskBlockedTooLongMsg = "Print task blocked too long!\r\n";
else else
{ {
/* We unblocked due to a message becoming available. Send the message /* We unblocked due to a message becoming available. Send the message
for printing. */ * for printing. */
vDisplayMessage( pcReceivedMessage ); vDisplayMessage( pcReceivedMessage );
} }
/* Key presses are used to invoke the trace visualisation utility, or /* Key presses are used to invoke the trace visualisation utility, or
end the program. */ * end the program. */
prvCheckForKeyPresses(); prvCheckForKeyPresses();
} }
} /*lint !e715 !e818 pvParameters is not used but all task functions must take this form. */ } /*lint !e715 !e818 pvParameters is not used but all task functions must take this form. */
@ -239,7 +239,6 @@ const char * const pcTaskBlockedTooLongMsg = "Print task blocked too long!\r\n";
static void prvCheckForKeyPresses( void ) static void prvCheckForKeyPresses( void )
{ {
#ifdef USE_STDIO #ifdef USE_STDIO
short sIn; short sIn;
@ -252,40 +251,42 @@ static void prvCheckForKeyPresses( void )
unsigned long ulBufferLength; unsigned long ulBufferLength;
/* Key presses can be used to start/stop the trace utility, or end the /* Key presses can be used to start/stop the trace utility, or end the
program. */ * program. */
sIn = getch(); sIn = getch();
switch( sIn ) switch( sIn )
{ {
/* Only define keys for turning on and off the trace if the trace /* Only define keys for turning on and off the trace if the trace
is being used. */ * is being used. */
#if configUSE_TRACE_FACILITY == 1 #if configUSE_TRACE_FACILITY == 1
case 't' : vTaskList( pcWriteBuffer ); case 't':
vTaskList( pcWriteBuffer );
vWriteMessageToDisk( pcWriteBuffer ); vWriteMessageToDisk( pcWriteBuffer );
break; break;
/* The legacy trace is no longer supported. Use FreeRTOS+Trace instead. /* The legacy trace is no longer supported. Use FreeRTOS+Trace instead.
case 's' : vTaskStartTrace( pcWriteBuffer, mainDEBUG_LOG_BUFFER_SIZE ); * case 's' : vTaskStartTrace( pcWriteBuffer, mainDEBUG_LOG_BUFFER_SIZE );
break; * break;
*
case 'e' : ulBufferLength = ulTaskEndTrace(); * case 'e' : ulBufferLength = ulTaskEndTrace();
vWriteBufferToDisk( pcWriteBuffer, ulBufferLength ); * vWriteBufferToDisk( pcWriteBuffer, ulBufferLength );
break;*/ * break;*/
#endif #endif
default : vTaskEndScheduler(); default:
vTaskEndScheduler();
break; break;
} }
} }
#else /* ifdef USE_STDIO */
#else
( void ) pcWriteBuffer; ( void ) pcWriteBuffer;
#endif #endif /* ifdef USE_STDIO */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckOtherTasksAreStillRunning( void ) static void prvCheckOtherTasksAreStillRunning( void )
{ {
short sErrorHasOccurred = pdFALSE; short sErrorHasOccurred = pdFALSE;
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreComTestTasksStillRunning() != pdTRUE )
{ {
@ -326,16 +327,17 @@ short sErrorHasOccurred = pdFALSE;
if( sErrorHasOccurred == pdFALSE ) if( sErrorHasOccurred == pdFALSE )
{ {
vDisplayMessage( "OK " ); vDisplayMessage( "OK " );
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
prvToggleLED(); prvToggleLED();
} }
else else
{ {
for( ;; ) for( ; ; )
{ {
/* An error has occurred in one of the tasks. Don't go any further and /* An error has occurred in one of the tasks. Don't go any further and
flash the LED rapidly in case console IO is not being used. */ * flash the LED rapidly in case console IO is not being used. */
prvToggleLED(); prvToggleLED();
vTaskDelay( mainERROR_FLASH_RATE ); vTaskDelay( mainERROR_FLASH_RATE );
} }
@ -345,8 +347,8 @@ short sErrorHasOccurred = pdFALSE;
static void prvInitLED( void ) static void prvInitLED( void )
{ {
unsigned short usPortDirection; unsigned short usPortDirection;
const unsigned short usLEDOut = 0x400; const unsigned short usLEDOut = 0x400;
/* Set the LED bit to an output. */ /* Set the LED bit to an output. */
@ -358,12 +360,13 @@ const unsigned short usLEDOut = 0x400;
static void prvToggleLED( void ) static void prvToggleLED( void )
{ {
static short sLED = pdTRUE; static short sLED = pdTRUE;
unsigned short usLEDState; unsigned short usLEDState;
const unsigned short usLEDBit = 0x400; const unsigned short usLEDBit = 0x400;
/* Flip the state of the LED. */ /* Flip the state of the LED. */
usLEDState = inpw( mainLED_REG ); usLEDState = inpw( mainLED_REG );
if( sLED ) if( sLED )
{ {
usLEDState &= ~usLEDBit; usLEDState &= ~usLEDBit;
@ -372,9 +375,8 @@ const unsigned short usLEDBit = 0x400;
{ {
usLEDState |= usLEDBit; usLEDState |= usLEDBit;
} }
outpw( mainLED_REG, usLEDState ); outpw( mainLED_REG, usLEDState );
sLED = !sLED; sLED = !sLED;
} }

View file

@ -1,4 +1,3 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
@ -69,8 +68,8 @@
/*----------------------------------------------------------- /*-----------------------------------------------------------
Definitions. * Definitions.
-----------------------------------------------------------*/ * -----------------------------------------------------------*/
/* Priorities assigned to demo application tasks. */ /* Priorities assigned to demo application tasks. */
#define mainFLASH_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainFLASH_PRIORITY ( tskIDLE_PRIORITY + 2 )
@ -81,9 +80,9 @@
#define mainDEATH_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainDEATH_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled with mainCHECK_PERIOD frequency. If an error is found * the LED is toggled with mainCHECK_PERIOD frequency. If an error is found
then the toggle rate increases to mainERROR_CHECK_PERIOD. */ * then the toggle rate increases to mainERROR_CHECK_PERIOD. */
#define mainCHECK_TASK_LED ( 7 ) #define mainCHECK_TASK_LED ( 7 )
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_CHECK_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainERROR_CHECK_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
@ -97,28 +96,28 @@ then the toggle rate increases to mainERROR_CHECK_PERIOD. */
/* Baud rate used by the serial port tasks (ComTest tasks). /* Baud rate used by the serial port tasks (ComTest tasks).
IMPORTANT: The function COM0_SetBaudRateValue() which is generated by the * IMPORTANT: The function COM0_SetBaudRateValue() which is generated by the
Processor Expert is used to set the baud rate. As configured in the FreeRTOS * Processor Expert is used to set the baud rate. As configured in the FreeRTOS
download this value must be one of the following: * download this value must be one of the following:
*
0 to configure for 38400 baud. * 0 to configure for 38400 baud.
1 to configure for 19200 baud. * 1 to configure for 19200 baud.
2 to configure for 9600 baud. * 2 to configure for 9600 baud.
3 to configure for 4800 baud. */ * 3 to configure for 4800 baud. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 2 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 2 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
/*----------------------------------------------------------- /*-----------------------------------------------------------
Local functions prototypes. * Local functions prototypes.
-----------------------------------------------------------*/ * -----------------------------------------------------------*/
/* /*
* The 'Check' task function. See the explanation at the top of the file. * The 'Check' task function. See the explanation at the top of the file.
*/ */
static void vErrorChecks( void* pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* The idle task hook - in which the integer task is implemented. See the * The idle task hook - in which the integer task is implemented. See the
@ -134,12 +133,12 @@ static long prvCheckOtherTasksAreStillRunning( void );
/*----------------------------------------------------------- /*-----------------------------------------------------------
Local variables. * Local variables.
-----------------------------------------------------------*/ * -----------------------------------------------------------*/
/* A few tasks are defined within this file. This flag is used to indicate /* A few tasks are defined within this file. This flag is used to indicate
their status. If an error is detected in one of the locally defined tasks then * their status. If an error is detected in one of the locally defined tasks then
this flag is set to pdTRUE. */ * this flag is set to pdTRUE. */
portBASE_TYPE xLocalError = pdFALSE; portBASE_TYPE xLocalError = pdFALSE;
@ -159,7 +158,7 @@ void vMain( void )
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
/* Start the locally defined tasks. There is also a task implemented as /* Start the locally defined tasks. There is also a task implemented as
the idle hook. */ * the idle hook. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Must be the last demo created. */ /* Must be the last demo created. */
@ -169,29 +168,31 @@ void vMain( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Should not reach here! */ /* Should not reach here! */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainCHECK_PERIOD; TickType_t xDelayPeriod = mainCHECK_PERIOD;
TickType_t xLastWakeTime; TickType_t xLastWakeTime;
/* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil() /* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil()
functions correctly. */ * functions correctly. */
xLastWakeTime = xTaskGetTickCount(); xLastWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. The delay period is /* Delay until it is time to execute again. The delay period is
shorter following an error. */ * shorter following an error. */
vTaskDelayUntil( &xLastWakeTime, xDelayPeriod ); vTaskDelayUntil( &xLastWakeTime, xDelayPeriod );
/* Check all the demo application tasks are executing without /* Check all the demo application tasks are executing without
error. If an error is found the delay period is shortened - this * error. If an error is found the delay period is shortened - this
has the effect of increasing the flash rate of the 'check' task * has the effect of increasing the flash rate of the 'check' task
LED. */ * LED. */
if( prvCheckOtherTasksAreStillRunning() == pdFAIL ) if( prvCheckOtherTasksAreStillRunning() == pdFAIL )
{ {
/* An error has been detected in one of the tasks - flash faster. */ /* An error has been detected in one of the tasks - flash faster. */
@ -206,7 +207,7 @@ TickType_t xLastWakeTime;
static long prvCheckOtherTasksAreStillRunning( void ) static long prvCheckOtherTasksAreStillRunning( void )
{ {
portBASE_TYPE xAllTasksPassed = pdPASS; portBASE_TYPE xAllTasksPassed = pdPASS;
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
@ -251,13 +252,13 @@ portBASE_TYPE xAllTasksPassed = pdPASS;
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* This variable is effectively set to a constant so it is made volatile to /* This variable is effectively set to a constant so it is made volatile to
ensure the compiler does not just get rid of it. */ * ensure the compiler does not just get rid of it. */
volatile long lValue; volatile long lValue;
/* Keep performing a calculation and checking the result against a constant. */ /* Keep performing a calculation and checking the result against a constant. */
/* Perform the calculation. This will store partial value in /* Perform the calculation. This will store partial value in
registers, resulting in a good test of the context switch mechanism. */ * registers, resulting in a good test of the context switch mechanism. */
lValue = intgCONST1; lValue = intgCONST1;
lValue += intgCONST2; lValue += intgCONST2;
lValue *= intgCONST3; lValue *= intgCONST3;
@ -280,6 +281,3 @@ volatile long lValue;
#endif #endif
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -98,8 +98,8 @@
#include "ButtonInterrupt.h" #include "ButtonInterrupt.h"
/*----------------------------------------------------------- /*-----------------------------------------------------------
Definitions. * Definitions.
-----------------------------------------------------------*/ * -----------------------------------------------------------*/
/* Priorities assigned to demo application tasks. */ /* Priorities assigned to demo application tasks. */
#define mainFLASH_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainFLASH_PRIORITY ( tskIDLE_PRIORITY + 2 )
@ -108,9 +108,9 @@
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled with mainCHECK_PERIOD frequency. If an error is found * the LED is toggled with mainCHECK_PERIOD frequency. If an error is found
then the toggle rate increases to mainERROR_CHECK_PERIOD. */ * then the toggle rate increases to mainERROR_CHECK_PERIOD. */
#define mainCHECK_TASK_LED ( 7 ) #define mainCHECK_TASK_LED ( 7 )
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_CHECK_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainERROR_CHECK_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
@ -126,22 +126,22 @@ then the toggle rate increases to mainERROR_CHECK_PERIOD. */
#define intgEXPECTED_ANSWER ( ( ( intgCONST1 + intgCONST2 ) * intgCONST3 ) / intgCONST4 ) #define intgEXPECTED_ANSWER ( ( ( intgCONST1 + intgCONST2 ) * intgCONST3 ) / intgCONST4 )
/* The length of the queue between is button push ISR and the Button Push task /* The length of the queue between is button push ISR and the Button Push task
is greater than 1 to account for switch bounces generating multiple inputs. */ * is greater than 1 to account for switch bounces generating multiple inputs. */
#define mainBUTTON_QUEUE_SIZE 6 #define mainBUTTON_QUEUE_SIZE 6
/*----------------------------------------------------------- /*-----------------------------------------------------------
Local functions prototypes. * Local functions prototypes.
-----------------------------------------------------------*/ * -----------------------------------------------------------*/
/* /*
* The 'Check' task function. See the explanation at the top of the file. * The 'Check' task function. See the explanation at the top of the file.
*/ */
static void vErrorChecks( void* pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* The 'Button Push' task. See the explanation at the top of the file. * The 'Button Push' task. See the explanation at the top of the file.
*/ */
static void vButtonTask( void *pvParameters ); static void vButtonTask( void * pvParameters );
/* /*
* The idle task hook - in which the integer task is implemented. See the * The idle task hook - in which the integer task is implemented. See the
@ -157,16 +157,16 @@ static long prvCheckOtherTasksAreStillRunning( void );
/*----------------------------------------------------------- /*-----------------------------------------------------------
Local variables. * Local variables.
-----------------------------------------------------------*/ * -----------------------------------------------------------*/
/* A few tasks are defined within this file. This flag is used to indicate /* A few tasks are defined within this file. This flag is used to indicate
their status. If an error is detected in one of the locally defined tasks then * their status. If an error is detected in one of the locally defined tasks then
this flag is set to pdTRUE. */ * this flag is set to pdTRUE. */
portBASE_TYPE xLocalError = pdFALSE; portBASE_TYPE xLocalError = pdFALSE;
/* The queue used to send data from the button push ISR to the Button Push /* The queue used to send data from the button push ISR to the Button Push
task. */ * task. */
static QueueHandle_t xButtonQueue; static QueueHandle_t xButtonQueue;
@ -183,7 +183,7 @@ void vMain( void )
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
/* Start the locally defined tasks. There is also a task implemented as /* Start the locally defined tasks. There is also a task implemented as
the idle hook. */ * the idle hook. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
xTaskCreate( vButtonTask, "Button", configMINIMAL_STACK_SIZE, NULL, mainBUTTON_TASK_PRIORITY, NULL ); xTaskCreate( vButtonTask, "Button", configMINIMAL_STACK_SIZE, NULL, mainBUTTON_TASK_PRIORITY, NULL );
@ -191,29 +191,31 @@ void vMain( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Should not reach here! */ /* Should not reach here! */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainCHECK_PERIOD; TickType_t xDelayPeriod = mainCHECK_PERIOD;
TickType_t xLastWakeTime; TickType_t xLastWakeTime;
/* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil() /* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil()
functions correctly. */ * functions correctly. */
xLastWakeTime = xTaskGetTickCount(); xLastWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. The delay period is /* Delay until it is time to execute again. The delay period is
shorter following an error. */ * shorter following an error. */
vTaskDelayUntil( &xLastWakeTime, xDelayPeriod ); vTaskDelayUntil( &xLastWakeTime, xDelayPeriod );
/* Check all the demo application tasks are executing without /* Check all the demo application tasks are executing without
error. If an error is found the delay period is shortened - this * error. If an error is found the delay period is shortened - this
has the effect of increasing the flash rate of the 'check' task * has the effect of increasing the flash rate of the 'check' task
LED. */ * LED. */
if( prvCheckOtherTasksAreStillRunning() == pdFAIL ) if( prvCheckOtherTasksAreStillRunning() == pdFAIL )
{ {
/* An error has been detected in one of the tasks - flash faster. */ /* An error has been detected in one of the tasks - flash faster. */
@ -228,7 +230,7 @@ TickType_t xLastWakeTime;
static long prvCheckOtherTasksAreStillRunning( void ) static long prvCheckOtherTasksAreStillRunning( void )
{ {
portBASE_TYPE xAllTasksPassed = pdPASS; portBASE_TYPE xAllTasksPassed = pdPASS;
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
@ -253,14 +255,14 @@ portBASE_TYPE xAllTasksPassed = pdPASS;
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* This variable is effectively set to a constant so it is made volatile to /* This variable is effectively set to a constant so it is made volatile to
ensure the compiler does not just get rid of it. */ * ensure the compiler does not just get rid of it. */
volatile long lValue; volatile long lValue;
/* Keep performing a calculation and checking the result against a constant. */ /* Keep performing a calculation and checking the result against a constant. */
for( ;; ) for( ; ; )
{ {
/* Perform the calculation. This will store partial value in /* Perform the calculation. This will store partial value in
registers, resulting in a good test of the context switch mechanism. */ * registers, resulting in a good test of the context switch mechanism. */
lValue = intgCONST1; lValue = intgCONST1;
lValue += intgCONST2; lValue += intgCONST2;
lValue *= intgCONST3; lValue *= intgCONST3;
@ -285,9 +287,9 @@ volatile long lValue;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vButtonTask( void *pvParameters ) static void vButtonTask( void * pvParameters )
{ {
unsigned portBASE_TYPE uxExpected = 1, uxReceived; unsigned portBASE_TYPE uxExpected = 1, uxReceived;
/* Create the queue used by the producer and consumer. */ /* Create the queue used by the producer and consumer. */
xButtonQueue = xQueueCreate( mainBUTTON_QUEUE_SIZE, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) ); xButtonQueue = xQueueCreate( mainBUTTON_QUEUE_SIZE, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) );
@ -297,7 +299,7 @@ unsigned portBASE_TYPE uxExpected = 1, uxReceived;
/* Now the queue is created it is safe to enable the button interrupt. */ /* Now the queue is created it is safe to enable the button interrupt. */
ButtonInterrupt_Enable(); ButtonInterrupt_Enable();
for( ;; ) for( ; ; )
{ {
/* Simply wait for data to arrive from the button push interrupt. */ /* Simply wait for data to arrive from the button push interrupt. */
if( xQueueReceive( xButtonQueue, &uxReceived, portMAX_DELAY ) == pdPASS ) if( xQueueReceive( xButtonQueue, &uxReceived, portMAX_DELAY ) == pdPASS )
@ -322,15 +324,17 @@ unsigned portBASE_TYPE uxExpected = 1, uxReceived;
} }
/* Will only get here if the queue could not be created. */ /* Will only get here if the queue could not be created. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#pragma CODE_SEG __NEAR_SEG NON_BANKED #pragma CODE_SEG __NEAR_SEG NON_BANKED
/* Button push ISR. */ /* Button push ISR. */
void interrupt vButtonPush( void ) void interrupt vButtonPush( void )
{ {
static unsigned portBASE_TYPE uxValToSend = 0; static unsigned portBASE_TYPE uxValToSend = 0;
static unsigned long xHigherPriorityTaskWoken; static unsigned long xHigherPriorityTaskWoken;
@ -343,21 +347,19 @@ unsigned portBASE_TYPE uxExpected = 1, uxReceived;
PIFP = 1; PIFP = 1;
/* Send the incremented value down the queue. The button push task is /* Send the incremented value down the queue. The button push task is
blocked waiting for the data. As the button push task is high priority * blocked waiting for the data. As the button push task is high priority
it will wake and a context switch should be performed before leaving * it will wake and a context switch should be performed before leaving
the ISR. */ * the ISR. */
xQueueSendFromISR( xButtonQueue, &uxValToSend, &xHigherPriorityTaskWoken ); xQueueSendFromISR( xButtonQueue, &uxValToSend, &xHigherPriorityTaskWoken );
if( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken )
{ {
/* NOTE: This macro can only be used if there are no local /* NOTE: This macro can only be used if there are no local
variables defined. This function uses a static variable so it's * variables defined. This function uses a static variable so it's
use is permitted. If the variable were not static portYIELD() * use is permitted. If the variable were not static portYIELD()
would have to be used in it's place. */ * would have to be used in it's place. */
portTASK_SWITCH_FROM_ISR(); portTASK_SWITCH_FROM_ISR();
} }
} }
#pragma CODE_SEG DEFAULT #pragma CODE_SEG DEFAULT

View file

@ -1,4 +1,3 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
@ -72,8 +71,8 @@ portBASE_TYPE xArePollingQueuesStillRunning( void );
/*----------------------------------------------------------- /*-----------------------------------------------------------
Definitions. * Definitions.
-----------------------------------------------------------*/ * -----------------------------------------------------------*/
/* Priorities assigned to demo application tasks. */ /* Priorities assigned to demo application tasks. */
#define mainFLASH_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainFLASH_PRIORITY ( tskIDLE_PRIORITY + 2 )
@ -84,9 +83,9 @@ portBASE_TYPE xArePollingQueuesStillRunning( void );
#define mainDEATH_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainDEATH_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled with mainCHECK_PERIOD frequency. If an error is found * the LED is toggled with mainCHECK_PERIOD frequency. If an error is found
then the toggle rate increases to mainERROR_CHECK_PERIOD. */ * then the toggle rate increases to mainERROR_CHECK_PERIOD. */
#define mainCHECK_TASK_LED ( 7 ) #define mainCHECK_TASK_LED ( 7 )
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_CHECK_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainERROR_CHECK_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
@ -100,28 +99,28 @@ then the toggle rate increases to mainERROR_CHECK_PERIOD. */
/* Baud rate used by the serial port tasks (ComTest tasks). /* Baud rate used by the serial port tasks (ComTest tasks).
IMPORTANT: The function COM0_SetBaudRateValue() which is generated by the * IMPORTANT: The function COM0_SetBaudRateValue() which is generated by the
Processor Expert is used to set the baud rate. As configured in the FreeRTOS * Processor Expert is used to set the baud rate. As configured in the FreeRTOS
download this value must be one of the following: * download this value must be one of the following:
*
0 to configure for 38400 baud. * 0 to configure for 38400 baud.
1 to configure for 19200 baud. * 1 to configure for 19200 baud.
2 to configure for 9600 baud. * 2 to configure for 9600 baud.
3 to configure for 4800 baud. */ * 3 to configure for 4800 baud. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 2 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 2 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
/*----------------------------------------------------------- /*-----------------------------------------------------------
Local functions prototypes. * Local functions prototypes.
-----------------------------------------------------------*/ * -----------------------------------------------------------*/
/* /*
* The 'Check' task function. See the explanation at the top of the file. * The 'Check' task function. See the explanation at the top of the file.
*/ */
static void ATTR_BANK1 vErrorChecks( void* pvParameters ); static void ATTR_BANK1 vErrorChecks( void * pvParameters );
/* /*
* The idle task hook - in which the integer task is implemented. See the * The idle task hook - in which the integer task is implemented. See the
@ -137,19 +136,19 @@ static long ATTR_BANK0 prvCheckOtherTasksAreStillRunning( void );
/*----------------------------------------------------------- /*-----------------------------------------------------------
Local variables. * Local variables.
-----------------------------------------------------------*/ * -----------------------------------------------------------*/
/* A few tasks are defined within this file. This flag is used to indicate /* A few tasks are defined within this file. This flag is used to indicate
their status. If an error is detected in one of the locally defined tasks then * their status. If an error is detected in one of the locally defined tasks then
this flag is set to pdTRUE. */ * this flag is set to pdTRUE. */
portBASE_TYPE xLocalError = pdFALSE; portBASE_TYPE xLocalError = pdFALSE;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* This is called from startup. */ /* This is called from startup. */
int ATTR_BANK0 main ( void ) int ATTR_BANK0 main( void )
{ {
/* Start some of the standard demo tasks. */ /* Start some of the standard demo tasks. */
vStartLEDFlashTasks( mainFLASH_PRIORITY ); vStartLEDFlashTasks( mainFLASH_PRIORITY );
@ -160,7 +159,7 @@ int ATTR_BANK0 main ( void )
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
/* Start the locally defined tasks. There is also a task implemented as /* Start the locally defined tasks. There is also a task implemented as
the idle hook. */ * the idle hook. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Must be the last demo created. */ /* Must be the last demo created. */
@ -170,30 +169,33 @@ int ATTR_BANK0 main ( void )
vTaskStartScheduler(); vTaskStartScheduler();
/* Should not reach here! */ /* Should not reach here! */
for( ;; ); for( ; ; )
{
}
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainCHECK_PERIOD; TickType_t xDelayPeriod = mainCHECK_PERIOD;
TickType_t xLastWakeTime; TickType_t xLastWakeTime;
/* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil() /* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil()
functions correctly. */ * functions correctly. */
xLastWakeTime = xTaskGetTickCount(); xLastWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. The delay period is /* Delay until it is time to execute again. The delay period is
shorter following an error. */ * shorter following an error. */
vTaskDelayUntil( &xLastWakeTime, xDelayPeriod ); vTaskDelayUntil( &xLastWakeTime, xDelayPeriod );
/* Check all the demo application tasks are executing without /* Check all the demo application tasks are executing without
error. If an error is found the delay period is shortened - this * error. If an error is found the delay period is shortened - this
has the effect of increasing the flash rate of the 'check' task * has the effect of increasing the flash rate of the 'check' task
LED. */ * LED. */
if( prvCheckOtherTasksAreStillRunning() == pdFAIL ) if( prvCheckOtherTasksAreStillRunning() == pdFAIL )
{ {
/* An error has been detected in one of the tasks - flash faster. */ /* An error has been detected in one of the tasks - flash faster. */
@ -208,7 +210,7 @@ TickType_t xLastWakeTime;
static long prvCheckOtherTasksAreStillRunning( void ) static long prvCheckOtherTasksAreStillRunning( void )
{ {
portBASE_TYPE xAllTasksPassed = pdPASS; portBASE_TYPE xAllTasksPassed = pdPASS;
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
@ -253,13 +255,13 @@ portBASE_TYPE xAllTasksPassed = pdPASS;
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* This variable is effectively set to a constant so it is made volatile to /* This variable is effectively set to a constant so it is made volatile to
ensure the compiler does not just get rid of it. */ * ensure the compiler does not just get rid of it. */
volatile long lValue; volatile long lValue;
/* Keep performing a calculation and checking the result against a constant. */ /* Keep performing a calculation and checking the result against a constant. */
/* Perform the calculation. This will store partial value in /* Perform the calculation. This will store partial value in
registers, resulting in a good test of the context switch mechanism. */ * registers, resulting in a good test of the context switch mechanism. */
lValue = intgCONST1; lValue = intgCONST1;
lValue += intgCONST2; lValue += intgCONST2;
lValue *= intgCONST3; lValue *= intgCONST3;
@ -282,4 +284,3 @@ volatile long lValue;
#endif #endif
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

Some files were not shown because too many files have changed in this diff Show more