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/AVR_ATMega4809_Atmel_Studio/RTOSDemo/.*',
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_IAR/STLibrary/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_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_TCP_Echo_Posix/Trace_Recorder_Configuration/.*',
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.
The processor MUST be in supervisor mode when vTaskStartScheduler is
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
these demo application projects then ensure Supervisor mode is used.
*/
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* The processor MUST be in supervisor mode when vTaskStartScheduler is
* 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
* these demo application projects then ensure Supervisor mode is used.
*/
/*
@ -96,7 +96,7 @@
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* 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 mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
#define mainON_BOARD_LED_BIT ( ( unsigned long ) 7 )
@ -113,7 +113,7 @@ error. */
#define MAX_WAIT_STATES 8
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,
WaitState2,
WaitState3,
@ -136,14 +136,14 @@ static long prvCheckOtherTasksAreStillRunning( unsigned long ulMemCheckTaskCount
* prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file.
*/
static void vErrorChecks( void *pvParameters );
static void vErrorChecks( void * pvParameters );
/*
* Dynamically created and deleted during each cycle of the vErrorChecks()
* task. This is done to check the operation of the memory allocator.
* 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
@ -175,12 +175,12 @@ int main( void )
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Now all the tasks have been started - start the scheduler.
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is
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
these demo application projects then ensure Supervisor mode is used here. */
*
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* The processor MUST be in supervisor mode when vTaskStartScheduler is
* 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
* these demo application projects then ensure Supervisor mode is used here. */
vTaskStartScheduler();
/* 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;
unsigned long ulMemCheckTaskRunningCount;
TaskHandle_t xCreatedTask;
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
unsigned long ulMemCheckTaskRunningCount;
TaskHandle_t xCreatedTask;
/* Just to stop compiler warnings. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase.
* operating without error. If an error is detected then the delay period
* is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
* 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
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( ;; )
for( ; ; )
{
/* 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;
/* Dynamically create a task - passing ulMemCheckTaskRunningCount as a
parameter. */
* parameter. */
ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;
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. */
@ -233,8 +234,8 @@ TaskHandle_t xCreatedTask;
}
/* Check all the standard demo application tasks are executing without
error. ulMemCheckTaskRunningCount is checked to ensure it was
modified by the task just deleted. */
* error. ulMemCheckTaskRunningCount is checked to ensure it was
* modified by the task just deleted. */
if( prvCheckOtherTasksAreStillRunning( ulMemCheckTaskRunningCount ) != pdPASS )
{
/* 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.
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 );
}
}
@ -250,7 +251,7 @@ TaskHandle_t xCreatedTask;
static void prvSetupHardware( void )
{
long lCount;
long lCount;
#ifdef RUN_FROM_ROM
{
@ -259,16 +260,16 @@ long lCount;
unsigned long ulCSRWaitValue;
/* 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
(flash @ 0x00000000, RAM @ 0x00300000), and set up the
proper flash wait states (starts out at the maximum number
of wait states on reset, so we should be able to reduce it).
Most of this code will probably get removed by the compiler
if optimization is enabled, since these calculations are
based on constants. But the compiler should still produce
a correct wait state register value. */
* Leave the RAM/flash mapped the way they are on reset
* (flash @ 0x00000000, RAM @ 0x00300000), and set up the
* proper flash wait states (starts out at the maximum number
* of wait states on reset, so we should be able to reduce it).
* Most of this code will probably get removed by the compiler
* if optimization is enabled, since these calculations are
* based on constants. But the compiler should still produce
* a correct wait state register value. */
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 )
{
@ -291,11 +292,11 @@ long lCount;
#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
be mapped at 0x00000000. This is typically done with an initialization
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. */
* be mapped at 0x00000000. This is typically done with an initialization
* 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. */
}
#endif
#endif /* ifdef RUN_FROM_ROM */
/* Disable all interrupts at the AIC level initially... */
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)... */
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;
}
@ -314,7 +315,7 @@ long lCount;
AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF;
/* Perform 8 "End Of Interrupt" cmds to make sure AIC will not Lock out
nIRQ */
* nIRQ */
for( lCount = 0; lCount < 8; lCount++ )
{
AT91C_BASE_AIC->AIC_EOICR = 0;
@ -327,11 +328,11 @@ long lCount;
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
that they are all still running, and that none of them have detected
an error. */
* that they are all still running, and that none of them have detected
* an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
@ -371,7 +372,7 @@ long lReturn = ( long ) pdPASS;
if( ulMemCheckTaskCount == mainCOUNT_INITIAL_VALUE )
{
/* The vMemCheckTask did not increment the counter - it must
have failed. */
* have failed. */
lReturn = ( long ) pdFAIL;
}
@ -379,26 +380,26 @@ long lReturn = ( long ) pdPASS;
}
/*-----------------------------------------------------------*/
static void vMemCheckTask( void *pvParameters )
static void vMemCheckTask( void * pvParameters )
{
unsigned long *pulMemCheckTaskRunningCounter;
void *pvMem1, *pvMem2, *pvMem3;
static long lErrorOccurred = pdFALSE;
unsigned long * pulMemCheckTaskRunningCounter;
void * pvMem1, * pvMem2, * pvMem3;
static long lErrorOccurred = pdFALSE;
/* This task is dynamically created then deleted during each cycle of the
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 deleted this memory is returned to the heap. This task itself
exercises the allocator by allocating and freeing blocks.
The task executes at the idle priority so does not require a delay.
pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the
vErrorChecks() task that this task is still executing without error. */
* 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 deleted this memory is returned to the heap. This task itself
* exercises the allocator by allocating and freeing blocks.
*
* The task executes at the idle priority so does not require a delay.
*
* pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the
* vErrorChecks() task that this task is still executing without error. */
pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters;
for( ;; )
for( ; ; )
{
if( lErrorOccurred == pdFALSE )
{
@ -408,16 +409,17 @@ static long lErrorOccurred = pdFALSE;
else
{
/* 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;
}
/* Allocate some memory - just to give the allocator some extra
exercise. This has to be in a critical section to ensure the
task does not get deleted while it has memory allocated. */
* exercise. This has to be in a critical section to ensure the
* task does not get deleted while it has memory allocated. */
vTaskSuspendAll();
{
pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );
if( pvMem1 == NULL )
{
lErrorOccurred = pdTRUE;
@ -434,6 +436,7 @@ static long lErrorOccurred = pdFALSE;
vTaskSuspendAll();
{
pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 );
if( pvMem2 == NULL )
{
lErrorOccurred = pdTRUE;
@ -450,6 +453,7 @@ static long lErrorOccurred = pdFALSE;
vTaskSuspendAll();
{
pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );
if( pvMem3 == NULL )
{
lErrorOccurred = pdTRUE;
@ -463,4 +467,3 @@ static long lErrorOccurred = pdFALSE;
xTaskResumeAll();
}
}

View file

@ -25,12 +25,12 @@
*/
/*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is
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
these demo application projects then ensure Supervisor mode is used.
*/
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* The processor MUST be in supervisor mode when vTaskStartScheduler is
* 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
* these demo application projects then ensure Supervisor mode is used.
*/
/*
* Creates all the demo application tasks, then starts the scheduler. The WEB
@ -92,7 +92,7 @@
* prvCheckOtherTasksAreStillRunning(). See the description at the top
* 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
@ -116,7 +116,7 @@ static long prvCheckOtherTasksAreStillRunning( void );
void main( void )
{
/* Setup any hardware that has not already been configured by the low
level init routines. */
* level init routines. */
prvSetupHardware();
/* 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 );
/* Start the scheduler.
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is
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
these demo application projects then ensure Supervisor mode is used here. */
*
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* The processor MUST be in supervisor mode when vTaskStartScheduler is
* 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
* these demo application projects then ensure Supervisor mode is used here. */
vTaskStartScheduler();
/* We should never get here as control is now taken by the scheduler. */
return;
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
/* When using the JTAG debugger the hardware is not always initialised to
the correct default state. This line just ensures that this does not
cause all interrupts to be masked at the start. */
* the correct default state. This line just ensures that this does not
* cause all interrupts to be masked at the start. */
AT91C_BASE_AIC->AIC_EOICR = 0;
/* 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
well as the UART Tx line. */
* well as the UART Tx line. */
AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK );
/* 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. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. */
* operating without error. If an error is detected then the delay period
* is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
* the on board LED flash rate will increase. */
for( ;; )
for( ; ; )
{
/* Delay until it is time to execute again. */
vTaskDelay( xDelayPeriod );
/* Check all the standard demo application tasks are executing without
error. */
* error. */
if( prvCheckOtherTasksAreStillRunning() != pdPASS )
{
/* 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 )
{
long lReturn = ( long ) pdPASS;
long lReturn = ( long ) pdPASS;
/* 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
an error. */
* that they are all still running, and that none of them have detected
* an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
@ -242,5 +241,3 @@ long lReturn = ( long ) pdPASS;
return lReturn;
}
/*-----------------------------------------------------------*/

View file

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

View file

@ -26,12 +26,12 @@
/*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is
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
these demo application projects then ensure Supervisor mode is used.
*/
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* The processor MUST be in supervisor mode when vTaskStartScheduler is
* 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
* these demo application projects then ensure Supervisor mode is used.
*/
/*
@ -112,7 +112,7 @@
* prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file.
*/
static void vErrorChecks( void *pvParameters );
static void vErrorChecks( void * pvParameters );
/*
* 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 );
/* Start the scheduler.
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is
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
these demo application projects then ensure Supervisor mode is used here.
*
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* The processor MUST be in supervisor mode when vTaskStartScheduler is
* 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
* these demo application projects then ensure Supervisor mode is used here.
*/
vTaskStartScheduler();
/* 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 );
/* Activate the PLL by turning it on then feeding the correct sequence of
bytes. */
* bytes. */
PLLCON = mainPLL_ENABLE;
PLLFEED = mainPLL_FEED_BYTE1;
PLLFEED = mainPLL_FEED_BYTE2;
/* Wait for the PLL to lock... */
while( !( PLLSTAT & mainPLL_LOCK ) );
while( !( PLLSTAT & mainPLL_LOCK ) )
{
}
/* ...before connecting it using the feed sequence again. */
PLLCON = mainPLL_CONNECT;
@ -183,8 +184,8 @@ static void prvSetupHardware( void )
PLLFEED = mainPLL_FEED_BYTE2;
/* 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
tuning the MAM and PLL settings. */
* PLL used. It is possible faster overall performance could be obtained by
* tuning the MAM and PLL settings. */
MAMTIM = mainMAM_TIM_3;
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. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. */
* operating without error. If an error is detected then the delay period
* is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
* the on board LED flash rate will increase. */
for( ;; )
for( ; ; )
{
/* Delay until it is time to execute again. */
vTaskDelay( xDelayPeriod );
/* Check all the standard demo application tasks are executing without
error. */
* error. */
if( prvCheckOtherTasksAreStillRunning() != pdPASS )
{
/* 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 )
{
long lReturn = ( long ) pdPASS;
long lReturn = ( long ) pdPASS;
/* 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
an error. */
* that they are all still running, and that none of them have detected
* an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
@ -274,5 +275,3 @@ long lReturn = ( long ) pdPASS;
return lReturn;
}
/*-----------------------------------------------------------*/

View file

@ -25,12 +25,12 @@
*/
/*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is
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
these demo application projects then ensure Supervisor mode is used.
*/
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* The processor MUST be in supervisor mode when vTaskStartScheduler is
* 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
* these demo application projects then ensure Supervisor mode is used.
*/
/*
@ -89,10 +89,10 @@
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
/* 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
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
then an error has been detected in at least one of the demo application tasks. */
* 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
* 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. */
#define mainCHECK_LED ( 7 )
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / 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
* 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
@ -141,44 +141,46 @@ int main( void )
vStartDynamicPriorityTasks();
/* 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
without error. */
* that periodically checks to see that all the other tasks are executing
* without error. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Now all the tasks have been started - start the scheduler.
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is
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
these demo application projects then ensure Supervisor mode is used here. */
*
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* The processor MUST be in supervisor mode when vTaskStartScheduler is
* 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
* these demo application projects then ensure Supervisor mode is used here. */
vTaskStartScheduler();
/* Should never reach here! If you do then there was not enough heap
available for the idle task to be created. */
for( ;; );
* available for the idle task to be created. */
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. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase.
* operating without error. If an error is detected then the delay period
* is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
* 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
detected or not. If an error has been detected then the period
is reduced to increase the LED flash rate. */
* detected or not. If an error has been detected then the period
* is reduced to increase the LED flash rate. */
vTaskDelay( xDelayPeriod );
if( prvCheckOtherTasksAreStillRunning() != pdPASS )
@ -196,7 +198,7 @@ TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
static void prvSetupHardware( void )
{
/* 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. */
PINSEL0 |= mainTX_ENABLE;
@ -212,11 +214,11 @@ static void prvSetupHardware( void )
static long prvCheckOtherTasksAreStillRunning( void )
{
long lReturn = pdPASS;
long lReturn = pdPASS;
/* 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
an error. */
* that they are all still running, and that none of them have detected
* an error. */
if( xAreComTestTasksStillRunning() != pdPASS )
{
lReturn = pdFAIL;
@ -245,5 +247,3 @@ long lReturn = pdPASS;
return lReturn;
}
/*-----------------------------------------------------------*/

View file

@ -104,22 +104,22 @@
/*-----------------------------------------------------------*/
/* The semaphore used to wake the button task from within the external interrupt
handler. */
* handler. */
SemaphoreHandle_t xButtonSemaphore;
/* The queue that is used to send message to vPrintTask for display in the
terminal output window. */
* terminal output window. */
QueueHandle_t xPrintQueue;
/* 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;
/*-----------------------------------------------------------*/
/*
* 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
@ -130,21 +130,21 @@ static void vLEDTask( void *pvParameters );
* Messages are not written directly to the terminal, but passed to vPrintTask
* 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
* terminal IO it posts a pointer to the text to vPrintTask via a queue. This
* 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
* generates a table of tasks states that is then written by vPrintTask to the
* 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
{
/* 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();
}
#endif
@ -187,13 +187,13 @@ int main( void )
vTaskStartScheduler();
/* 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;
}
/*-----------------------------------------------------------*/
static void vLEDTask( void *pvParameters )
static void vLEDTask( void * pvParameters )
{
/* Just to remove compiler warnings. */
( void ) pvParameters;
@ -202,7 +202,7 @@ static void vLEDTask( void *pvParameters )
IO0DIR |= mainLED_BIT;
IO0SET = mainLED_BIT;
for( ;; )
for( ; ; )
{
/* Not very exiting - just 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;
TickType_t xLastExecutionTime;
const char * const pcPassMessage = "PASS\n";
const char * const pcFailMessage = "FAIL\n";
portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime;
const char * const pcPassMessage = "PASS\n";
const char * const pcFailMessage = "FAIL\n";
/* Just to remove compiler warnings. */
( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */
* works correctly. */
xLastExecutionTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
@ -268,7 +268,7 @@ const char * const pcFailMessage = "FAIL\n";
#if configUSE_PREEMPTION == 1
{
/* 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 )
{
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
never cleared again. */
* never cleared again. */
if( xErrorOccurred == pdTRUE )
{
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. */
( void ) pvParameters;
for( ;; )
for( ; ; )
{
/* 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. */
#ifndef NDEBUG
@ -316,12 +318,13 @@ char *pcMessage;
}
/*-----------------------------------------------------------*/
static void vButtonHandlerTask( void *pvParameters )
static void vButtonHandlerTask( void * pvParameters )
{
static char cListBuffer[ mainLIST_BUFFER_SIZE ];
const char *pcList = &( cListBuffer[ 0 ] );
const char * const pcHeader = "\nTask State Priority Stack #\n************************************************";
extern void (vButtonISRWrapper) ( void );
static char cListBuffer[ mainLIST_BUFFER_SIZE ];
const char * pcList = &( cListBuffer[ 0 ] );
const char * const pcHeader = "\nTask State Priority Stack #\n************************************************";
extern void( vButtonISRWrapper ) ( void );
/* Just to stop compiler warnings. */
( void ) pvParameters;
@ -342,7 +345,7 @@ extern void (vButtonISRWrapper) ( void );
}
portEXIT_CRITICAL();
for( ;; )
for( ; ; )
{
/* For debouncing, wait a while then clear the semaphore. */
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
if pcTaskName has itself been corrupted. */
* if pcTaskName has itself been corrupted. */
( void ) pxTask;
( void ) pcTaskName;
for( ;; );
for( ; ; )
{
}
}

View file

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

View file

@ -25,12 +25,12 @@
*/
/*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is
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
these demo application projects then ensure Supervisor mode is used.
*/
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* The processor MUST be in supervisor mode when vTaskStartScheduler is
* 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
* these demo application projects then ensure Supervisor mode is used.
*/
/*
* Creates all the demo application tasks, then starts the scheduler. The WEB
@ -90,7 +90,7 @@
* prvCheckOtherTasksAreStillRunning(). See the description at the top
* 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
@ -113,7 +113,7 @@ static long prvCheckOtherTasksAreStillRunning( void );
void main( void )
{
/* Setup any hardware that has not already been configured by the low
level init routines. */
* level init routines. */
prvSetupHardware();
/* 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 );
/* Start the scheduler.
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is
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
these demo application projects then ensure Supervisor mode is used here. */
*
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* The processor MUST be in supervisor mode when vTaskStartScheduler is
* 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
* these demo application projects then ensure Supervisor mode is used here. */
vTaskStartScheduler();
/* 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 xLastWakeTime;
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
TickType_t xLastWakeTime;
/* The parameters are not used in this task. */
( void ) pvParameters;
/* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil()
functions correctly. */
* functions correctly. */
xLastWakeTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. */
* operating without error. If an error is detected then the delay period
* is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
* the on board LED flash rate will increase. */
for( ;; )
for( ; ; )
{
/* 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 );
/* Check all the standard demo application tasks are executing without
error. */
* error. */
if( prvCheckOtherTasksAreStillRunning() != pdPASS )
{
/* An error has been detected in one of the tasks - flash faster. */
@ -197,11 +196,11 @@ TickType_t xLastWakeTime;
static long prvCheckOtherTasksAreStillRunning( void )
{
long lReturn = ( long ) pdPASS;
long lReturn = ( long ) pdPASS;
/* 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
an error. */
* that they are all still running, and that none of them have detected
* an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
@ -236,5 +235,3 @@ long lReturn = ( long ) pdPASS;
return lReturn;
}
/*-----------------------------------------------------------*/

View file

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

View file

@ -85,7 +85,7 @@
static void prvSetupHardware( void );
/* The check task as described at the top of this file. */
static void prvCheckTask( void *pvParameters );
static void prvCheckTask( void * pvParameters );
/*-----------------------------------------------------------*/
int main()
@ -94,8 +94,8 @@ int main()
prvSetupHardware();
/* First create the 'standard demo' tasks. These exist just to to
demonstrate API functions being used and test the kernel port. More
information is provided on the FreeRTOS.org WEB site. */
* demonstrate API functions being used and test the kernel port. More
* information is provided on the FreeRTOS.org WEB site. */
vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
@ -109,42 +109,44 @@ int main()
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
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 );
/* 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 );
/* Start the scheduler. From this point on the execution will be under
the control of the kernel. */
* the control of the kernel. */
vTaskStartScheduler();
/* Will only get here if there was insufficient heap available for the
idle task to be created. */
for( ;; );
* idle task to be created. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvCheckTask( void * pvParameters )
{
TickType_t xNextWakeTime, xPeriod = mainNO_ERROR_PERIOD;
static volatile unsigned long ulErrorCode = 0UL;
TickType_t xNextWakeTime, xPeriod = mainNO_ERROR_PERIOD;
static volatile unsigned long ulErrorCode = 0UL;
/* Just to remove the compiler warning. */
( void ) pvParameters;
/* 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();
for( ;; )
for( ; ; )
{
/* Delay until it is time for this task to execute again. */
vTaskDelayUntil( &xNextWakeTime, xPeriod );
/* Check all the other tasks in the system - latch any reported errors
into the ulErrorCode variable. */
* into the ulErrorCode variable. */
if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
ulErrorCode |= 0x01UL;
@ -206,9 +208,9 @@ static volatile unsigned long ulErrorCode = 0UL;
}
/* Reduce the block period and in so doing increase the frequency at
which this task executes if any errors have been latched. The increased
frequency causes the LED toggle rate to increase and so gives some
visual feedback that an error has occurred. */
* which this task executes if any errors have been latched. The increased
* frequency causes the LED toggle rate to increase and so gives some
* visual feedback that an error has occurred. */
if( ulErrorCode != 0x00 )
{
xPeriod = mainERROR_PERIOD;
@ -222,7 +224,7 @@ static volatile unsigned long ulErrorCode = 0UL;
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. */
vParTestInitialise();

View file

@ -25,7 +25,8 @@
*/
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
/* \file *********************************************************************
*
* \brief FreeRTOS Real Time Kernel example.
*
@ -79,10 +80,9 @@
#include "death.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.
*/
//! @{
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
@ -90,45 +90,38 @@
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#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 )
//! 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.
/* 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. */
#define mainCOM_TEST_LED ( 3 )
//! 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
//! the LED is toggled. If an error is found at any time the LED toggles faster.
/* 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
* the LED is toggled. If an error is found at any time the LED toggles faster.
*/
#define mainCHECK_TASK_LED ( 6 )
//! LED that is set upon error.
/* LED that is set upon error. */
#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 )
//! If an error is detected in a task, the vErrorChecks task will enter in an
//! infinite loop flashing the LED at this rate.
#define mainERROR_FLASH_RATE ( (TickType_t) 500 / portTICK_PERIOD_MS )
/* If an error is detected in a task, the vErrorChecks task will enter in an
* infinite loop flashing the LED at this rate. */
#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 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_2 ( ( size_t ) 52 )
#define mainMEM_CHECK_SIZE_3 ( ( size_t ) 15 )
//! @}
/*-----------------------------------------------------------*/
@ -137,7 +130,7 @@
* prvCheckOtherTasksAreStillRunning(). See the description at the top
* 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
@ -148,7 +141,7 @@ static portBASE_TYPE prvCheckOtherTasksAreStillRunning( void );
/*
* 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
@ -161,15 +154,15 @@ static void prvIndicateError( void );
int main( void )
{
/* 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. */
vParTestInitialise();
/* Start the standard demo tasks. See the WEB documentation for more
information. */
* information. */
vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
@ -180,7 +173,7 @@ int main( void )
vStartMathTasks( tskIDLE_PRIORITY );
/* 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(
vErrorChecks
, "ErrCheck"
@ -193,35 +186,35 @@ int main( void )
vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle
task. */
* task. */
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;
unsigned long ulMemCheckTaskRunningCount;
TaskHandle_t xCreatedTask;
portBASE_TYPE bSuicidalTask = 0;
static volatile unsigned long ulDummyVariable = 3UL;
unsigned long ulMemCheckTaskRunningCount;
TaskHandle_t xCreatedTask;
portBASE_TYPE bSuicidalTask = 0;
/* The parameters are not used. Prevent compiler warnings. */
( void ) pvParameters;
/* 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
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( ;; )
for( ; ; )
{
/* Do this only once. */
if( bSuicidalTask == 0 )
@ -229,22 +222,22 @@ portBASE_TYPE bSuicidalTask = 0;
bSuicidalTask++;
/* 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
to be called before vTaskStartScheduler(). We're in the case here where
vTaskStartScheduler() has already been called (thus the hidden IDLE task
has already been spawned). Since vCreateSuicidalTask() supposes that the
IDLE task isn't included in the response from uxTaskGetNumberOfTasks(),
let the MEM_CHECK task play that role. => this is why vCreateSuicidalTasks()
is not called as the last task. */
* tasks it expects to see running. However its implementation expects
* to be called before vTaskStartScheduler(). We're in the case here where
* vTaskStartScheduler() has already been called (thus the hidden IDLE task
* has already been spawned). Since vCreateSuicidalTask() supposes that the
* IDLE task isn't included in the response from uxTaskGetNumberOfTasks(),
* let the MEM_CHECK task play that role. => this is why vCreateSuicidalTasks()
* is not called as the last task. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
}
/* 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;
/* Dynamically create a task - passing ulMemCheckTaskRunningCount as a
parameter. */
* parameter. */
ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;
if( xTaskCreate( vMemCheckTask,
@ -254,8 +247,8 @@ portBASE_TYPE bSuicidalTask = 0;
tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )
{
/* 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
feedback of the error. */
* Don't go any further and flash the LED faster to provide visual
* feedback of the error. */
prvIndicateError();
}
@ -269,18 +262,18 @@ portBASE_TYPE bSuicidalTask = 0;
}
/* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */
* integer tasks get some exercise. The result here is not important -
* see the demo application documentation for more info. */
ulDummyVariable *= 3;
/* Check all other tasks are still operating without error.
Check that vMemCheckTask did increment the counter. */
if( ( prvCheckOtherTasksAreStillRunning() != pdFALSE )
|| ( ulMemCheckTaskRunningCount == mainCOUNT_INITIAL_VALUE ) )
* Check that vMemCheckTask did increment the counter. */
if( ( prvCheckOtherTasksAreStillRunning() != pdFALSE ) ||
( ulMemCheckTaskRunningCount == mainCOUNT_INITIAL_VALUE ) )
{
/* An error has occurred in one of the tasks.
Don't go any further and flash the LED faster to give visual
feedback of the error. */
* Don't go any further and flash the LED faster to give visual
* feedback of the error. */
prvIndicateError();
}
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 xErrorHasOccurred = pdFALSE;
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreComTestTasksStillRunning() != pdTRUE )
{
@ -340,38 +333,38 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
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.
* 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;
void *pvMem1, *pvMem2, *pvMem3;
static long lErrorOccurred = pdFALSE;
unsigned long * pulMemCheckTaskRunningCounter;
void * pvMem1, * pvMem2, * pvMem3;
static long lErrorOccurred = pdFALSE;
/* This task is dynamically created then deleted during each cycle of the
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 deleted this memory is returned to the heap. This task itself
exercises the allocator by allocating and freeing blocks.
The task executes at the idle priority so does not require a delay.
pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the
vErrorChecks() task that this task is still executing without error. */
* 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 deleted this memory is returned to the heap. This task itself
* exercises the allocator by allocating and freeing blocks.
*
* The task executes at the idle priority so does not require a delay.
*
* pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the
* vErrorChecks() task that this task is still executing without error. */
pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters;
for( ;; )
for( ; ; )
{
if( lErrorOccurred == pdFALSE )
{
@ -381,13 +374,13 @@ static long lErrorOccurred = pdFALSE;
else
{
/* 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;
}
/* Allocate some memory - just to give the allocator some extra
exercise. This has to be in a critical section to ensure the
task does not get deleted while it has memory allocated. */
* exercise. This has to be in a critical section to ensure the
* task does not get deleted while it has memory allocated. */
vTaskSuspendAll();
{
@ -426,6 +419,7 @@ static long lErrorOccurred = pdFALSE;
vTaskSuspendAll();
{
pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );
if( pvMem3 == NULL )
{
lErrorOccurred = pdTRUE;
@ -444,16 +438,16 @@ static long lErrorOccurred = pdFALSE;
static void prvIndicateError( void )
{
/* The check task has found an error in one of the other tasks.
Set the LEDs to a state that indicates this. */
vParTestSetLED(mainERROR_LED,pdTRUE);
* Set the LEDs to a state that indicates this. */
vParTestSetLED( mainERROR_LED, pdTRUE );
for(;;)
for( ; ; )
{
#if( BOARD==EVK1100 )
#if ( BOARD == EVK1100 )
vParTestToggleLED( mainCHECK_TASK_LED );
vTaskDelay( mainERROR_FLASH_RATE );
#endif
#if ( BOARD==EVK1101 )
#if ( BOARD == EVK1101 )
vParTestSetLED( 0, pdTRUE );
vParTestSetLED( 1, pdTRUE );
vParTestSetLED( 2, pdTRUE );
@ -461,4 +455,3 @@ static void prvIndicateError( void )
#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.
Changes from V1.2.3
+
+ Changes from V1.2.3
+
+ The integer and comtest tasks are now used when the cooperative scheduler
is being used. Previously they were only used with the preemptive
scheduler.
Changes from V1.2.5
+ is being used. Previously they were only used with the preemptive
+ scheduler.
+
+ Changes from V1.2.5
+
+ Set the baud rate to 38400. This has a smaller error percentage with an
8MHz clock (according to the manual).
Changes from V2.0.0
+ 8MHz clock (according to the manual).
+
+ Changes from V2.0.0
+
+ Delay periods are now specified using variables and constants of
TickType_t rather than unsigned long.
Changes from V2.2.0
+ TickType_t rather than unsigned long.
+
+ Changes from V2.2.0
+
+ 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.
Changes from V4.0.5
+
+ Changes from V4.0.5
+
+ Modified to demonstrate the use of co-routines.
*/
*/
#include <stdlib.h>
#include <string.h>
@ -101,7 +101,7 @@ Changes from V4.0.5
#include "regtest.h"
/* 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 mainCOM_TEST_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 )
/* 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 )
/* 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
the LED is toggled. If an error is found at any time the LED is never toggles
again. */
* 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
* again. */
#define mainCHECK_TASK_LED ( 7 )
/* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
/* 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 )
/* The number of coroutines to create. */
@ -133,7 +133,7 @@ the demo application is not unexpectedly resetting. */
/*
* 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.
@ -172,30 +172,30 @@ short main( void )
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */
* as 1 in portmacro.h. To use the cooperative scheduler define
* configUSE_PREEMPTION as 0. */
vTaskStartScheduler();
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. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */
for( ;; )
* operating without error. */
for( ; ; )
{
vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */
* integer tasks get some exercise. The result here is not important -
* see the demo application documentation for more info. */
ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning();
@ -205,7 +205,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void )
{
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
@ -230,7 +230,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xErrorHasOccurred == pdFALSE )
{
/* 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 );
}
}
@ -238,14 +238,14 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void )
{
unsigned char ucCount;
const unsigned char ucReadBit = ( unsigned char ) 0x01;
const unsigned char ucWrite1 = ( unsigned char ) 0x04;
const unsigned char ucWrite2 = ( unsigned char ) 0x02;
unsigned char ucCount;
const unsigned char ucReadBit = ( unsigned char ) 0x01;
const unsigned char ucWrite1 = ( unsigned char ) 0x04;
const unsigned char ucWrite2 = ( unsigned char ) 0x02;
/* Increment the EEPROM value at 0x00.
Setup the EEPROM address. */
*
* Setup the EEPROM address. */
EEARH = 0x00;
EEARL = 0x00;
@ -253,7 +253,9 @@ const unsigned char ucWrite2 = ( unsigned char ) 0x02;
EECR |= ucReadBit;
/* Wait for the read. */
while( EECR & ucReadBit );
while( EECR & ucReadBit )
{
}
/* The byte is ready. */
ucCount = EEDR;
@ -270,4 +272,3 @@ void vApplicationIdleHook( void )
{
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.
Changes from V1.2.3
+
+ Changes from V1.2.3
+
+ The integer and comtest tasks are now used when the cooperative scheduler
is being used. Previously they were only used with the preemptive
scheduler.
Changes from V1.2.5
+ is being used. Previously they were only used with the preemptive
+ scheduler.
+
+ Changes from V1.2.5
+
+ Set the baud rate to 38400. This has a smaller error percentage with an
8MHz clock (according to the manual).
Changes from V2.0.0
+ 8MHz clock (according to the manual).
+
+ Changes from V2.0.0
+
+ Delay periods are now specified using variables and constants of
TickType_t rather than unsigned long.
Changes from V2.6.1
+ TickType_t rather than unsigned long.
+
+ Changes from V2.6.1
+
+ 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.
*/
+
*/
#include <stdlib.h>
#include <string.h>
@ -98,7 +98,7 @@ Changes from V4.0.5
#include "regtest.h"
/* 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 mainCOM_TEST_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 )
/* 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 )
/* 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
the LED is toggled. If an error is found at any time the LED is never toggles
again. */
* 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
* again. */
#define mainCHECK_TASK_LED ( 7 )
/* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
/* 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 )
/* The number of coroutines to create. */
@ -130,7 +130,7 @@ the demo application is not unexpectedly resetting. */
/*
* 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.
@ -171,30 +171,30 @@ short main( void )
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */
* as 1 in portmacro.h. To use the cooperative scheduler define
* configUSE_PREEMPTION as 0. */
vTaskStartScheduler();
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. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */
for( ;; )
* operating without error. */
for( ; ; )
{
vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */
* integer tasks get some exercise. The result here is not important -
* see the demo application documentation for more info. */
ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning();
@ -204,7 +204,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void )
{
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
@ -229,7 +229,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xErrorHasOccurred == pdFALSE )
{
/* 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 );
}
}
@ -237,7 +237,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void )
{
unsigned char ucCount;
unsigned char ucCount;
eeprom_read_block( &ucCount, mainRESET_COUNT_ADDRESS, sizeof( ucCount ) );
ucCount++;
@ -249,4 +249,3 @@ void vApplicationIdleHook( void )
{
vCoRoutineSchedule();
}

View file

@ -1,22 +1,22 @@
/*
(C) 2020 Microchip Technology Inc. and its subsidiaries.
Subject to your compliance with these terms, you may use Microchip software and
any derivatives exclusively with Microchip products. It is your responsibility
to comply with third party license terms applicable to your use of third party
software (including open source software) that may accompany Microchip software.
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS,
IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES
OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
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
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
SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY
TO MICROCHIP FOR THIS SOFTWARE.
*/
* (C) 2020 Microchip Technology Inc. and its subsidiaries.
*
* Subject to your compliance with these terms, you may use Microchip software and
* any derivatives exclusively with Microchip products. It is your responsibility
* to comply with third party license terms applicable to your use of third party
* software (including open source software) that may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS,
* IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES
* OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
* IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
* 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
* 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
* SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY
* TO MICROCHIP FOR THIS SOFTWARE.
*/
#include <ioavr.h>
#include "FreeRTOS.h"
@ -28,29 +28,29 @@ TO MICROCHIP FOR THIS SOFTWARE.
static void prvSetupHardware( void );
#if ( mainSELECTED_APPLICATION == 0 )
extern void main_blinky( void );
extern void init_blinky( void );
extern void main_blinky( void );
extern void init_blinky( void );
#elif ( mainSELECTED_APPLICATION == 1 )
extern void main_minimal( void );
extern void init_minimal( void );
extern void main_minimal( void );
extern void init_minimal( void );
#elif ( mainSELECTED_APPLICATION == 2 )
extern void main_full( void );
extern void init_full( void );
extern void main_full( void );
extern void init_full( void );
#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
int main( void )
{
prvSetupHardware();
#if ( mainSELECTED_APPLICATION == 0 )
#if ( mainSELECTED_APPLICATION == 0 )
main_blinky();
#elif ( mainSELECTED_APPLICATION == 1 )
#elif ( mainSELECTED_APPLICATION == 1 )
main_minimal();
#elif ( mainSELECTED_APPLICATION == 2 )
#elif ( mainSELECTED_APPLICATION == 2 )
main_full();
#endif
#endif
return 0;
}
@ -58,37 +58,37 @@ int main( void )
static void prvSetupHardware( void )
{
/* Ensure no interrupts execute while the scheduler is in an inconsistent
state. Interrupts are automatically enabled when the scheduler is
started. */
* state. Interrupts are automatically enabled when the scheduler is
* started. */
portDISABLE_INTERRUPTS();
CLK_init();
#if ( mainSELECTED_APPLICATION == 0 )
#if ( mainSELECTED_APPLICATION == 0 )
init_blinky();
#elif ( mainSELECTED_APPLICATION == 1 )
#elif ( mainSELECTED_APPLICATION == 1 )
init_minimal();
#elif ( mainSELECTED_APPLICATION == 2 )
#elif ( mainSELECTED_APPLICATION == 2 )
init_full();
#endif
#endif
}
/* vApplicationStackOverflowHook is called when a stack overflow occurs.
This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in
"FreeRTOSConfig.h" header file. */
* This is usefull in application development, for debugging. To use this
* hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in
* "FreeRTOSConfig.h" header file. */
// void vApplicationStackOverflowHook(TaskHandle_t *pxTask, char *pcTaskName )
// {
// for( ;; );
// }
/* void vApplicationStackOverflowHook(TaskHandle_t *pxTask, char *pcTaskName ) */
/* { */
/* for( ;; ); */
/* } */
/* vApplicationMallocFailedHook is called when memorry allocation fails.
This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in
"FreeRTOSConfig.h" header file. */
* This is usefull in application development, for debugging. To use this
* hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in
* "FreeRTOSConfig.h" header file. */
// void vApplicationMallocFailedHook( void )
// {
// for( ;; );
// }
/* void vApplicationMallocFailedHook( void ) */
/* { */
/* for( ;; ); */
/* } */

View file

@ -63,12 +63,12 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/*-----------------------------------------------------------*/
@ -76,8 +76,8 @@ the queue empty. */
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/
@ -92,7 +92,7 @@ void main_blinky( void )
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
* file. */
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. */
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
line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle
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
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
a privileged mode (not user mode). */
for( ;; );
* line will never be reached. If the following line does execute, then
* there was either insufficient FreeRTOS heap memory available for the idle
* 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
* 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
* a privileged mode (not user mode). */
for( ; ; )
{
}
}
void init_blinky( void )
@ -123,10 +125,10 @@ void init_blinky( void )
PORTF.DIRSET = PIN5_bm;
}
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
@ -134,37 +136,37 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U );
}
}
/*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters )
static void prvQueueReceiveTask( void * pvParameters )
{
unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL;
unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL;
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
/* 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 )
/* 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
the LED is toggled. If an error is found at any time the LED is never toggles
again. */
* 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
* again. */
#define mainCHECK_TASK_LED ( 5 )
/*
* 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 )
{
vStartSemaphoreTasks(mainSEM_TEST_PRIORITY);
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartTaskNotifyTask();
vStartRegTestTasks();
vStartRecursiveMutexTasks();
/* 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 );
vTaskStartScheduler();
/* 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 either insufficient FreeRTOS heap memory available for the idle
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
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
a privileged mode (not user mode). */
for( ;; );
* line will never be reached. If the following line does execute, then
* there was either insufficient FreeRTOS heap memory available for the idle
* 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
* 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
* a privileged mode (not user mode). */
for( ; ; )
{
}
}
void init_full( void )
@ -54,28 +55,28 @@ void init_full( void )
vParTestInitialise();
}
static void prvCheckTask( void *pvParameters )
static void prvCheckTask( void * pvParameters )
{
TickType_t xLastExecutionTime;
unsigned long ulErrorFound = pdFALSE;
TickType_t xLastExecutionTime;
unsigned long ulErrorFound = pdFALSE;
/* Just to stop compiler warnings. */
( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */
* works correctly. */
xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration
unless an error occurred. */
for( ;; )
* operating without error. The onboard LED is toggled on each iteration
* unless an error occurred. */
for( ; ; )
{
/* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_PERIOD );
/* 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 )
{
ulErrorFound |= 1UL << 0UL;
@ -91,7 +92,7 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound |= 1UL << 2UL;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 3UL;
}
@ -99,7 +100,7 @@ unsigned long ulErrorFound = pdFALSE;
if( ulErrorFound == pdFALSE )
{
/* 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 );
}
}

View file

@ -37,7 +37,7 @@
#include "regtest.h"
/* 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 mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#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 )
/* 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 )
/* 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
the LED is toggled. If an error is found at any time the LED is never toggles
again. */
* 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
* again. */
#define mainCHECK_TASK_LED ( 5 )
/* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS )
/* 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 )
/* The number of coroutines to create. */
@ -68,7 +68,7 @@ the demo application is not unexpectedly resetting. */
/*
* 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.
@ -99,8 +99,8 @@ void main_minimal( void )
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */
* as 1 in portmacro.h. To use the cooperative scheduler define
* configUSE_PREEMPTION as 0. */
vTaskStartScheduler();
}
@ -113,22 +113,22 @@ void init_minimal( void )
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. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */
for( ;; )
* operating without error. */
for( ; ; )
{
vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */
* integer tasks get some exercise. The result here is not important -
* see the demo application documentation for more info. */
ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning();
@ -138,7 +138,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void )
{
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
@ -163,7 +163,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xErrorHasOccurred == pdFALSE )
{
/* 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 );
}
}
@ -171,7 +171,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void )
{
static unsigned char __eeprom ucResetCount @ mainRESET_COUNT_ADDRESS;
static unsigned char __eeprom ucResetCount @ mainRESET_COUNT_ADDRESS;
ucResetCount++;
}

View file

@ -1,22 +1,22 @@
/*
(C) 2020 Microchip Technology Inc. and its subsidiaries.
Subject to your compliance with these terms, you may use Microchip software and
any derivatives exclusively with Microchip products. It is your responsibility
to comply with third party license terms applicable to your use of third party
software (including open source software) that may accompany Microchip software.
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS,
IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES
OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
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
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
SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY
TO MICROCHIP FOR THIS SOFTWARE.
*/
* (C) 2020 Microchip Technology Inc. and its subsidiaries.
*
* Subject to your compliance with these terms, you may use Microchip software and
* any derivatives exclusively with Microchip products. It is your responsibility
* to comply with third party license terms applicable to your use of third party
* software (including open source software) that may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS,
* IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES
* OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
* IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
* 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
* 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
* SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY
* TO MICROCHIP FOR THIS SOFTWARE.
*/
#include <avr/io.h>
#include "FreeRTOS.h"
@ -28,29 +28,29 @@ TO MICROCHIP FOR THIS SOFTWARE.
static void prvSetupHardware( void );
#if ( mainSELECTED_APPLICATION == 0 )
extern void main_blinky( void );
extern void init_blinky( void );
extern void main_blinky( void );
extern void init_blinky( void );
#elif ( mainSELECTED_APPLICATION == 1 )
extern void main_minimal( void );
extern void init_minimal( void );
extern void main_minimal( void );
extern void init_minimal( void );
#elif ( mainSELECTED_APPLICATION == 2 )
extern void main_full( void );
extern void init_full( void );
extern void main_full( void );
extern void init_full( void );
#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
int main( void )
{
prvSetupHardware();
#if ( mainSELECTED_APPLICATION == 0 )
#if ( mainSELECTED_APPLICATION == 0 )
main_blinky();
#elif ( mainSELECTED_APPLICATION == 1 )
#elif ( mainSELECTED_APPLICATION == 1 )
main_minimal();
#elif ( mainSELECTED_APPLICATION == 2 )
#elif ( mainSELECTED_APPLICATION == 2 )
main_full();
#endif
#endif
return 0;
}
@ -58,37 +58,58 @@ int main( void )
static void prvSetupHardware( void )
{
/* Ensure no interrupts execute while the scheduler is in an inconsistent
state. Interrupts are automatically enabled when the scheduler is
started. */
* state. Interrupts are automatically enabled when the scheduler is
* started. */
portDISABLE_INTERRUPTS();
CLK_init();
#if ( mainSELECTED_APPLICATION == 0 )
#if ( mainSELECTED_APPLICATION == 0 )
init_blinky();
#elif ( mainSELECTED_APPLICATION == 1 )
#elif ( mainSELECTED_APPLICATION == 1 )
init_minimal();
#elif ( mainSELECTED_APPLICATION == 2 )
#elif ( mainSELECTED_APPLICATION == 2 )
init_full();
#endif
#endif
}
/* vApplicationStackOverflowHook is called when a stack overflow occurs.
This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in
"FreeRTOSConfig.h" header file. */
* This is usefull in application development, for debugging. To use this
* hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in
* "FreeRTOSConfig.h" header file. */
// void vApplicationStackOverflowHook(TaskHandle_t *pxTask, char *pcTaskName )
// {
// for( ;; );
// }
#if ( portHAS_STACK_OVERFLOW_CHECKING != 0 ) && ( configCHECK_FOR_STACK_OVERFLOW != 0 )
void vApplicationStackOverflowHook( void )
{
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.
This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in
"FreeRTOSConfig.h" header file. */
* This is usefull in application development, for debugging. To use this
* hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in
* "FreeRTOSConfig.h" header file. */
// void vApplicationMallocFailedHook( void )
// {
// for( ;; );
// }
#if ( configUSE_MALLOC_FAILED_HOOK != 0 )
void vApplicationMallocFailedHook( void )
{
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 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/*-----------------------------------------------------------*/
@ -76,8 +76,8 @@ the queue empty. */
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/
@ -92,7 +92,7 @@ void main_blinky( void )
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
* file. */
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. */
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
line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle
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
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
a privileged mode (not user mode). */
for( ;; );
* line will never be reached. If the following line does execute, then
* there was either insufficient FreeRTOS heap memory available for the idle
* 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
* 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
* a privileged mode (not user mode). */
for( ; ; )
{
}
}
void init_blinky( void )
@ -123,10 +125,10 @@ void init_blinky( void )
PORTF.DIRSET = PIN5_bm;
}
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
@ -134,37 +136,37 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U );
}
}
/*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters )
static void prvQueueReceiveTask( void * pvParameters )
{
unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL;
unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL;
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
/* Toggle LED on pin PF5. */

View file

@ -13,36 +13,38 @@
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
/* 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
the LED is toggled. If an error is found at any time the LED is never toggles
again. */
* 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
* again. */
#define mainCHECK_TASK_LED ( 5 )
/* 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 )
{
vStartSemaphoreTasks(mainSEM_TEST_PRIORITY);
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartTaskNotifyTask();
vStartRegTestTasks();
vStartRecursiveMutexTasks();
/* 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 );
vTaskStartScheduler();
/* 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 either insufficient FreeRTOS heap memory available for the idle
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
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
a privileged mode (not user mode). */
for( ;; );
* line will never be reached. If the following line does execute, then
* there was either insufficient FreeRTOS heap memory available for the idle
* 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
* 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
* a privileged mode (not user mode). */
for( ; ; )
{
}
}
void init_full( void )
@ -50,28 +52,28 @@ void init_full( void )
vParTestInitialise();
}
static void prvCheckTask( void *pvParameters )
static void prvCheckTask( void * pvParameters )
{
TickType_t xLastExecutionTime;
unsigned long ulErrorFound = pdFALSE;
TickType_t xLastExecutionTime;
unsigned long ulErrorFound = pdFALSE;
/* Just to stop compiler warnings. */
( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */
* works correctly. */
xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration
unless an error occurred. */
for( ;; )
* operating without error. The onboard LED is toggled on each iteration
* unless an error occurred. */
for( ; ; )
{
/* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_PERIOD );
/* 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 )
{
ulErrorFound |= 1UL << 0UL;
@ -87,7 +89,7 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound |= 1UL << 2UL;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 3UL;
}
@ -95,7 +97,7 @@ unsigned long ulErrorFound = pdFALSE;
if( ulErrorFound == pdFALSE )
{
/* 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 );
}
}

View file

@ -38,7 +38,7 @@
#include "regtest.h"
/* 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 mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#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 )
/* 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 )
/* 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
the LED is toggled. If an error is found at any time the LED is never toggles
again. */
* 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
* again. */
#define mainCHECK_TASK_LED ( 5 )
/* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS )
/* 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 )
/* The number of coroutines to create. */
@ -69,7 +69,7 @@ the demo application is not unexpectedly resetting. */
/*
* 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.
@ -100,8 +100,8 @@ void main_minimal( void )
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */
* as 1 in portmacro.h. To use the cooperative scheduler define
* configUSE_PREEMPTION as 0. */
vTaskStartScheduler();
}
@ -114,22 +114,22 @@ void init_minimal( void )
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. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */
for( ;; )
* operating without error. */
for( ; ; )
{
vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */
* integer tasks get some exercise. The result here is not important -
* see the demo application documentation for more info. */
ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning();
@ -139,7 +139,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void )
{
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
@ -164,7 +164,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xErrorHasOccurred == pdFALSE )
{
/* 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 );
}
}
@ -172,7 +172,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void )
{
unsigned char ucResetCount;
unsigned char ucResetCount;
eeprom_read_block( &ucResetCount, ( void * ) mainRESET_COUNT_ADDRESS, sizeof( ucResetCount ) );
ucResetCount++;

View file

@ -1,22 +1,22 @@
/*
(C) 2020 Microchip Technology Inc. and its subsidiaries.
Subject to your compliance with these terms, you may use Microchip software and
any derivatives exclusively with Microchip products. It is your responsibility
to comply with third party license terms applicable to your use of third party
software (including open source software) that may accompany Microchip software.
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS,
IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES
OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
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
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
SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY
TO MICROCHIP FOR THIS SOFTWARE.
*/
* (C) 2020 Microchip Technology Inc. and its subsidiaries.
*
* Subject to your compliance with these terms, you may use Microchip software and
* any derivatives exclusively with Microchip products. It is your responsibility
* to comply with third party license terms applicable to your use of third party
* software (including open source software) that may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS,
* IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES
* OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
* IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
* 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
* 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
* SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY
* TO MICROCHIP FOR THIS SOFTWARE.
*/
#include <ioavr.h>
#include "FreeRTOS.h"
@ -28,29 +28,29 @@ TO MICROCHIP FOR THIS SOFTWARE.
static void prvSetupHardware( void );
#if ( mainSELECTED_APPLICATION == 0 )
extern void main_blinky( void );
extern void init_blinky( void );
extern void main_blinky( void );
extern void init_blinky( void );
#elif ( mainSELECTED_APPLICATION == 1 )
extern void main_minimal( void );
extern void init_minimal( void );
extern void main_minimal( void );
extern void init_minimal( void );
#elif ( mainSELECTED_APPLICATION == 2 )
extern void main_full( void );
extern void init_full( void );
extern void main_full( void );
extern void init_full( void );
#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
int main( void )
{
prvSetupHardware();
#if ( mainSELECTED_APPLICATION == 0 )
#if ( mainSELECTED_APPLICATION == 0 )
main_blinky();
#elif ( mainSELECTED_APPLICATION == 1 )
#elif ( mainSELECTED_APPLICATION == 1 )
main_minimal();
#elif ( mainSELECTED_APPLICATION == 2 )
#elif ( mainSELECTED_APPLICATION == 2 )
main_full();
#endif
#endif
return 0;
}
@ -58,37 +58,58 @@ int main( void )
static void prvSetupHardware( void )
{
/* Ensure no interrupts execute while the scheduler is in an inconsistent
state. Interrupts are automatically enabled when the scheduler is
started. */
* state. Interrupts are automatically enabled when the scheduler is
* started. */
portDISABLE_INTERRUPTS();
CLK_init();
#if ( mainSELECTED_APPLICATION == 0 )
#if ( mainSELECTED_APPLICATION == 0 )
init_blinky();
#elif ( mainSELECTED_APPLICATION == 1 )
#elif ( mainSELECTED_APPLICATION == 1 )
init_minimal();
#elif ( mainSELECTED_APPLICATION == 2 )
#elif ( mainSELECTED_APPLICATION == 2 )
init_full();
#endif
#endif
}
/* vApplicationStackOverflowHook is called when a stack overflow occurs.
This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in
"FreeRTOSConfig.h" header file. */
* This is usefull in application development, for debugging. To use this
* hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in
* "FreeRTOSConfig.h" header file. */
// void vApplicationStackOverflowHook(TaskHandle_t *pxTask, char *pcTaskName )
// {
// for( ;; );
// }
#if ( portHAS_STACK_OVERFLOW_CHECKING != 0 ) && ( configCHECK_FOR_STACK_OVERFLOW != 0 )
void vApplicationStackOverflowHook( void )
{
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.
This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in
"FreeRTOSConfig.h" header file. */
* This is usefull in application development, for debugging. To use this
* hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in
* "FreeRTOSConfig.h" header file. */
// void vApplicationMallocFailedHook( void )
// {
// for( ;; );
// }
#if ( configUSE_MALLOC_FAILED_HOOK != 0 )
void vApplicationMallocFailedHook( void )
{
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 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/*-----------------------------------------------------------*/
@ -76,8 +76,8 @@ the queue empty. */
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/
@ -92,7 +92,7 @@ void main_blinky( void )
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
* file. */
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. */
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
line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle
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
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
a privileged mode (not user mode). */
for( ;; );
* line will never be reached. If the following line does execute, then
* there was either insufficient FreeRTOS heap memory available for the idle
* 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
* 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
* a privileged mode (not user mode). */
for( ; ; )
{
}
}
void init_blinky( void )
@ -123,10 +125,10 @@ void init_blinky( void )
PORTC.DIRSET = PIN6_bm;
}
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
@ -134,37 +136,37 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U );
}
}
/*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters )
static void prvQueueReceiveTask( void * pvParameters )
{
unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL;
unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL;
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
/* 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 )
/* 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
the LED is toggled. If an error is found at any time the LED is never toggles
again. */
* 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
* again. */
#define mainCHECK_TASK_LED ( 6 )
/*
* 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 )
{
vStartSemaphoreTasks(mainSEM_TEST_PRIORITY);
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartTaskNotifyTask();
vStartRegTestTasks();
vStartRecursiveMutexTasks();
/* 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 );
vTaskStartScheduler();
/* 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 either insufficient FreeRTOS heap memory available for the idle
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
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
a privileged mode (not user mode). */
for( ;; );
* line will never be reached. If the following line does execute, then
* there was either insufficient FreeRTOS heap memory available for the idle
* 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
* 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
* a privileged mode (not user mode). */
for( ; ; )
{
}
}
void init_full( void )
@ -54,28 +55,28 @@ void init_full( void )
vParTestInitialise();
}
static void prvCheckTask( void *pvParameters )
static void prvCheckTask( void * pvParameters )
{
TickType_t xLastExecutionTime;
unsigned long ulErrorFound = pdFALSE;
TickType_t xLastExecutionTime;
unsigned long ulErrorFound = pdFALSE;
/* Just to stop compiler warnings. */
( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */
* works correctly. */
xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration
unless an error occurred. */
for( ;; )
* operating without error. The onboard LED is toggled on each iteration
* unless an error occurred. */
for( ; ; )
{
/* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_PERIOD );
/* 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 )
{
ulErrorFound |= 1UL << 0UL;
@ -91,7 +92,7 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound |= 1UL << 2UL;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 3UL;
}
@ -99,7 +100,7 @@ unsigned long ulErrorFound = pdFALSE;
if( ulErrorFound == pdFALSE )
{
/* 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 );
}
}

View file

@ -37,7 +37,7 @@
#include "regtest.h"
/* 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 mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#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 )
/* 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 )
/* 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
the LED is toggled. If an error is found at any time the LED is never toggles
again. */
* 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
* again. */
#define mainCHECK_TASK_LED ( 6 )
/* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS )
/* 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 )
/* The number of coroutines to create. */
@ -68,7 +68,7 @@ the demo application is not unexpectedly resetting. */
/*
* 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.
@ -99,8 +99,8 @@ void main_minimal( void )
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */
* as 1 in portmacro.h. To use the cooperative scheduler define
* configUSE_PREEMPTION as 0. */
vTaskStartScheduler();
}
@ -113,22 +113,22 @@ void init_minimal( void )
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. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */
for( ;; )
* operating without error. */
for( ; ; )
{
vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */
* integer tasks get some exercise. The result here is not important -
* see the demo application documentation for more info. */
ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning();
@ -138,7 +138,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void )
{
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
@ -163,7 +163,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xErrorHasOccurred == pdFALSE )
{
/* 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 );
}
}
@ -171,7 +171,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void )
{
static unsigned char __eeprom ucResetCount @ mainRESET_COUNT_ADDRESS;
static unsigned char __eeprom ucResetCount @ mainRESET_COUNT_ADDRESS;
ucResetCount++;
}

View file

@ -1,22 +1,22 @@
/*
(C) 2020 Microchip Technology Inc. and its subsidiaries.
Subject to your compliance with these terms, you may use Microchip software and
any derivatives exclusively with Microchip products. It is your responsibility
to comply with third party license terms applicable to your use of third party
software (including open source software) that may accompany Microchip software.
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS,
IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES
OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
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
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
SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY
TO MICROCHIP FOR THIS SOFTWARE.
*/
* (C) 2020 Microchip Technology Inc. and its subsidiaries.
*
* Subject to your compliance with these terms, you may use Microchip software and
* any derivatives exclusively with Microchip products. It is your responsibility
* to comply with third party license terms applicable to your use of third party
* software (including open source software) that may accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS,
* IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES
* OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
* IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
* 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
* 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
* SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY
* TO MICROCHIP FOR THIS SOFTWARE.
*/
#include <avr/io.h>
#include "FreeRTOS.h"
@ -28,29 +28,29 @@ TO MICROCHIP FOR THIS SOFTWARE.
static void prvSetupHardware( void );
#if ( mainSELECTED_APPLICATION == 0 )
extern void main_blinky( void );
extern void init_blinky( void );
extern void main_blinky( void );
extern void init_blinky( void );
#elif ( mainSELECTED_APPLICATION == 1 )
extern void main_minimal( void );
extern void init_minimal( void );
extern void main_minimal( void );
extern void init_minimal( void );
#elif ( mainSELECTED_APPLICATION == 2 )
extern void main_full( void );
extern void init_full( void );
extern void main_full( void );
extern void init_full( void );
#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
int main( void )
{
prvSetupHardware();
#if ( mainSELECTED_APPLICATION == 0 )
#if ( mainSELECTED_APPLICATION == 0 )
main_blinky();
#elif ( mainSELECTED_APPLICATION == 1 )
#elif ( mainSELECTED_APPLICATION == 1 )
main_minimal();
#elif ( mainSELECTED_APPLICATION == 2 )
#elif ( mainSELECTED_APPLICATION == 2 )
main_full();
#endif
#endif
return 0;
}
@ -58,37 +58,58 @@ int main( void )
static void prvSetupHardware( void )
{
/* Ensure no interrupts execute while the scheduler is in an inconsistent
state. Interrupts are automatically enabled when the scheduler is
started. */
* state. Interrupts are automatically enabled when the scheduler is
* started. */
portDISABLE_INTERRUPTS();
CLK_init();
#if ( mainSELECTED_APPLICATION == 0 )
#if ( mainSELECTED_APPLICATION == 0 )
init_blinky();
#elif ( mainSELECTED_APPLICATION == 1 )
#elif ( mainSELECTED_APPLICATION == 1 )
init_minimal();
#elif ( mainSELECTED_APPLICATION == 2 )
#elif ( mainSELECTED_APPLICATION == 2 )
init_full();
#endif
#endif
}
/* vApplicationStackOverflowHook is called when a stack overflow occurs.
This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in
"FreeRTOSConfig.h" header file. */
* This is usefull in application development, for debugging. To use this
* hook, uncomment it, and set configCHECK_FOR_STACK_OVERFLOW to 1 in
* "FreeRTOSConfig.h" header file. */
// void vApplicationStackOverflowHook(TaskHandle_t *pxTask, char *pcTaskName )
// {
// for( ;; );
// }
#if ( portHAS_STACK_OVERFLOW_CHECKING != 0 ) && ( configCHECK_FOR_STACK_OVERFLOW != 0 )
void vApplicationStackOverflowHook( void )
{
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.
This is usefull in application development, for debugging. To use this
hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in
"FreeRTOSConfig.h" header file. */
* This is usefull in application development, for debugging. To use this
* hook, uncomment it, and set configUSE_MALLOC_FAILED_HOOK to 1 in
* "FreeRTOSConfig.h" header file. */
// void vApplicationMallocFailedHook( void )
// {
// for( ;; );
// }
#if ( configUSE_MALLOC_FAILED_HOOK != 0 )
void vApplicationMallocFailedHook( void )
{
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 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/*-----------------------------------------------------------*/
@ -76,8 +76,8 @@ the queue empty. */
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/
@ -92,7 +92,7 @@ void main_blinky( void )
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
* file. */
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. */
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
line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle
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
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
a privileged mode (not user mode). */
for( ;; );
* line will never be reached. If the following line does execute, then
* there was either insufficient FreeRTOS heap memory available for the idle
* 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
* 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
* a privileged mode (not user mode). */
for( ; ; )
{
}
}
void init_blinky( void )
@ -123,10 +125,10 @@ void init_blinky( void )
PORTC.DIRSET = PIN6_bm;
}
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
@ -134,37 +136,37 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U );
}
}
/*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters )
static void prvQueueReceiveTask( void * pvParameters )
{
unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL;
unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL;
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
/* Toggle LED on pin PC6. */

View file

@ -13,36 +13,38 @@
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
/* 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
the LED is toggled. If an error is found at any time the LED is never toggles
again. */
* 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
* again. */
#define mainCHECK_TASK_LED ( 6 )
/* 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 )
{
vStartSemaphoreTasks(mainSEM_TEST_PRIORITY);
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartTaskNotifyTask();
vStartRegTestTasks();
vStartRecursiveMutexTasks();
/* 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 );
vTaskStartScheduler();
/* 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 either insufficient FreeRTOS heap memory available for the idle
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
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
a privileged mode (not user mode). */
for( ;; );
* line will never be reached. If the following line does execute, then
* there was either insufficient FreeRTOS heap memory available for the idle
* 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
* 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
* a privileged mode (not user mode). */
for( ; ; )
{
}
}
void init_full( void )
@ -50,28 +52,28 @@ void init_full( void )
vParTestInitialise();
}
static void prvCheckTask( void *pvParameters )
static void prvCheckTask( void * pvParameters )
{
TickType_t xLastExecutionTime;
unsigned long ulErrorFound = pdFALSE;
TickType_t xLastExecutionTime;
unsigned long ulErrorFound = pdFALSE;
/* Just to stop compiler warnings. */
( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */
* works correctly. */
xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration
unless an error occurred. */
for( ;; )
* operating without error. The onboard LED is toggled on each iteration
* unless an error occurred. */
for( ; ; )
{
/* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_PERIOD );
/* 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 )
{
ulErrorFound |= 1UL << 0UL;
@ -87,7 +89,7 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound |= 1UL << 2UL;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound |= 1UL << 3UL;
}
@ -95,7 +97,7 @@ unsigned long ulErrorFound = pdFALSE;
if( ulErrorFound == pdFALSE )
{
/* 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 );
}
}

View file

@ -37,7 +37,7 @@
#include "regtest.h"
/* 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 mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#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 )
/* 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 )
/* 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
the LED is toggled. If an error is found at any time the LED is never toggles
again. */
* 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
* again. */
#define mainCHECK_TASK_LED ( 6 )
/* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS )
/* 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 )
/* The number of coroutines to create. */
@ -68,7 +68,7 @@ the demo application is not unexpectedly resetting. */
/*
* 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.
@ -99,8 +99,8 @@ void main_minimal( void )
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */
* as 1 in portmacro.h. To use the cooperative scheduler define
* configUSE_PREEMPTION as 0. */
vTaskStartScheduler();
}
@ -113,22 +113,22 @@ void init_minimal( void )
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. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */
for( ;; )
* operating without error. */
for( ; ; )
{
vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */
* integer tasks get some exercise. The result here is not important -
* see the demo application documentation for more info. */
ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning();
@ -138,7 +138,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void )
{
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
@ -163,7 +163,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xErrorHasOccurred == pdFALSE )
{
/* 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 );
}
}
@ -171,7 +171,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void )
{
unsigned char ucResetCount;
unsigned char ucResetCount;
eeprom_read_block( &ucResetCount, ( void * ) mainRESET_COUNT_ADDRESS, sizeof( ucResetCount ) );
ucResetCount++;

View file

@ -82,7 +82,7 @@
#include "chip.h"
/* 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
/*-----------------------------------------------------------*/
@ -103,14 +103,15 @@ static void prvSetupHardware( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
* within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void );
/* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port
layer. */
* layer. */
void vApplicationIRQHandler( void );
/*-----------------------------------------------------------*/
@ -121,8 +122,8 @@ int main( void )
prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
* of this file. */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{
main_blinky();
}
@ -139,7 +140,7 @@ int main( void )
static void prvSetupHardware( void )
{
/* Disable watchdog */
wdt_disable( );
wdt_disable();
/* Set protect mode in the AIC for easier debugging. */
AIC->AIC_DCR |= AIC_DCR_PROT;
@ -147,7 +148,7 @@ static void prvSetupHardware( void )
/* Configure ports used by LEDs. */
vParTestInitialise();
#if defined (ddram)
#if defined( ddram )
MMU_Initialize( ( uint32_t * ) 0x30C000 );
CP15_EnableMMU();
CP15_EnableDcache();
@ -159,24 +160,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
@ -185,15 +187,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
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
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
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
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */
* 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
* 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
* configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
* RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize();
/* 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 ) ulLine;
@ -211,7 +214,7 @@ volatile unsigned long ul = 0;
taskENTER_CRITICAL();
{
/* Set ul to a non-zero value using the debugger to step out of this
function. */
* function. */
while( ul == 0 )
{
portNOP();
@ -226,7 +229,7 @@ void vApplicationTickHook( void )
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{
/* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */
* prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */
@ -235,24 +238,24 @@ void vApplicationTickHook( void )
/* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing();
}
#endif
#endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
}
/*-----------------------------------------------------------*/
/* The function called by the RTOS port layer after it has managed interrupt
entry. */
* entry. */
void vApplicationIRQHandler( void )
{
typedef void (*ISRFunction_t)( void );
ISRFunction_t pxISRFunction;
volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
typedef void (* ISRFunction_t)( void );
ISRFunction_t pxISRFunction;
volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
/* Obtain the address of the interrupt handler from the AIR. */
pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR;
/* 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
then this write is not necessary. */
* CPU is in protect mode. If the interrupt controller is not in protect mode
* then this write is not necessary. */
*pulAIC_IVR = ( uint32_t ) pxISRFunction;
/* 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. */
size_t __write(int, const unsigned char *, size_t);
size_t __write(int f, const unsigned char *p, size_t s)
size_t __write( int,
const unsigned char *,
size_t );
size_t __write( int f,
const unsigned char * p,
size_t s )
{
(void) f;
(void) p;
(void) s;
( void ) f;
( void ) p;
( void ) s;
return 0;
}

View file

@ -57,7 +57,7 @@
#include "chip.h"
/* 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
/*-----------------------------------------------------------*/
@ -78,14 +78,15 @@ static void prvSetupHardware( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
* within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void );
/* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port
layer. */
* layer. */
void vApplicationIRQHandler( void );
/*-----------------------------------------------------------*/
@ -96,8 +97,8 @@ int main( void )
prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
* of this file. */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{
main_blinky();
}
@ -122,7 +123,7 @@ static void prvSetupHardware( void )
/* Configure ports used by LEDs. */
vParTestInitialise();
#if defined (ddram)
#if defined( ddram )
MMU_Initialize( ( uint32_t * ) 0x30C000 );
CP15_EnableMMU();
CP15_EnableDcache();
@ -134,24 +135,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
@ -160,15 +162,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
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
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
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
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */
* 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
* 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
* configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
* RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize();
/* 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 ) ulLine;
@ -186,7 +189,7 @@ volatile unsigned long ul = 0;
taskENTER_CRITICAL();
{
/* Set ul to a non-zero value using the debugger to step out of this
function. */
* function. */
while( ul == 0 )
{
portNOP();
@ -201,7 +204,7 @@ void vApplicationTickHook( void )
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{
/* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */
* prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */
@ -210,24 +213,24 @@ void vApplicationTickHook( void )
/* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing();
}
#endif
#endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
}
/*-----------------------------------------------------------*/
/* The function called by the RTOS port layer after it has managed interrupt
entry. */
* entry. */
void vApplicationIRQHandler( void )
{
typedef void (*ISRFunction_t)( void );
ISRFunction_t pxISRFunction;
volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
typedef void (* ISRFunction_t)( void );
ISRFunction_t pxISRFunction;
volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
/* Obtain the address of the interrupt handler from the AIR. */
pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR;
/* 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
then this write is not necessary. */
* CPU is in protect mode. If the interrupt controller is not in protect mode
* then this write is not necessary. */
*pulAIC_IVR = ( uint32_t ) pxISRFunction;
/* 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. */
pxISRFunction();
}

View file

@ -57,7 +57,7 @@
#include "chip.h"
/* 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
/*-----------------------------------------------------------*/
@ -71,21 +71,22 @@ static void prvSetupHardware( void );
* 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.
*/
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
extern void main_blinky( void );
#else
extern void main_full( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
* within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void );
/* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port
layer. */
* layer. */
void vApplicationIRQHandler( void );
/*-----------------------------------------------------------*/
@ -96,8 +97,8 @@ int main( void )
prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
* of this file. */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{
main_blinky();
}
@ -117,13 +118,13 @@ static void prvSetupHardware( void )
WDT_Disable( WDT );
/* Set protect mode in the AIC for easier debugging. THIS IS COMMENTED OUT
AS IT RESULTS IN SPURIOUS INTERRUPTS.
AIC->AIC_DCR |= AIC_DCR_PROT; */
* AS IT RESULTS IN SPURIOUS INTERRUPTS.
* AIC->AIC_DCR |= AIC_DCR_PROT; */
/* Configure ports used by LEDs. */
vParTestInitialise();
#if defined (ddram)
#if defined( ddram )
{
MMU_Initialize( ( uint32_t * ) 0x20C000 );
CP15_EnableMMU();
@ -137,24 +138,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
@ -163,15 +165,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
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
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
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
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */
* 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
* 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
* configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
* RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize();
/* 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 ) ulLine;
@ -189,7 +192,7 @@ volatile unsigned long ul = 0;
taskENTER_CRITICAL();
{
/* Set ul to a non-zero value using the debugger to step out of this
function. */
* function. */
while( ul == 0 )
{
portNOP();
@ -204,7 +207,7 @@ void vApplicationTickHook( void )
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{
/* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */
* prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */
@ -213,24 +216,24 @@ void vApplicationTickHook( void )
/* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing();
}
#endif
#endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
}
/*-----------------------------------------------------------*/
/* The function called by the RTOS port layer after it has managed interrupt
entry. */
* entry. */
void vApplicationIRQHandler( void )
{
typedef void (*ISRFunction_t)( void );
ISRFunction_t pxISRFunction;
volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
typedef void (* ISRFunction_t)( void );
ISRFunction_t pxISRFunction;
volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
/* Obtain the address of the interrupt handler from the AIR. */
pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR;
/* 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
then this write is not necessary. */
* CPU is in protect mode. If the interrupt controller is not in protect mode
* then this write is not necessary. */
*pulAIC_IVR = ( uint32_t ) pxISRFunction;
/* 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. */
pxISRFunction();
}

View file

@ -95,25 +95,26 @@ static void prvSetupHardware( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
* within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void );
/*-----------------------------------------------------------*/
/* 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
heap can be forced into fast internal RAM - useful because the stacks used by
the tasks come from this space. */
uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__ ( ( section( ".oc_ram" ) ) );
* 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
* the tasks come from this space. */
uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__( ( section( ".oc_ram" ) ) );
/* 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,
and so not accessible outside of the dirver's source file. Instead declare an
array for use by the FreeRTOS handler. See:
http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html. */
* 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
* array for use by the FreeRTOS handler. See:
* http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html. */
static INT_DISPATCH_t xISRHandlers[ ALT_INT_PROVISION_INT_COUNT ];
/*-----------------------------------------------------------*/
@ -124,8 +125,8 @@ int main( void )
prvSetupHardware();
/* The mainSELECTED_APPLICATION setting is described at the top
of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
* of this file. */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{
main_blinky();
}
@ -142,15 +143,15 @@ int main( void )
static void prvSetupHardware( void )
{
extern uint8_t __cs3_interrupt_vector;
uint32_t ulSCTLR, ulVectorTable = ( uint32_t ) &__cs3_interrupt_vector;
const uint32_t ulVBit = 13U;
extern uint8_t __cs3_interrupt_vector;
uint32_t ulSCTLR, ulVectorTable = ( uint32_t ) &__cs3_interrupt_vector;
const uint32_t ulVBit = 13U;
alt_int_global_init();
alt_int_cpu_binary_point_set( 0 );
/* 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 ) );
ulSCTLR &= ~( 1 << ulVBit );
__asm( "MCR p15, 0, %0, c1, c0, 0" : : "r" ( ulSCTLR ) );
@ -160,7 +161,7 @@ const uint32_t ulVBit = 13U;
mmu_init();
/* GPIO for LEDs. ParTest is a historic name which used to stand for
parallel port test. */
* parallel port test. */
vParTestInitialise();
}
/*-----------------------------------------------------------*/
@ -168,39 +169,46 @@ const uint32_t ulVBit = 13U;
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
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
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
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
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */
* 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
* 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
* configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
* RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize();
/* 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 ) ulLine;
@ -218,7 +227,7 @@ volatile unsigned long ul = 0;
taskENTER_CRITICAL();
{
/* Set ul to a non-zero value using the debugger to step out of this
function. */
* function. */
while( ul == 0 )
{
portNOP();
@ -230,10 +239,10 @@ volatile unsigned long ul = 0;
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
prodding periodically from the tick interrupt. */
* prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests();
/* 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. */
vInterruptSemaphorePeriodicTest();
}
#endif
#endif /* if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) */
}
/*-----------------------------------------------------------*/
void vConfigureTickInterrupt( void )
{
alt_freq_t ulTempFrequency;
const alt_freq_t ulMicroSecondsPerSecond = 1000000UL;
void FreeRTOS_Tick_Handler( void );
alt_freq_t ulTempFrequency;
const alt_freq_t ulMicroSecondsPerSecond = 1000000UL;
void FreeRTOS_Tick_Handler( void );
/* 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 );
/* Register the standard FreeRTOS Cortex-A tick handler as the timer's
interrupt handler. The handler clears the interrupt using the
configCLEAR_TICK_INTERRUPT() macro, which is defined in FreeRTOSConfig.h. */
* interrupt handler. The handler clears the interrupt using the
* 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 );
/* This tick interrupt must run at the lowest priority. */
@ -289,11 +299,12 @@ void FreeRTOS_Tick_Handler( void );
/* Finally, enable the interrupt. */
alt_gpt_int_clear_pending( 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 )
{
@ -305,24 +316,23 @@ void vRegisterIRQHandler( uint32_t ulID, alt_int_callback_t pxHandlerFunction, v
void vApplicationIRQHandler( uint32_t ulICCIAR )
{
uint32_t ulInterruptID;
void *pvContext;
alt_int_callback_t pxISR;
uint32_t ulInterruptID;
void * pvContext;
alt_int_callback_t pxISR;
/* Re-enable interrupts. */
__asm ( "cpsie i" );
__asm( "cpsie i" );
/* The ID of the interrupt is obtained by bitwise anding the ICCIAR value
with 0x3FF. */
* with 0x3FF. */
ulInterruptID = ulICCIAR & 0x3FFUL;
if( ulInterruptID < ALT_INT_PROVISION_INT_COUNT )
{
/* Call the function installed in the array of installed handler
functions. */
* functions. */
pxISR = xISRHandlers[ ulInterruptID ].pxISR;
pvContext = xISRHandlers[ ulInterruptID ].pvContext;
pxISR( ulICCIAR, pvContext );
}
}

View file

@ -74,12 +74,12 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* 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.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/
@ -108,7 +108,7 @@ void main_blinky( void )
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
* file. */
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. */
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
line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle
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
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
a privileged mode (not user mode). */
for( ;; );
* line will never be reached. If the following line does execute, then
* there was either insufficient FreeRTOS heap memory available for the idle
* 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
* 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
* a privileged mode (not user mode). */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
@ -145,37 +147,37 @@ const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U );
}
}
/*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters )
static void prvQueueReceiveTask( void * pvParameters )
{
unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL;
unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL;
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
vParTestToggleLED( mainTASK_LED );
@ -184,4 +186,3 @@ const unsigned long ulExpectedValue = 100UL;
}
}
/*-----------------------------------------------------------*/

View file

@ -102,7 +102,7 @@
#define mainQUEUE_OVERWRITE_PRIORITY ( tskIDLE_PRIORITY )
/* 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 )
/* 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 )
/* 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
using the pdMS_TO_TICKS() macro constant. */
* any of the standard demo tasks. ms are converted to the equivalent in ticks
* using the pdMS_TO_TICKS() macro constant. */
#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 standard demo tasks. ms are converted to the equivalent in ticks using the
pdMS_TO_TICKS() macro. */
* the standard demo tasks. ms are converted to the equivalent in ticks using the
* pdMS_TO_TICKS() macro. */
#define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 200UL )
/* 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_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.
*/
static void prvCheckTask( void *pvParameters );
static void prvCheckTask( void * pvParameters );
/*
* 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
* parameter.
*/
static void prvRegTestTaskEntry1( void *pvParameters );
static void prvRegTestTaskEntry1( void * pvParameters );
extern void vRegTest1Implementation( void );
static void prvRegTestTaskEntry2( void *pvParameters );
static void prvRegTestTaskEntry2( void * pvParameters );
extern void vRegTest2Implementation( void );
/*
@ -158,21 +158,22 @@ extern void vRegisterSampleCLICommands( void );
/*
* 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
* time to ensure the other test tasks don't just execute in a repeating
* pattern.
*/
static void prvPseudoRandomiser( void *pvParameters );
static void prvPseudoRandomiser( void * pvParameters );
/*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the
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
stops incrementing, then an error has been found. */
* 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
* stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/
@ -180,8 +181,8 @@ volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
void main_full( void )
{
/* 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
kernel port. */
* functionality, but do demonstrate how to use the FreeRTOS API and test the
* kernel port. */
vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks();
@ -196,7 +197,7 @@ void main_full( void )
vStartInterruptSemaphoreTasks();
/* 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 );
/* Register the standard CLI commands. */
@ -210,56 +211,58 @@ void main_full( void )
xTaskCreate( prvPseudoRandomiser, "Rnd", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
/* 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 );
/* 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
running. */
* created last as they keep account of the number of tasks they expect to see
* running. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the scheduler. */
vTaskStartScheduler();
/* 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 either insufficient FreeRTOS heap memory available for the idle
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
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
a privileged mode (not user mode). */
for( ;; );
* line will never be reached. If the following line does execute, then
* there was either insufficient FreeRTOS heap memory available for the idle
* 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
* 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
* a privileged mode (not user mode). */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvCheckTask( void *pvParameters )
static void prvCheckTask( void * pvParameters )
{
TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD;
TickType_t xLastExecutionTime;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD;
TickType_t xLastExecutionTime;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
/* Just to stop compiler warnings. */
( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */
* works correctly. */
xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration.
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
effect of increasing the rate at which the onboard LED toggles, and in so
doing gives visual feedback of the system status. */
for( ;; )
* operating without error. The onboard LED is toggled on each iteration.
* 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
* effect of increasing the rate at which the onboard LED toggles, and in so
* doing gives visual feedback of the system status. */
for( ; ; )
{
/* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod );
/* 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 )
{
ulErrorFound = 1 << 1;
@ -275,17 +278,17 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound = 1 << 3;
}
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
ulErrorFound = 1 << 4;
}
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
ulErrorFound = 1 << 5;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound = 1 << 6;
}
@ -330,6 +333,7 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound = 1 << 14;
}
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */
@ -337,35 +341,36 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound = 1 << 15;
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainNO_ERROR_CHECK_TASK_PERIOD milliseconds then
everything is ok. A faster toggle indicates an error. */
* the LED toggles every mainNO_ERROR_CHECK_TASK_PERIOD milliseconds then
* everything is ok. A faster toggle indicates an error. */
vParTestToggleLED( mainCHECK_LED );
if( ulErrorFound != pdFALSE )
{
/* An error has been detected in one of the tasks - flash the LED
at a higher frequency to give visible feedback that something has
gone wrong (it might just be that the loop back connector required
by the comtest tasks has not been fitted). */
* at a higher frequency to give visible feedback that something has
* gone wrong (it might just be that the loop back connector required
* by the comtest tasks has not been fitted). */
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
written in C for convenience of checking the task parameter is being passed
in correctly. */
* written in C for convenience of checking the task parameter is being passed
* in correctly. */
if( pvParameters == mainREG_TEST_TASK_1_PARAMETER )
{
/* The reg test task also tests the floating point registers. Tasks
that use the floating point unit must call vPortTaskUsesFPU() before
any floating point instructions are executed. */
* that use the floating point unit must call vPortTaskUsesFPU() before
* any floating point instructions are executed. */
vPortTaskUsesFPU();
/* 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
be incorrect. The check task will detect that the regtest loop counter is
not being incremented and flag an error. */
* be incorrect. The check task will detect that the regtest loop counter is
* not being incremented and flag an error. */
vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/
static void prvRegTestTaskEntry2( void *pvParameters )
static void prvRegTestTaskEntry2( void * pvParameters )
{
/* 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
in correctly. */
* written in C for convenience of checking the task parameter is being passed
* in correctly. */
if( pvParameters == mainREG_TEST_TASK_2_PARAMETER )
{
/* The reg test task also tests the floating point registers. Tasks
that use the floating point unit must call vPortTaskUsesFPU() before
any floating point instructions are executed. */
* that use the floating point unit must call vPortTaskUsesFPU() before
* any floating point instructions are executed. */
vPortTaskUsesFPU();
/* 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
be incorrect. The check task will detect that the regtest loop counter is
not being incremented and flag an error. */
* be incorrect. The check task will detect that the regtest loop counter is
* not being incremented and flag an error. */
vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/
static void prvPseudoRandomiser( void *pvParameters )
static void prvPseudoRandomiser( void * pvParameters )
{
const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL, ulMinDelay = ( 35 / portTICK_PERIOD_MS );
volatile uint32_t ulNextRand = ( uint32_t ) &pvParameters, ulValue;
const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL, ulMinDelay = ( 35 / portTICK_PERIOD_MS );
volatile uint32_t ulNextRand = ( uint32_t ) &pvParameters, ulValue;
/* 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
done by generating interrupts at pseudo random times. */
for( ;; )
* disruption in the scheduling pattern of the other tasks. Normally this is
* done by generating interrupts at pseudo random times. */
for( ; ; )
{
ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
ulValue = ( ulNextRand >> 16UL ) & 0xffUL;
@ -425,18 +430,12 @@ volatile uint32_t ulNextRand = ( uint32_t ) &pvParameters, ulValue;
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--;
}
}
}

View file

@ -83,7 +83,7 @@
/*-----------------------------------------------------------*/
/* The time between cycles of the 'check' functionality (defined within the
tick hook). */
* tick hook). */
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* 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 )
/* The maximum number of message that can be waiting for display at any one
time. */
* time. */
#define mainLCD_QUEUE_SIZE ( 3 )
/* 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 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 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
* 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.
@ -148,11 +149,11 @@ int main( void )
prvSetupHardware();
/* 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 ) );
/* 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 );
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
vStartRecursiveMutexTasks();
@ -171,7 +172,7 @@ int main( void )
vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle
task. */
* task. */
return 0;
}
/*-----------------------------------------------------------*/
@ -185,13 +186,14 @@ void prvSetupHardware( void )
void vApplicationTickHook( void )
{
static xLCDMessage xMessage = { "PASS" };
static unsigned long ulTicksSinceLastDisplay = 0;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
static xLCDMessage xMessage = { "PASS" };
static unsigned long ulTicksSinceLastDisplay = 0;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* 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++;
if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
{
ulTicksSinceLastDisplay = 0;
@ -201,6 +203,7 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
{
xMessage.pcMessage = "ERROR IN GEN Q";
}
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
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 ) pcTaskName;
/* If the parameters have been corrupted then inspect pxCurrentTCB to
identify which task has overflowed its stack. */
for( ;; );
* identify which task has overflowed its stack. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvLCDTask( void *pvParameters )
static void prvLCDTask( void * pvParameters )
{
xLCDMessage xMessage;
unsigned long ulY = 0;
const unsigned long ulX = 5;
const unsigned long ulMaxY = 250, ulYIncrement = 22, ulWidth = 250, ulHeight = 20;;
xLCDMessage xMessage;
unsigned long ulY = 0;
const unsigned long ulX = 5;
const unsigned long ulMaxY = 250, ulYIncrement = 22, ulWidth = 250, ulHeight = 20;
/* Initialize LCD. */
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_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
the tick hook). */
* the tick hook). */
xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY );
/* 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_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 );
#else
extern void main_full( void );
#endif /* #if configCREATE_LOW_POWER_DEMO == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
* within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void );
/*-----------------------------------------------------------*/
@ -93,8 +94,8 @@ int main( void )
prvSetupHardware();
/* The mainCREATE_LOW_POWER_DEMO setting is described at the top
of this file. */
#if( configCREATE_LOW_POWER_DEMO != 0 )
* of this file. */
#if ( configCREATE_LOW_POWER_DEMO != 0 )
{
main_low_power();
}
@ -124,24 +125,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
@ -150,15 +152,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
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
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
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
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */
* 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
* 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
* configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
* RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -169,13 +171,13 @@ volatile size_t xFreeHeapSpace;
void vApplicationTickHook( void )
{
/* 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 );
/* Some of the tests and demo tasks executed by the full demo include
interaction from an interrupt - for which the tick interrupt is used
via the tick hook function. */
* interaction from an interrupt - for which the tick interrupt is used
* via the tick hook function. */
vFullDemoTickHook();
}
#endif
@ -183,51 +185,54 @@ void vApplicationTickHook( void )
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
* used by the Idle task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* 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;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
* application must provide an implementation of vApplicationGetTimerTaskMemory()
* to provide the memory that is used by the Timer service task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* 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;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*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_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 );
#else
extern void main_full( void );
#endif /* #if configCREATE_LOW_POWER_DEMO == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
* within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void );
/*-----------------------------------------------------------*/
@ -93,8 +94,8 @@ int main( void )
prvSetupHardware();
/* The mainCREATE_LOW_POWER_DEMO setting is described at the top
of this file. */
#if( configCREATE_LOW_POWER_DEMO != 0 )
* of this file. */
#if ( configCREATE_LOW_POWER_DEMO != 0 )
{
main_low_power();
}
@ -111,8 +112,8 @@ int main( void )
static void prvSetupHardware( void )
{
EMU_DCDCInit_TypeDef xDCDInit = EMU_DCDCINIT_STK_DEFAULT;
CMU_HFXOInit_TypeDef xHFXOInit = CMU_HFXOINIT_STK_DEFAULT;
EMU_DCDCInit_TypeDef xDCDInit = EMU_DCDCINIT_STK_DEFAULT;
CMU_HFXOInit_TypeDef xHFXOInit = CMU_HFXOINIT_STK_DEFAULT;
/* Chip errata */
CHIP_Init();
@ -135,24 +136,25 @@ CMU_HFXOInit_TypeDef xHFXOInit = CMU_HFXOINIT_STK_DEFAULT;
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
@ -161,15 +163,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
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
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
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
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */
* 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
* 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
* configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
* RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -180,13 +182,13 @@ volatile size_t xFreeHeapSpace;
void vApplicationTickHook( void )
{
/* 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 );
/* Some of the tests and demo tasks executed by the full demo include
interaction from an interrupt - for which the tick interrupt is used
via the tick hook function. */
* interaction from an interrupt - for which the tick interrupt is used
* via the tick hook function. */
vFullDemoTickHook();
}
#endif
@ -194,50 +196,54 @@ void vApplicationTickHook( void )
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
* used by the Idle task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* 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;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
* application must provide an implementation of vApplicationGetTimerTaskMemory()
* to provide the memory that is used by the Timer service task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* 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;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}

View file

@ -89,26 +89,26 @@
#define mainNUM_FLASH_CO_ROUTINES ( 5 )
/* The length of the queue used to pass received characters to the Comms Rx
task. */
* task. */
#define mainRX_QUEUE_LEN ( 5 )
/* 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 )
/* Only one co-routine is created so its index is not important. */
#define mainTX_CO_ROUTINE_INDEX ( 0 )
/* 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 mainMAX_TX_DELAY ( ( TickType_t ) 0x7f )
#define mainOFFSET_TIME ( ( TickType_t ) 3 )
/* 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
a character after this time then there must be an error in the transmission or
the timing of the transmission. */
* 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
* the timing of the transmission. */
#define mainCOMMS_RX_DELAY ( mainMAX_TX_DELAY + 20 )
/* The task priorities. */
@ -127,21 +127,21 @@ the timing of the transmission. */
#define mainFIFO_SET ( 0x10 )
/* 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 mainLAST_TX_CHAR 'z'
/* 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 mainFIRST_PROGRAM_BYTES ( ( unsigned long * ) 4 )
/* The error routine that is called if the driver library encounters an error. */
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
void __error__( char * pcFilename,
unsigned long ulLine )
{
}
#endif
/*-----------------------------------------------------------*/
@ -160,12 +160,13 @@ static void vCommsRxTask( void * pvParameters );
* The co-routine that periodically initiates the transmission of the string on
* 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.
*/
static void prvWriteString( const char *pcString );
static void prvWriteString( const char * pcString );
/*
* Initialisation routine for the UART.
@ -175,7 +176,8 @@ static void vSerialInit( void );
/*
* 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
@ -197,14 +199,14 @@ static void prvSetupHardware( void );
/*-----------------------------------------------------------*/
/* 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;
/* The next character to transmit. */
static char cNextChar;
/* The queue used to transmit characters from the interrupt to the Comms Rx
task. */
* task. */
static QueueHandle_t xCommsQueue;
/*-----------------------------------------------------------*/
@ -212,7 +214,7 @@ static QueueHandle_t xCommsQueue;
void Main( void )
{
/* Create the queue used to communicate between the UART ISR and the Comms
Rx task. */
* Rx task. */
xCommsQueue = xQueueCreate( mainRX_QUEUE_LEN, sizeof( char ) );
/* Setup the ports used by the demo and the clock. */
@ -222,7 +224,7 @@ void Main( void )
vStartFlashCoRoutines( mainNUM_FLASH_CO_ROUTINES );
/* 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 );
/* Create the LCD and Comms Rx tasks. */
@ -233,8 +235,10 @@ void Main( void )
vTaskStartScheduler();
/* Should not get here unless we did not have enough memory to start the
scheduler. */
for( ;; );
* scheduler. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
@ -253,8 +257,8 @@ static void prvSetupHardware( void )
void vApplicationIdleHook( void )
{
/* The co-routines are executed in the idle task using the idle task
hook. */
for( ;; )
* hook. */
for( ; ; )
{
/* Schedule the co-routines. */
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. */
prvPDCWrite(PDC_LCD_CSR, LCD_CLEAR);
prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR );
while( *pcString )
{
vTaskDelay( mainCHAR_WRITE_DELAY );
@ -280,8 +285,9 @@ static void prvWriteString( const char *pcString )
void vLCDTask( void * pvParameters )
{
unsigned portBASE_TYPE uxIndex;
const unsigned char ucCFGData[] = {
unsigned portBASE_TYPE uxIndex;
const unsigned char ucCFGData[] =
{
0x30, /* Set data bus to 8-bits. */
0x30,
0x30,
@ -293,7 +299,8 @@ const unsigned char ucCFGData[] = {
};
/* The strings that are written to the LCD. */
const char *pcStringsToDisplay[] = {
const char * pcStringsToDisplay[] =
{
"Stellaris",
"Demo",
"One",
@ -303,6 +310,7 @@ const char *pcStringsToDisplay[] = {
/* Configure the LCD. */
uxIndex = 0;
while( uxIndex < sizeof( ucCFGData ) )
{
prvPDCWrite( PDC_LCD_CSR, ucCFGData[ uxIndex ] );
@ -318,13 +326,15 @@ const char *pcStringsToDisplay[] = {
prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR );
uxIndex = 0;
for( ;; )
for( ; ; )
{
/* Display the string on the LCD. */
prvWriteString( pcStringsToDisplay[ uxIndex ] );
/* Move on to the next string - wrapping if necessary. */
uxIndex++;
if( *( pcStringsToDisplay[ uxIndex ] ) == 0x00 )
{
uxIndex = 0;
@ -340,12 +350,12 @@ const char *pcStringsToDisplay[] = {
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. */
cExpectedChar = mainFIRST_TX_CHAR;
for( ;; )
for( ; ; )
{
/* Wait for a character to be received. */
xQueueReceive( xCommsQueue, ( void * ) &cRxedChar, mainCOMMS_RX_DELAY );
@ -354,14 +364,16 @@ static char cRxedChar, cExpectedChar;
if( cRxedChar != cExpectedChar )
{
/* Got an unexpected character. This can sometimes occur when
reseting the system using the debugger leaving characters already
in the UART registers. */
* reseting the system using the debugger leaving characters already
* in the UART registers. */
uxErrorStatus = pdFAIL;
/* Resync by waiting for the end of the current string. */
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. */
@ -372,16 +384,16 @@ static char cRxedChar, cExpectedChar;
if( cExpectedChar == mainLAST_TX_CHAR )
{
/* We have reached the end of the string - we now expect to
receive the first character in the string again. The LED is
toggled to indicate that the entire string was received without
error. */
* receive the first character in the string again. The LED is
* toggled to indicate that the entire string was received without
* error. */
vParTestToggleLED( mainCOMMS_RX_LED );
cExpectedChar = mainFIRST_TX_CHAR;
}
else
{
/* We got the expected character, we now expect to receive the
next character in the string. */
* next character in the string. */
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;
static unsigned long *pulRandomBytes = mainFIRST_PROGRAM_BYTES;
TickType_t xDelayPeriod;
static unsigned long * pulRandomBytes = mainFIRST_PROGRAM_BYTES;
/* Co-routine MUST start with a call to crSTART. */
crSTART( xHandle );
for(;;)
for( ; ; )
{
/* Was the previously transmitted string received correctly? */
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
the next character in the string once this one has completed. */
* the next character in the string once this one has completed. */
cNextChar++;
}
UARTIntEnable(UART0_BASE, UART_INT_TX);
UARTIntEnable( UART0_BASE, UART_INT_TX );
/* Toggle the LED to show a new string is being transmitted. */
vParTestToggleLED( mainCOMMS_TX_LED );
/* 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 );
pulRandomBytes++;
if( pulRandomBytes > mainTOTAL_PROGRAM_MEMORY )
{
pulRandomBytes = mainFIRST_PROGRAM_BYTES;
@ -457,17 +471,17 @@ static unsigned long *pulRandomBytes = mainFIRST_PROGRAM_BYTES;
static void vSerialInit( void )
{
/* 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
UART signals. */
* UART signals. */
GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW );
/* 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 );
/* 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;
/* 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;
char cRxedChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
unsigned long ulStatus;
char cRxedChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* What caused the interrupt. */
ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
@ -491,11 +505,11 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Was an Rx interrupt pending? */
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
Rxed chars. Posting the character should wake the task that is
blocked on the queue waiting for characters. */
* Rxed chars. Posting the character should wake the task that is
* blocked on the queue waiting for characters. */
cRxedChar = ( char ) HWREG( UART0_BASE + UART_O_DR );
xQueueSendFromISR( xCommsQueue, &cRxedChar, &xHigherPriorityTaskWoken );
}
@ -511,19 +525,21 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
{
HWREG( UART0_BASE + UART_O_DR ) = cNextChar;
}
cNextChar++;
}
}
/* 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
the currently executing task (i.e. the task that this interrupt
interrupted.) */
* 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
* interrupted.) */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/
static void prvPDCWrite( char cAddress, char cData )
static void prvPDCWrite( char cAddress,
char cData )
{
vTaskSuspendAll();
{
@ -542,7 +558,7 @@ void vSetErrorLED( void )
void prvSetAndCheckRegisters( void )
{
/* 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 r1, r11, #2\n"
" add r2, r11, #3\n"
@ -557,7 +573,7 @@ void prvSetAndCheckRegisters( void )
" add r12, r11, #12" );
/* Check the values are as expected. */
__asm volatile( " cmp r11, #10\n"
__asm volatile ( " cmp r11, #10\n"
" bne set_error_led\n"
" cmp r0, #11\n"
" bne set_error_led\n"
@ -585,7 +601,7 @@ void prvSetAndCheckRegisters( void )
" bne set_error_led\n"
" bx lr" );
__asm volatile( "set_error_led:\n"
__asm volatile ( "set_error_led:\n"
" push {r14}\n"
" ldr r1, =vSetErrorLED\n"
" blx r1\n"

View file

@ -109,7 +109,7 @@
#define mainLCD_QUEUE_LEN ( 3 )
/* 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 mainADC_CO_ROUTINE_PRIORITY ( 2 )
@ -130,7 +130,7 @@ string on UART 0. */
#define mainMAX_ADC_STRING_LEN 20
/* The LED that is lit should an error be detected in any of the tasks or
co-routines. */
* co-routines. */
#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
* 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
@ -166,7 +167,8 @@ void vSetErrorLED( void );
/*
* 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.
@ -179,12 +181,12 @@ static void prvSetupHardware( void );
/* The structure that is passed on the LCD message queue. */
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. */
} xLCDMessage;
/* 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;
/* The queue used to transmit messages to the LCD task. */
@ -207,14 +209,14 @@ void main( void )
vStartFlashCoRoutines( mainNUM_FLASH_CO_ROUTINES );
/* 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
this file. */
* on the UART and the task that receives them, as described at the top of
* this file. */
xCoRoutineCreate( vSerialTxCoRoutine, mainTX_CO_ROUTINE_PRIORITY, mainTX_CO_ROUTINE_INDEX );
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
task and co-routine that send messages for display (as described at the top
of this file. */
* task and co-routine that send messages for display (as described at the top
* of this file. */
xTaskCreate( prvLCDTask, "LCD", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainLCD_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 );
@ -223,15 +225,18 @@ void main( void )
vTaskStartScheduler();
/* Should not get here unless we did not have enough memory to start the
scheduler. */
for( ;; );
* scheduler. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvLCDMessageTask( void * pvParameters )
{
/* The strings that are written to the LCD. */
char *pcStringsToDisplay[] = {
char * pcStringsToDisplay[] =
{
"IAR ",
"Stellaris ",
"Demo ",
@ -239,16 +244,16 @@ char *pcStringsToDisplay[] = {
""
};
QueueHandle_t *pxLCDQueue;
xLCDMessage xMessageToSend;
portBASE_TYPE xIndex = 0;
QueueHandle_t * pxLCDQueue;
xLCDMessage xMessageToSend;
portBASE_TYPE xIndex = 0;
/* 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
scope variable anyway. */
* posted is passed in as a parameter even though it is available as a file
* scope variable anyway. */
pxLCDQueue = ( QueueHandle_t * ) pvParameters;
for( ;; )
for( ; ; )
{
/* Wait until it is time to move onto the next string. */
vTaskDelay( mainSTRING_WRITE_DELAY );
@ -265,6 +270,7 @@ portBASE_TYPE xIndex = 0;
/* Move onto the next message, wrapping when necessary. */
xIndex++;
if( *( pcStringsToDisplay[ xIndex ] ) == 0x00 )
{
xIndex = 0;
@ -278,11 +284,12 @@ portBASE_TYPE xIndex = 0;
void prvLCDTask( void * pvParameters )
{
unsigned portBASE_TYPE uxIndex;
QueueHandle_t *pxLCDQueue;
xLCDMessage xReceivedMessage;
char *pcString;
const unsigned char ucCFGData[] = {
unsigned portBASE_TYPE uxIndex;
QueueHandle_t * pxLCDQueue;
xLCDMessage xReceivedMessage;
char * pcString;
const unsigned char ucCFGData[] =
{
0x30, /* Set data bus to 8-bits. */
0x30,
0x30,
@ -294,12 +301,13 @@ const unsigned char ucCFGData[] = {
};
/* 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
scope variable anyway. */
* received is passed in as a parameter even though it is available as a file
* scope variable anyway. */
pxLCDQueue = ( QueueHandle_t * ) pvParameters;
/* Configure the LCD. */
uxIndex = 0;
while( uxIndex < sizeof( ucCFGData ) )
{
prvPDCWrite( PDC_LCD_CSR, ucCFGData[ uxIndex ] );
@ -315,7 +323,8 @@ const unsigned char ucCFGData[] = {
prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR );
uxIndex = 0;
for( ;; )
for( ; ; )
{
/* Wait for a message to arrive. */
if( xQueueReceive( *pxLCDQueue, &xReceivedMessage, portMAX_DELAY ) )
@ -329,7 +338,7 @@ const unsigned char ucCFGData[] = {
while( *pcString )
{
/* Don't write out the string too quickly as LCD's are usually
pretty slow devices. */
* pretty slow devices. */
vTaskDelay( mainCHAR_WRITE_DELAY );
prvPDCWrite( PDC_LCD_RAM, *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 char cMessageBuffer[ mainMAX_ADC_STRING_LEN ];
static char *pcMessage;
static xLCDMessage xMessageToSend;
static unsigned long ulADCValue;
static char cMessageBuffer[ mainMAX_ADC_STRING_LEN ];
static char * pcMessage;
static xLCDMessage xMessageToSend;
/* Co-routines MUST start with a call to crSTART(). */
crSTART( xHandle );
for( ;; )
for( ; ; )
{
/* Start an ADC conversion. */
ADCProcessorTrigger( ADC_BASE, 0 );
@ -365,11 +375,11 @@ static xLCDMessage xMessageToSend;
pcMessage = cMessageBuffer;
/* Configure the message we are going to send for display. */
xMessageToSend.ppcMessageToDisplay = ( char** ) &pcMessage;
xMessageToSend.ppcMessageToDisplay = ( char ** ) &pcMessage;
xMessageToSend.xRow = mainBOTTOM_ROW;
/* 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 ) )
{
uxErrorStatus = pdFAIL;
@ -393,14 +403,14 @@ static void prvSetupHardware( void )
/* The ADC is used to read the light sensor. */
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 );
ADCSequenceEnable( ADC_BASE, 0 );
}
/*-----------------------------------------------------------*/
static void prvPDCWrite( char cAddress, char cData )
static void prvPDCWrite( char cAddress,
char cData )
{
vTaskSuspendAll();
{
@ -419,8 +429,8 @@ void vSetErrorLED( void )
void vApplicationIdleHook( void )
{
/* The co-routines are executed in the idle task using the idle task
hook. */
for( ;; )
* hook. */
for( ; ; )
{
/* Schedule the co-routines. */
vCoRoutineSchedule();

View file

@ -60,10 +60,10 @@
*/
/*************************************************************************
* Please ensure to read http://www.freertos.org/portlm3sx965.html
* which provides information on configuring and running this demo for the
* various Luminary Micro EKs.
*************************************************************************/
* Please ensure to read http://www.freertos.org/portlm3sx965.html
* which provides information on configuring and running this demo for the
* various Luminary Micro EKs.
*************************************************************************/
/* Standard includes. */
#include <stdio.h>
@ -101,7 +101,7 @@
/*-----------------------------------------------------------*/
/* The time between cycles of the 'check' functionality (defined within the
tick hook. */
* tick hook. */
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* Task stack sizes. */
@ -115,14 +115,14 @@ tick hook. */
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* The maximum number of message that can be waiting for display at any one
time. */
* time. */
#define mainOLED_QUEUE_SIZE ( 3 )
/* Dimensions the buffer into which the jitter time is written. */
#define mainMAX_MSG_LEN 25
/* 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 ) )
/* 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
* the message to the gatekeeper.
*/
static void prvOLEDTask( void *pvParameters );
static void prvOLEDTask( void * pvParameters );
/*
* Configure the hardware for the demo.
@ -157,7 +157,8 @@ extern void vSetupHighFrequencyTimer( void );
/*
* 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 );
/*
@ -176,21 +177,21 @@ const char * const pcWelcomeMessage = " www.FreeRTOS.org";
/*-----------------------------------------------------------*/
/*************************************************************************
* Please ensure to read http://www.freertos.org/portlm3sx965.html
* which provides information on configuring and running this demo for the
* various Luminary Micro EKs.
*************************************************************************/
* Please ensure to read http://www.freertos.org/portlm3sx965.html
* which provides information on configuring and running this demo for the
* various Luminary Micro EKs.
*************************************************************************/
int main( void )
{
/* Initialise the trace recorder. Use of the trace recorder is optional.
See http://www.FreeRTOS.org/trace for more information and the comments at
the top of this file regarding enabling trace in this demo.
vTraceEnable( TRC_START ); */
* See http://www.FreeRTOS.org/trace for more information and the comments at
* the top of this file regarding enabling trace in this demo.
* vTraceEnable( TRC_START ); */
prvSetupHardware();
/* 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 * ) );
/* Start the standard demo tasks. */
@ -207,27 +208,29 @@ int main( void )
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
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. */
* 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. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Uncomment the following line to configure the high frequency interrupt
used to measure the interrupt jitter time.
vSetupHighFrequencyTimer(); */
* used to measure the interrupt jitter time.
* vSetupHighFrequencyTimer(); */
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle
task. */
for( ;; );
* task. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void prvSetupHardware( void )
{
/* 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 )
{
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 );
/* Initialise the UART - QEMU usage does not seem to require this
initialisation. */
* initialisation. */
SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
UARTEnable( UART0_BASE );
}
@ -245,13 +248,14 @@ void prvSetupHardware( void )
void vApplicationTickHook( void )
{
static const char * pcMessage = "PASS";
static uint32_t ulTicksSinceLastDisplay = 0;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
static const char * pcMessage = "PASS";
static uint32_t ulTicksSinceLastDisplay = 0;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* 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++;
if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
{
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
demonstrate using queue sets from an ISR. */
* demonstrate using queue sets from an ISR. */
vQueueSetAccessQueueSetFromISR();
/* 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;
uint32_t ulY, ulMaxY;
static char cMessage[ mainMAX_MSG_LEN ];
const unsigned char *pucImage;
const char * pcMessage;
uint32_t ulY, ulMaxY;
static char cMessage[ mainMAX_MSG_LEN ];
const unsigned char * pucImage;
/* Functions to access the OLED. The one used depends on the dev kit
being used. */
void ( *vOLEDInit )( uint32_t ) = NULL;
void ( *vOLEDStringDraw )( const char *, uint32_t, uint32_t, unsigned char ) = NULL;
void ( *vOLEDImageDraw )( const unsigned char *, uint32_t, uint32_t, uint32_t, uint32_t ) = NULL;
void ( *vOLEDClear )( void ) = NULL;
* being used. */
void ( * vOLEDInit )( uint32_t ) = NULL;
void ( * vOLEDStringDraw )( const char *,
uint32_t,
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. */
( void ) pvParameters;
/* 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 );
vOLEDInit = OSRAM128x64x4Init;
vOLEDStringDraw = OSRAM128x64x4StringDraw;
@ -354,13 +365,14 @@ void ( *vOLEDClear )( void ) = NULL;
vOLEDStringDraw( "POWERED BY FreeRTOS", 0, 0, mainFULL_SCALE );
vOLEDImageDraw( pucImage, 0, mainCHARACTER_HEIGHT + 1, bmpBITMAP_WIDTH, bmpBITMAP_HEIGHT );
for( ;; )
for( ; ; )
{
/* Wait for a message to arrive that requires displaying. */
xQueueReceive( xOLEDQueue, &pcMessage, portMAX_DELAY );
/* Write the message on the next available row. */
ulY += mainCHARACTER_HEIGHT;
if( ulY >= ulMaxY )
{
ulY = mainCHARACTER_HEIGHT;
@ -369,7 +381,7 @@ void ( *vOLEDClear )( void ) = NULL;
}
/* 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() );
vOLEDStringDraw( cMessage, 0, ulY, mainFULL_SCALE );
prvPrintString( cMessage );
@ -378,27 +390,32 @@ void ( *vOLEDClear )( void ) = NULL;
}
/*-----------------------------------------------------------*/
volatile char *pcOverflowedTask = NULL; /* Prevent task name being optimised away. */
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
volatile char * pcOverflowedTask = NULL; /* Prevent task name being optimised away. */
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pxTask;
pcOverflowedTask = pcTaskName;
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();
{
while( ulSetTo1InDebuggerToExit == 0 )
{
/* 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 assertion. */
* the debugger to step out of this function to the point that caused
* the assertion. */
( void ) pcFile;
( void ) ulLine;
}
@ -407,56 +424,61 @@ volatile uint32_t ulSetTo1InDebuggerToExit = 0;
}
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
* used by the Idle task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* 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;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
* application must provide an implementation of vApplicationGetTimerTaskMemory()
* to provide the memory that is used by the Timer service task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* 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;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*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. */
( void ) r;

View file

@ -83,7 +83,7 @@
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* UART configuration - note this does not use the FIFO so is not very
efficient. */
* efficient. */
#define mainBAUD_RATE ( 19200 )
#define mainFIFO_SET ( 0x10 )
@ -100,6 +100,7 @@ efficient. */
#define mainQUEUE_SIZE ( 3 )
#define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS )
#define mainNO_DELAY ( ( TickType_t ) 0 )
/*
* 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.
*/
static void vCheckTask( void *pvParameters );
static void vCheckTask( void * pvParameters );
/*
* The task that is woken by the ISR that processes GPIO interrupts originating
* from the push button.
*/
static void vButtonHandlerTask( void *pvParameters );
static void vButtonHandlerTask( void * pvParameters );
/*
* 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. */
static char *cMessage = "Task woken by button interrupt! --- ";
static volatile char *pcNextChar;
static char * cMessage = "Task woken by button interrupt! --- ";
static volatile char * pcNextChar;
/* The semaphore used to wake the button handler task from within the GPIO
interrupt handler. */
* interrupt handler. */
SemaphoreHandle_t xButtonSemaphore;
/* The queue used to send strings to the print task for display on the LCD. */
@ -140,7 +141,7 @@ int main( void )
prvSetupHardware();
/* Create the semaphore used to wake the button handler task from the GPIO
ISR. */
* ISR. */
vSemaphoreCreateBinary( xButtonSemaphore );
xSemaphoreTake( xButtonSemaphore, 0 );
@ -162,24 +163,24 @@ int main( void )
vTaskStartScheduler();
/* Will only get here if there was insufficient heap to start the
scheduler. */
* scheduler. */
return 0;
}
/*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters )
static void vCheckTask( void * pvParameters )
{
portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime;
const char *pcPassMessage = "PASS";
const char *pcFailMessage = "FAIL";
portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime;
const char * pcPassMessage = "PASS";
const char * pcFailMessage = "FAIL";
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */
* works correctly. */
xLastExecutionTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Perform this check every mainCHECK_DELAY milliseconds. */
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
never cleared again. We do not write directly to the LCD, but instead
queue a message for display by the print task. */
* never cleared again. We do not write directly to the LCD, but instead
* queue a message for display by the print task. */
if( xErrorOccurred == pdTRUE )
{
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 );
/* Setup the push button. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN);
GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE );
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOC );
GPIODirModeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN );
GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_FALLING_EDGE );
IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY );
GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON );
IntEnable( INT_GPIOC );
@ -237,18 +238,18 @@ static void prvSetupHardware( void )
/* Enable the UART. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOA );
/* 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 );
/* 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 );
/* 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;
/* Enable Tx interrupts. */
@ -259,19 +260,21 @@ static void prvSetupHardware( void )
/* Initialise the LCD> */
OSRAMInit( false );
OSRAMStringDraw("www.FreeRTOS.org", 0, 0);
OSRAMStringDraw("LM3S811 demo", 16, 1);
OSRAMStringDraw( "www.FreeRTOS.org", 0, 0 );
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. */
while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS );
while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS )
{
}
/* Start the Tx of the message on the UART. */
UARTIntDisable( UART0_BASE, UART_INT_TX );
@ -286,7 +289,7 @@ const char *pcInterruptMessage = "Int";
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. */
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. */
ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
@ -319,6 +322,7 @@ unsigned long ulStatus;
{
HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
}
pcNextChar++;
}
}
@ -327,10 +331,10 @@ unsigned long ulStatus;
void vGPIO_ISR( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt. */
GPIOPinIntClear(GPIO_PORTC_BASE, mainPUSH_BUTTON);
GPIOPinIntClear( GPIO_PORTC_BASE, mainPUSH_BUTTON );
/* Wake the button handler task. */
xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );
@ -339,12 +343,12 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
}
/*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters )
static void vPrintTask( void * pvParameters )
{
char *pcMessage;
unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
char * pcMessage;
unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
for( ;; )
for( ; ; )
{
/* Wait for a message to arrive. */
xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY );
@ -353,7 +357,6 @@ unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
uxRow++;
uxLine++;
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 )
/* UART configuration - note this does not use the FIFO so is not very
efficient. */
* efficient. */
#define mainBAUD_RATE ( 19200 )
#define mainFIFO_SET ( 0x10 )
@ -100,6 +100,7 @@ efficient. */
#define mainQUEUE_SIZE ( 3 )
#define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS )
#define mainNO_DELAY ( ( TickType_t ) 0 )
/*
* 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.
*/
static void vCheckTask( void *pvParameters );
static void vCheckTask( void * pvParameters );
/*
* The task that is woken by the ISR that processes GPIO interrupts originating
* from the push button.
*/
static void vButtonHandlerTask( void *pvParameters );
static void vButtonHandlerTask( void * pvParameters );
/*
* 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. */
static char *cMessage = "Task woken by button interrupt! --- ";
static volatile char *pcNextChar;
static char * cMessage = "Task woken by button interrupt! --- ";
static volatile char * pcNextChar;
/* The semaphore used to wake the button handler task from within the GPIO
interrupt handler. */
* interrupt handler. */
SemaphoreHandle_t xButtonSemaphore;
/* The queue used to send strings to the print task for display on the LCD. */
@ -140,7 +141,7 @@ int main( void )
prvSetupHardware();
/* Create the semaphore used to wake the button handler task from the GPIO
ISR. */
* ISR. */
vSemaphoreCreateBinary( xButtonSemaphore );
xSemaphoreTake( xButtonSemaphore, 0 );
@ -162,24 +163,24 @@ int main( void )
vTaskStartScheduler();
/* Will only get here if there was insufficient heap to start the
scheduler. */
* scheduler. */
return 0;
}
/*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters )
static void vCheckTask( void * pvParameters )
{
portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime;
const char *pcPassMessage = "PASS";
const char *pcFailMessage = "FAIL";
portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime;
const char * pcPassMessage = "PASS";
const char * pcFailMessage = "FAIL";
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */
* works correctly. */
xLastExecutionTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Perform this check every mainCHECK_DELAY milliseconds. */
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
never cleared again. We do not write directly to the LCD, but instead
queue a message for display by the print task. */
* never cleared again. We do not write directly to the LCD, but instead
* queue a message for display by the print task. */
if( xErrorOccurred == pdTRUE )
{
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 );
/* Setup the push button. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN);
GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE );
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOC );
GPIODirModeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN );
GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_FALLING_EDGE );
IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY );
GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON );
IntEnable( INT_GPIOC );
@ -237,18 +238,18 @@ static void prvSetupHardware( void )
/* Enable the UART. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOA );
/* 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 );
/* 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 );
/* 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;
/* Enable Tx interrupts. */
@ -259,19 +260,21 @@ static void prvSetupHardware( void )
/* Initialise the LCD> */
OSRAMInit( false );
OSRAMStringDraw("www.FreeRTOS.org", 0, 0);
OSRAMStringDraw("LM3S811 demo", 16, 1);
OSRAMStringDraw( "www.FreeRTOS.org", 0, 0 );
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. */
while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS );
while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS )
{
}
/* Start the Tx of the message on the UART. */
UARTIntDisable( UART0_BASE, UART_INT_TX );
@ -286,7 +289,7 @@ const char *pcInterruptMessage = "Int";
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. */
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. */
ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
@ -319,6 +322,7 @@ unsigned long ulStatus;
{
HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
}
pcNextChar++;
}
}
@ -327,10 +331,10 @@ unsigned long ulStatus;
void vGPIO_ISR( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt. */
GPIOPinIntClear(GPIO_PORTC_BASE, mainPUSH_BUTTON);
GPIOPinIntClear( GPIO_PORTC_BASE, mainPUSH_BUTTON );
/* Wake the button handler task. */
xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );
@ -338,12 +342,12 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
}
/*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters )
static void vPrintTask( void * pvParameters )
{
char *pcMessage;
unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
char * pcMessage;
unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
for( ;; )
for( ; ; )
{
/* Wait for a message to arrive. */
xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY );
@ -352,7 +356,6 @@ unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
uxRow++;
uxLine++;
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 )
/* UART configuration - note this does not use the FIFO so is not very
efficient. */
* efficient. */
#define mainBAUD_RATE ( 19200 )
#define mainFIFO_SET ( 0x10 )
@ -100,6 +100,7 @@ efficient. */
#define mainQUEUE_SIZE ( 3 )
#define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS )
#define mainNO_DELAY ( ( TickType_t ) 0 )
/*
* 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.
*/
static void vCheckTask( void *pvParameters );
static void vCheckTask( void * pvParameters );
/*
* The task that is woken by the ISR that processes GPIO interrupts originating
* from the push button.
*/
static void vButtonHandlerTask( void *pvParameters );
static void vButtonHandlerTask( void * pvParameters );
/*
* 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. */
static char *cMessage = "Task woken by button interrupt! --- ";
static volatile char *pcNextChar;
static char * cMessage = "Task woken by button interrupt! --- ";
static volatile char * pcNextChar;
/* The semaphore used to wake the button handler task from within the GPIO
interrupt handler. */
* interrupt handler. */
SemaphoreHandle_t xButtonSemaphore;
/* The queue used to send strings to the print task for display on the LCD. */
QueueHandle_t xPrintQueue;
/* 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 )
@ -142,7 +146,7 @@ int main( void )
prvSetupHardware();
/* Create the semaphore used to wake the button handler task from the GPIO
ISR. */
* ISR. */
vSemaphoreCreateBinary( xButtonSemaphore );
xSemaphoreTake( xButtonSemaphore, 0 );
@ -164,24 +168,24 @@ int main( void )
vTaskStartScheduler();
/* Will only get here if there was insufficient heap to start the
scheduler. */
* scheduler. */
return 0;
}
/*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters )
static void vCheckTask( void * pvParameters )
{
portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime;
const char *pcPassMessage = "PASS";
const char *pcFailMessage = "FAIL";
portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime;
const char * pcPassMessage = "PASS";
const char * pcFailMessage = "FAIL";
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */
* works correctly. */
xLastExecutionTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Perform this check every mainCHECK_DELAY milliseconds. */
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
never cleared again. We do not write directly to the LCD, but instead
queue a message for display by the print task. */
* never cleared again. We do not write directly to the LCD, but instead
* queue a message for display by the print task. */
if( xErrorOccurred == pdTRUE )
{
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 );
/* Setup the push button. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN);
GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE );
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOC );
GPIODirModeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN );
GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_FALLING_EDGE );
IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY );
GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON );
IntEnable( INT_GPIOC );
@ -239,18 +243,18 @@ static void prvSetupHardware( void )
/* Enable the UART. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOA );
/* 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 );
/* 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 );
/* 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;
/* Enable Tx interrupts. */
@ -261,19 +265,21 @@ static void prvSetupHardware( void )
/* Initialise the LCD> */
OSRAMInit( false );
OSRAMStringDraw("www.FreeRTOS.org", 0, 0);
OSRAMStringDraw("LM3S811 demo", 16, 1);
OSRAMStringDraw( "www.FreeRTOS.org", 0, 0 );
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. */
while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS );
while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS )
{
}
/* Start the Tx of the message on the UART. */
UARTIntDisable( UART0_BASE, UART_INT_TX );
@ -288,7 +294,7 @@ const char *pcInterruptMessage = "Int";
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. */
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. */
ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
@ -321,6 +327,7 @@ unsigned long ulStatus;
{
HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
}
pcNextChar++;
}
}
@ -329,7 +336,7 @@ unsigned long ulStatus;
void vGPIO_ISR( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt. */
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;
unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
char * pcMessage;
unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
for( ;; )
for( ; ; )
{
/* Wait for a message to arrive. */
xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY );
@ -354,7 +361,6 @@ unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
uxRow++;
uxLine++;
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 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter
functionality. */
* functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
@ -94,8 +94,8 @@ functionality. */
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*
* Called by main() to create the simply blinky style application if
@ -123,7 +123,7 @@ void main_blinky( void )
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
* file. */
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. */
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
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 tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */
for( ;; );
* 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 tasks to be created. See the memory management section on the
* FreeRTOS web site for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */
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. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* 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
to ms. While in the Blocked state this task will not consume any CPU
time. */
* 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
* time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
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. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
vParTestToggleLED( mainLED_TO_TOGGLE );
@ -198,4 +200,3 @@ unsigned long ulReceivedValue;
}
}
/*-----------------------------------------------------------*/

View file

@ -91,27 +91,27 @@
#include "QueueSet.h"
/* 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
equivalent in ticks using the portTICK_PERIOD_MS constant. */
* been reported by any of the standard demo tasks. ms are converted to the
* equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* 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
in ticks using the portTICK_PERIOD_MS constant. */
* reported in one of the standard demo tasks. ms are converted to the equivalent
* in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL )
/* 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 )
/* The LED toggle by the check timer. */
#define mainCHECK_LED ( 4 )
/* 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 )
/*-----------------------------------------------------------*/
@ -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
* these files necessitates that they are written in an assembly.
*/
extern void vRegTest1Task( void *pvParameters );
extern void vRegTest2Task( void *pvParameters );
extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void * pvParameters );
/*
* 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
* 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
@ -154,27 +154,28 @@ void main_full( void );
/*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */
* register check tasks to the check software timer. If the variables keep
* incrementing, then the register check tasks have not discovered any errors. If
* a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/* 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
task toggles LED mainSEMAPHORE_LED each time the semaphore is taken. */
* and taken by the task implemented by the prvSemaphoreTakeTask() function. The
* task toggles LED mainSEMAPHORE_LED each time the semaphore is taken. */
SemaphoreHandle_t xLEDSemaphore = NULL;
/*-----------------------------------------------------------*/
void main_full( void )
{
TimerHandle_t xTimer = NULL;
unsigned long ulTimer;
const unsigned long ulTimersToCreate = 3L;
TimerHandle_t xTimer = NULL;
unsigned long ulTimer;
const unsigned long ulTimersToCreate = 3L;
/* 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
for the additional required for the stack overflow checking to work (if
configured). */
const size_t xRegTestStackSize = 25U;
* 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
* configured). */
const size_t xRegTestStackSize = 25U;
/* Create the standard demo tasks */
vCreateBlockTimeTasks();
@ -185,7 +186,7 @@ const size_t xRegTestStackSize = 25U;
vStartQueueSetTasks();
/* 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 );
xTaskCreate( prvSemaphoreTakeTask, /* Function that implements 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. */
/* 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
to be allocated to hold the task context. */
* These are naked functions that don't use any stack. A stack still has
* to be allocated to hold the task context. */
xTaskCreate( vRegTest1Task, /* Function that implements the task. */
"Reg1", /* Text name of 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,
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. */
( 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. */
@ -237,9 +238,9 @@ const size_t xRegTestStackSize = 25U;
);
/* If the software timer was created successfully, start it. It won't
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
time will be ignored because the scheduler has not started yet. */
* 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
* time will be ignored because the scheduler has not started yet. */
if( xTimer != NULL )
{
xTimerStart( xTimer, mainDONT_BLOCK );
@ -249,23 +250,25 @@ const size_t xRegTestStackSize = 25U;
vTaskStartScheduler();
/* 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 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, or the FreeRTOS tutorial books for more details. */
for( ;; );
* 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
* tasks to be created. See the memory management section on the FreeRTOS web
* site, or the FreeRTOS tutorial books for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
/* See the description at the top of this file. */
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
/* 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 )
{
ulErrorFound |= ( 0x01UL << 0UL );
@ -291,6 +294,7 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound |= ( 0x01UL << 4UL );
}
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */
@ -298,6 +302,7 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound |= ( 0x01UL << 5UL );
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
if( xAreQueueSetTasksStillRunning() != pdPASS )
@ -311,14 +316,14 @@ unsigned long ulErrorFound = pdFALSE;
}
/* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */
* the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
* everything is ok. A faster toggle indicates an error. */
vParTestToggleLED( mainCHECK_LED );
/* Have any errors been latched in ulErrorFound? If so, shorten the
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
toggles. */
* 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
* toggles. */
if( ulErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == pdFALSE )
@ -326,22 +331,22 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must
*never* attempt to block. */
* Functions called from inside of a timer callback function must
* never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
}
/*-----------------------------------------------------------*/
static void prvSemaphoreTakeTask( void *pvParameters )
static void prvSemaphoreTakeTask( void * pvParameters )
{
configASSERT( xLEDSemaphore );
for( ;; )
for( ; ; )
{
/* Wait to obtain the semaphore - which is given by the tick hook
function every 50ms. */
* function every 50ms. */
xSemaphoreTake( xLEDSemaphore, portMAX_DELAY );
vParTestToggleLED( mainSEMAPHORE_LED );
}
@ -350,14 +355,13 @@ static void prvSemaphoreTakeTask( void *pvParameters )
static void prvFlashTimerCallback( TimerHandle_t xTimer )
{
unsigned long ulLED;
unsigned long ulLED;
/* This callback function is assigned to three separate software timers.
Each timer toggles a different LED. Obtain the number of the LED that
this timer is toggling. */
* Each timer toggles a different LED. Obtain the number of the LED that
* this timer is toggling. */
ulLED = ( unsigned long ) pvTimerGetTimerID( xTimer );
/* Toggle the LED. */
vParTestToggleLED( ulLED );
}

View file

@ -54,7 +54,7 @@
#include "QueueSet.h"
/* 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
@ -86,7 +86,7 @@ int main( void )
prvSetupHardware();
/* 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
{
main_blinky();
@ -111,62 +111,69 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
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.
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
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
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
* 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.
* 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
* 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
* FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* 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
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
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
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. */
* 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
* to block in any way (for example, call xQueueReceive() with a block time
* specified, or call vTaskDelay()). If the application makes use of the
* vTaskDelete() API function (as this demo application does) then it is also
* important that vApplicationIdleHook() is permitted to return to its calling
* 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. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
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
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
tick hook implementation is for demonstration only - it has no real
purpose. It just gives a semaphore every 50ms. The semaphore unblocks a
task that then toggles an LED. Additionally, the call to
vQueueSetAccessQueueSetFromISR() is part of the "standard demo tasks"
functionality. */
* 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
* 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
* tick hook implementation is for demonstration only - it has no real
* purpose. It just gives a semaphore every 50ms. The semaphore unblocks a
* task that then toggles an LED. Additionally, the call to
* vQueueSetAccessQueueSetFromISR() is part of the "standard demo tasks"
* functionality. */
/* 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
{
static unsigned long ulLastGiveTime = 0UL;
@ -178,16 +185,16 @@ void vApplicationTickHook( void )
if( ( xTaskGetTickCountFromISR() - ulLastGiveTime ) > ulRate )
{
/* The second parameter is normally used to determine if a context
switch should be performed or not. In this case the function is
being performed from the tick hook, so the scheduler will make that
assessment before returning to a task anyway - so the parameter is
not needed and is just set to NULL. */
* switch should be performed or not. In this case the function is
* being performed from the tick hook, so the scheduler will make that
* assessment before returning to a task anyway - so the parameter is
* not needed and is just set to NULL. */
xSemaphoreGiveFromISR( xLEDSemaphore, NULL );
ulLastGiveTime += ulRate;
}
/* 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();
}
#endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */
@ -196,32 +203,28 @@ void vApplicationTickHook( void )
#ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void)
{
long lHigherPriorityTaskWoken = pdFALSE;
void Dummy_IRQHandler( void )
{
long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. Only FreeRTOS API functions
that end in "FromISR" can be called from an ISR. */
* task with an interrupt. A semaphore is used for this purpose. Note
* lHigherPriorityTaskWoken is initialised to zero. Only FreeRTOS API functions
* that end in "FromISR" can be called from an ISR. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* 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
higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
* 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
* interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
* internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
* portEND_SWITCHING_ISR() macro will result in a context switch being pended to
* ensure this interrupt returns directly to the unblocked, higher priority,
* task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
}
#endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -77,16 +77,16 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter
functionality. */
* functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
/*-----------------------------------------------------------*/
@ -94,8 +94,8 @@ functionality. */
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*
* Called by main() to create the simply blinky style application if
@ -123,7 +123,7 @@ void main_blinky( void )
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
* file. */
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. */
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
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 tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */
for( ;; );
* 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 tasks to be created. See the memory management section on the
* FreeRTOS web site for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */
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. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* 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
to ms. While in the Blocked state this task will not consume any CPU
time. */
* 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
* time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
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. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
vParTestToggleLED( LED1 );
@ -198,4 +200,3 @@ unsigned long ulReceivedValue;
}
}
/*-----------------------------------------------------------*/

View file

@ -87,20 +87,20 @@
#include "stm320518_eval.h"
/* 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
equivalent in ticks using the portTICK_PERIOD_MS constant. */
* been reported by any of the standard demo tasks. ms are converted to the
* equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* 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
in ticks using the portTICK_PERIOD_MS constant. */
* reported in one of the standard demo tasks. ms are converted to the equivalent
* in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL )
/* 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 )
/* 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
* these files necessitates that they are written in an assembly.
*/
extern void vRegTest1Task( void *pvParameters );
extern void vRegTest2Task( void *pvParameters );
extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void * pvParameters );
/*
* 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
register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */
* register check tasks to the check software timer. If the variables keep
* incrementing, then the register check tasks have not discovered any errors. If
* a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/
void main_full( void )
{
TimerHandle_t xTimer = NULL;
unsigned long ulTimer;
const unsigned long ulTimersToCreate = 3L;
TimerHandle_t xTimer = NULL;
unsigned long ulTimer;
const unsigned long ulTimersToCreate = 3L;
/* 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
for the additional required for the stack overflow checking to work (if
configured). */
const size_t xRegTestStackSize = 25U;
* 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
* configured). */
const size_t xRegTestStackSize = 25U;
/* Create the standard demo tasks */
vCreateBlockTimeTasks();
@ -164,8 +165,8 @@ const size_t xRegTestStackSize = 25U;
vStartDynamicPriorityTasks();
/* 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
to be allocated to hold the task context. */
* These are naked functions that don't use any stack. A stack still has
* to be allocated to hold the task context. */
xTaskCreate( vRegTest1Task, /* Function that implements the task. */
"Reg1", /* Text name of 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,
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. */
( 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. */
@ -206,9 +207,9 @@ const size_t xRegTestStackSize = 25U;
);
/* If the software timer was created successfully, start it. It won't
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
time will be ignored because the scheduler has not started yet. */
* 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
* time will be ignored because the scheduler has not started yet. */
if( xTimer != NULL )
{
xTimerStart( xTimer, mainDONT_BLOCK );
@ -218,23 +219,25 @@ const size_t xRegTestStackSize = 25U;
vTaskStartScheduler();
/* 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 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, or the FreeRTOS tutorial books for more details. */
for( ;; );
* 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
* tasks to be created. See the memory management section on the FreeRTOS web
* site, or the FreeRTOS tutorial books for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
/* See the description at the top of this file. */
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
/* 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 )
{
ulErrorFound |= ( 0x01UL << 0UL );
@ -260,6 +263,7 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound |= ( 0x01UL << 4UL );
}
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */
@ -267,17 +271,18 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound |= ( 0x01UL << 5UL );
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */
* the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
* everything is ok. A faster toggle indicates an error. */
vParTestToggleLED( mainCHECK_LED );
/* Have any errors been latched in ulErrorFound? If so, shorten the
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
toggles. */
* 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
* toggles. */
if( ulErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == pdFALSE )
@ -285,8 +290,8 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must
*never* attempt to block. */
* Functions called from inside of a timer callback function must
* never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
@ -295,14 +300,13 @@ unsigned long ulErrorFound = pdFALSE;
static void prvFlashTimerCallback( TimerHandle_t xTimer )
{
unsigned long ulLED;
unsigned long ulLED;
/* This callback function is assigned to three separate software timers.
Each timer toggles a different LED. Obtain the number of the LED that
this timer is toggling. */
* Each timer toggles a different LED. Obtain the number of the LED that
* this timer is toggling. */
ulLED = ( unsigned long ) pvTimerGetTimerID( xTimer );
/* Toggle the LED. */
vParTestToggleLED( ulLED );
}

View file

@ -52,7 +52,7 @@
#include "ParTest.h"
/* 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
@ -65,7 +65,7 @@ or 0 to run the more comprehensive test and demo application. */
static void prvSetupHardware( void );
/* 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_full( void );
@ -77,7 +77,7 @@ int main( void )
prvSetupHardware();
/* 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
{
main_blinky();
@ -101,85 +101,88 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
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.
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
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
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
* 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.
* 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
* 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
* FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* 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
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
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
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. */
* 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
* to block in any way (for example, call xQueueReceive() with a block time
* specified, or call vTaskDelay()). If the application makes use of the
* vTaskDelete() API function (as this demo application does) then it is also
* important that vApplicationIdleHook() is permitted to return to its calling
* 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. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
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
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
* 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
* code must not attempt to block, and only the interrupt safe FreeRTOS API
* functions can be used (those that end in FromISR()). */
}
/*-----------------------------------------------------------*/
#ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void)
{
long lHigherPriorityTaskWoken = pdFALSE;
void Dummy_IRQHandler( void )
{
long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. Only FreeRTOS API functions
that end in "FromISR" can be called from an ISR. */
* task with an interrupt. A semaphore is used for this purpose. Note
* lHigherPriorityTaskWoken is initialised to zero. Only FreeRTOS API functions
* that end in "FromISR" can be called from an ISR. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* 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
higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
* 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
* interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
* internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
* portEND_SWITCHING_ISR() macro will result in a context switch being pended to
* ensure this interrupt returns directly to the unblocked, higher priority,
* task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
}
#endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -52,9 +52,9 @@
#include "task.h"
/* Hardware register addresses. */
#define mainVTOR ( * ( uint32_t * ) 0xE000ED08 )
#define mainNVIC_AUX_ACTLR ( * ( uint32_t * ) 0xE000E008 )
#define mainEC_INTERRUPT_CONTROL ( * ( volatile uint32_t * ) 0x4000FC18 )
#define mainVTOR ( *( uint32_t * ) 0xE000ED08 )
#define mainNVIC_AUX_ACTLR ( *( uint32_t * ) 0xE000E008 )
#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_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 );
@ -75,27 +75,28 @@ static void prvSetupHardware( void );
extern void main_full( void );
/* 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. */
/* 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. */
extern void vFullDemoTickHook( void );
#endif /* #if configCREATE_LOW_POWER_DEMO == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
* within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void );
/*-----------------------------------------------------------*/
/* 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
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.
See the comments in main_low_power.c and main_full.c for information on the
expected LED toggle rate). */
* 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
* 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
* expected LED toggle rate). */
volatile uint32_t ulLED = 0;
/*-----------------------------------------------------------*/
@ -108,11 +109,11 @@ int main( void )
prvSetupHardware();
/* The configCREATE_LOW_POWER_DEMO setting is described at the top
of this file. */
#if( configCREATE_LOW_POWER_DEMO == 1 )
* of this file. */
#if ( configCREATE_LOW_POWER_DEMO == 1 )
{
/* 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;
main_low_power();
@ -120,12 +121,12 @@ int main( void )
#else
{
/* 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;
main_full();
}
#endif
#endif /* if ( configCREATE_LOW_POWER_DEMO == 1 ) */
/* Should not get here. */
return 0;
@ -134,8 +135,8 @@ int main( void )
static void prvSetupHardware( void )
{
extern void system_set_ec_clock( void );
extern unsigned long __Vectors[];
extern void system_set_ec_clock( void );
extern unsigned long __Vectors[];
/* Disable M4 write buffer: fix CEC1302 hardware bug. */
mainNVIC_AUX_ACTLR |= 0x07;
@ -143,7 +144,7 @@ extern unsigned long __Vectors[];
system_set_ec_clock();
/* 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;
}
/*-----------------------------------------------------------*/
@ -151,24 +152,25 @@ extern unsigned long __Vectors[];
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
@ -177,15 +179,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
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
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
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
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */
* 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
* 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
* configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
* RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -196,11 +198,11 @@ volatile size_t xFreeHeapSpace;
void vApplicationTickHook( void )
{
/* 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
interaction from an interrupt - for which the tick interrupt is used
via the tick hook function. */
* interaction from an interrupt - for which the tick interrupt is used
* via the tick hook function. */
vFullDemoTickHook();
}
#endif
@ -208,52 +210,54 @@ void vApplicationTickHook( void )
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
* used by the Idle task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* 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;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
* application must provide an implementation of vApplicationGetTimerTaskMemory()
* to provide the memory that is used by the Timer service task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* 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;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}

View file

@ -47,10 +47,10 @@
#include "task.h"
/* Hardware register addresses and value. */
#define mainVTOR ( * ( uint32_t * ) 0xE000ED08 )
#define mainNVIC_AUX_ACTLR ( * ( uint32_t * ) 0xE000E008 )
#define mainEC_INTERRUPT_CONTROL ( * ( volatile uint32_t * ) 0x4000FC18 )
#define mainMMCR_PCR_PROCESSOR_CLOCK_CONTROL ( * ( volatile uint32_t * )( 0x40080120 ) )
#define mainVTOR ( *( uint32_t * ) 0xE000ED08 )
#define mainNVIC_AUX_ACTLR ( *( uint32_t * ) 0xE000E008 )
#define mainEC_INTERRUPT_CONTROL ( *( volatile uint32_t * ) 0x4000FC18 )
#define mainMMCR_PCR_PROCESSOR_CLOCK_CONTROL ( *( volatile uint32_t * ) ( 0x40080120 ) )
#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_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 );
@ -72,27 +72,28 @@ static void prvSetupHardware( void );
extern void main_full( void );
/* 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. */
/* 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. */
extern void vFullDemoTickHook( void );
#endif /* #if configCREATE_LOW_POWER_DEMO == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
* within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void );
/*-----------------------------------------------------------*/
/* 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
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.
See the comments in main_low_power.c and main_full.c for information on the
expected LED toggle rate). */
* 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
* 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
* expected LED toggle rate). */
volatile uint32_t ulLED = 0;
/*-----------------------------------------------------------*/
@ -103,8 +104,8 @@ int main( void )
prvSetupHardware();
/* The configCREATE_LOW_POWER_DEMO setting is described at the top
of this file. */
#if( configCREATE_LOW_POWER_DEMO == 1 )
* of this file. */
#if ( configCREATE_LOW_POWER_DEMO == 1 )
{
main_low_power();
}
@ -125,7 +126,7 @@ static void prvSetupHardware( void )
mainNVIC_AUX_ACTLR |= 0x07;
/* 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;
/* Enable alternative NVIC vectors. */
@ -141,24 +142,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
@ -167,15 +169,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
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
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
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
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */
* 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
* 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
* configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
* RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -186,11 +188,11 @@ volatile size_t xFreeHeapSpace;
void vApplicationTickHook( void )
{
/* 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
interaction from an interrupt - for which the tick interrupt is used
via the tick hook function. */
* interaction from an interrupt - for which the tick interrupt is used
* via the tick hook function. */
vFullDemoTickHook();
}
#endif
@ -198,52 +200,54 @@ void vApplicationTickHook( void )
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
* used by the Idle task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* 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;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
* application must provide an implementation of vApplicationGetTimerTaskMemory()
* to provide the memory that is used by the Timer service task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* 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;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}

View file

@ -48,12 +48,12 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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 ) )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#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
* 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.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/
/* configSUPPORT_STATIC_ALLOCATION is 1 and configSUPPORT_DYNAMIC_ALLOCATION is
0 so the queue structure and the queue storage area can only be statically
allocated. See http://TBD for more information.
The queue storage area is dimensioned to hold just one 32-bit value. */
* 0 so the queue structure and the queue storage area can only be statically
* allocated. See http://TBD for more information.
* The queue storage area is dimensioned to hold just one 32-bit value. */
static StaticQueue_t xStaticQueue;
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;
/* 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
allocated. See http://TBD for more information. */
* 0 so the task structure and the stacks used by the tasks can only be statically
* allocated. See http://TBD for more information. */
StaticTask_t xRxTCBBuffer, xTxTCBBuffer;
static StackType_t uxRxStackBuffer[ configMINIMAL_STACK_SIZE ], uxTxStackBuffer[ configMINIMAL_STACK_SIZE ];
@ -102,22 +102,22 @@ int main( void )
prvITMPrintString( "Starting\r\n" );
/* Create the queue. xQueueCreateStatic() has two more parameters than 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
the StaticQueue_t structure that will hold the queue state information in
an anonymous way. */
* xQueueCreate() function. The first new parameter is a pointer to the
* 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
* an anonymous way. */
xQueue = xQueueCreateStatic( mainQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
sizeof( uint32_t ), /* The size of each item. */
ucQueueStorageArea, /* The buffer used to hold items within 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
file. */
* file. */
xTaskCreateStatic( prvQueueReceiveTask, /* Function that implements the task. */
"Rx", /* Human readable name for the task. */
configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
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. */
&xRxTCBBuffer ); /* The variable that will hold that task's TCB. */
@ -133,51 +133,53 @@ int main( void )
vTaskStartScheduler();
/* If dynamic memory allocation was used then the following code line would
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
then the following line should never be reached. */
for( ;; );
* 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
* then the following line should never be reached. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* 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
to ms. While in the Blocked state this task will not consume any CPU
time. */
* 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
* time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
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
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
/* 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
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 ) pcTaskName;
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
* used by the Idle task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* 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;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
* application must provide an implementation of vApplicationGetTimerTaskMemory()
* to provide the memory that is used by the Timer service task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* 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;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
/*-----------------------------------------------------------*/
static void prvITMPrintString( const char *pcString )
static void prvITMPrintString( const char * pcString )
{
while( *pcString != 0x00 )
{
@ -263,4 +273,3 @@ static void prvITMPrintString( const char *pcString )
}
}
/*-----------------------------------------------------------*/

View file

@ -62,7 +62,7 @@
#include "task.h"
/* 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
/*-----------------------------------------------------------*/
@ -87,7 +87,7 @@ int main( void )
prvSetupHardware();
/* 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
{
main_blinky();
@ -114,80 +114,87 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
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.
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
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
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
* 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.
* 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
* 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
* FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* 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
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
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
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. */
* 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
* to block in any way (for example, call xQueueReceive() with a block time
* specified, or call vTaskDelay()). If the application makes use of the
* vTaskDelete() API function (as this demo application does) then it is also
* important that vApplicationIdleHook() is permitted to return to its calling
* 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. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
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
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
* 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
* code must not attempt to block, and only the interrupt safe FreeRTOS API
* functions can be used (those that end in FromISR()). */
}
/*-----------------------------------------------------------*/
#ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void)
{
long lHigherPriorityTaskWoken = pdFALSE;
void Dummy_IRQHandler( void )
{
long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. */
* task with an interrupt. A semaphore is used for this purpose. Note
* lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* 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
higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
* 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
* interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
* internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
* portEND_SWITCHING_ISR() macro will result in a context switch being pended to
* ensure this interrupt returns directly to the unblocked, higher priority,
* task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
}
#endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -74,16 +74,16 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter
functionality. */
* functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
@ -92,8 +92,8 @@ functionality. */
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*
* Called by main() to create the simply blinky style application if
@ -116,7 +116,7 @@ void main_blinky( void )
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
* file. */
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. */
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
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 tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */
for( ;; );
* 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 tasks to be created. See the memory management section on the
* FreeRTOS web site for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */
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. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* 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
to ms. While in the Blocked state this task will not consume any CPU
time. */
* 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
* time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
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. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
configTOGGLE_LED();
@ -191,4 +193,3 @@ unsigned long ulReceivedValue;
}
}
/*-----------------------------------------------------------*/

View file

@ -93,13 +93,13 @@
#define mainDONT_BLOCK ( 0UL )
/* 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
equivalent in ticks using the portTICK_PERIOD_MS constant. */
* have been reported by any of the standard demo tasks. ms are converted to the
* equivalent in ticks using the portTICK_PERIOD_MS constant. */
#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
reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */
* reported in one of the standard demo tasks. ms are converted to the equivalent
* in ticks using the portTICK_PERIOD_MS constant. */
#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
* these files necessitates that they are written in an assembly file.
*/
static void prvRegTest1Task( void *pvParameters ) __attribute__((naked));
static void prvRegTest2Task( void *pvParameters ) __attribute__((naked));
static void prvRegTest1Task( void * pvParameters ) __attribute__( ( naked ) );
static void prvRegTest2Task( void * pvParameters ) __attribute__( ( naked ) );
/*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */
* register check tasks to the check software timer. If the variables keep
* incrementing, then the register check tasks have not discovered any errors. If
* a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/
void main_full( void )
{
TimerHandle_t xCheckTimer = NULL;
TimerHandle_t xCheckTimer = NULL;
/* 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
kernel port. */
* functionality, but do demonstrate how to use the FreeRTOS API and test the
* kernel port. */
vStartDynamicPriorityTasks();
vCreateBlockTimeTasks();
vStartCountingSemaphoreTasks();
@ -143,12 +143,12 @@ TimerHandle_t xCheckTimer = NULL;
vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* 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( prvRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* 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. */
( 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. */
@ -165,22 +165,24 @@ TimerHandle_t xCheckTimer = NULL;
vTaskStartScheduler();
/* 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
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
for more details. */
for( ;; );
* 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
* to be created. See the memory management section on the FreeRTOS web site
* for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
/* 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 )
{
@ -192,17 +194,17 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound = pdTRUE;
}
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
@ -217,6 +219,7 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound = pdTRUE;
}
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */
@ -224,17 +227,18 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound = pdTRUE;
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */
* the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
* everything is ok. A faster toggle indicates an error. */
configTOGGLE_LED();
/* Have any errors been latch in ulErrorFound? If so, shorten the
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
toggles. */
* 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
* toggles. */
if( ulErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == pdFALSE )
@ -242,8 +246,8 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must
*never* attempt to block. */
* Functions called from inside of a timer callback function must
* never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
@ -251,7 +255,7 @@ unsigned long ulErrorFound = pdFALSE;
/*-----------------------------------------------------------*/
/* This is a naked function. */
static void prvRegTest1Task( void *pvParameters )
static void prvRegTest1Task( void * pvParameters )
{
__asm volatile
(
@ -435,7 +439,7 @@ static void prvRegTest1Task( void *pvParameters )
/*-----------------------------------------------------------*/
/* This is a naked function. */
static void prvRegTest2Task( void *pvParameters )
static void prvRegTest2Task( void * pvParameters )
{
__asm volatile
(
@ -609,8 +613,8 @@ static void prvRegTest2Task( void *pvParameters )
" \n"
" /* Yield to increase test coverage. */ \n"
" movs r0, #0x01 \n"
" ldr r1, =0xe000ed04 \n" /*NVIC_INT_CTRL */
" lsl r0, #28 \n" /* Shift to PendSV bit */
" ldr r1, =0xe000ed04 \n"/*NVIC_INT_CTRL */
" lsl r0, #28 \n"/* Shift to PendSV bit */
" str r0, [r1] \n"
" dsb \n"
" pop { r0-r1 } \n"

View file

@ -59,7 +59,7 @@
#include "QueueOverwrite.h"
/* 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
/*-----------------------------------------------------------*/
@ -84,7 +84,7 @@ int main( void )
prvSetupHardware();
/* 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
{
main_blinky();
@ -111,59 +111,66 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
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.
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
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
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
* 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.
* 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
* 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
* FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* 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
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
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
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. */
* 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
* to block in any way (for example, call xQueueReceive() with a block time
* specified, or call vTaskDelay()). If the application makes use of the
* vTaskDelete() API function (as this demo application does) then it is also
* important that vApplicationIdleHook() is permitted to return to its calling
* 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. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
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
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
* 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
* code must not attempt to block, and only the interrupt safe FreeRTOS API
* functions can be used (those that end in FromISR()). */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{
/* 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();
/* Test the ISR safe queue overwrite functions. */
@ -175,27 +182,27 @@ void vApplicationTickHook( void )
#ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void)
{
long lHigherPriorityTaskWoken = pdFALSE;
void Dummy_IRQHandler( void )
{
long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. */
* task with an interrupt. A semaphore is used for this purpose. Note
* lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* 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
higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
* 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
* interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
* internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
* portEND_SWITCHING_ISR() macro will result in a context switch being pended to
* ensure this interrupt returns directly to the unblocked, higher priority,
* task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
}
#endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -74,16 +74,16 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter
functionality. */
* functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
@ -92,8 +92,8 @@ functionality. */
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*
* Called by main() to create the simply blinky style application if
@ -116,7 +116,7 @@ void main_blinky( void )
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
* file. */
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. */
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
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 tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */
for( ;; );
* 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 tasks to be created. See the memory management section on the
* FreeRTOS web site for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */
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. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* 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
to ms. While in the Blocked state this task will not consume any CPU
time. */
* 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
* time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
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. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
configTOGGLE_LED();
@ -191,4 +193,3 @@ unsigned long ulReceivedValue;
}
}
/*-----------------------------------------------------------*/

View file

@ -95,13 +95,13 @@
#define mainDONT_BLOCK ( 0UL )
/* 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
equivalent in ticks using the portTICK_PERIOD_MS constant. */
* have been reported by any of the standard demo tasks. ms are converted to the
* equivalent in ticks using the portTICK_PERIOD_MS constant. */
#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
reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */
* reported in one of the standard demo tasks. ms are converted to the equivalent
* in ticks using the portTICK_PERIOD_MS constant. */
#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
* these files necessitates that they are written in an assembly file.
*/
extern void vRegTest1Task( void *pvParameters );
extern void vRegTest2Task( void *pvParameters );
extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void * pvParameters );
/*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */
* register check tasks to the check software timer. If the variables keep
* incrementing, then the register check tasks have not discovered any errors. If
* a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/
void main_full( void )
{
TimerHandle_t xCheckTimer = NULL;
TimerHandle_t xCheckTimer = NULL;
/* 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
kernel port. */
* functionality, but do demonstrate how to use the FreeRTOS API and test the
* kernel port. */
vStartQueueSetTasks();
vStartQueueOverwriteTask( tskIDLE_PRIORITY );
vStartDynamicPriorityTasks();
@ -145,12 +145,12 @@ TimerHandle_t xCheckTimer = NULL;
vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* 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( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* 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. */
( 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. */
@ -167,22 +167,24 @@ TimerHandle_t xCheckTimer = NULL;
vTaskStartScheduler();
/* 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
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
for more details. */
for( ;; );
* 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
* to be created. See the memory management section on the FreeRTOS web site
* for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
/* 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 )
{
@ -194,17 +196,17 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound = pdTRUE;
}
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
@ -224,6 +226,7 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound = pdTRUE;
}
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */
@ -231,17 +234,18 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound = pdTRUE;
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */
* the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
* everything is ok. A faster toggle indicates an error. */
configTOGGLE_LED();
/* Have any errors been latch in ulErrorFound? If so, shorten the
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
toggles. */
* 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
* toggles. */
if( ulErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == pdFALSE )
@ -249,11 +253,10 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must
*never* attempt to block. */
* Functions called from inside of a timer callback function must
* never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
}
/*-----------------------------------------------------------*/

View file

@ -55,7 +55,7 @@
#include "task.h"
/* 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
/*-----------------------------------------------------------*/
@ -80,7 +80,7 @@ int main( void )
prvSetupHardware();
/* 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
{
main_blinky();
@ -107,80 +107,87 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
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.
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
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
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
* 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.
* 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
* 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
* FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* 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
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
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
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. */
* 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
* to block in any way (for example, call xQueueReceive() with a block time
* specified, or call vTaskDelay()). If the application makes use of the
* vTaskDelete() API function (as this demo application does) then it is also
* important that vApplicationIdleHook() is permitted to return to its calling
* 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. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
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
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
* 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
* code must not attempt to block, and only the interrupt safe FreeRTOS API
* functions can be used (those that end in FromISR()). */
}
/*-----------------------------------------------------------*/
#ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void)
{
long lHigherPriorityTaskWoken = pdFALSE;
void Dummy_IRQHandler( void )
{
long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. */
* task with an interrupt. A semaphore is used for this purpose. Note
* lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* 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
higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
* 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
* interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
* internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
* portEND_SWITCHING_ISR() macro will result in a context switch being pended to
* ensure this interrupt returns directly to the unblocked, higher priority,
* task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
}
#endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -74,16 +74,16 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter
functionality. */
* functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
@ -92,8 +92,8 @@ functionality. */
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*
* Called by main() to create the simply blinky style application if
@ -116,7 +116,7 @@ void main_blinky( void )
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
* file. */
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. */
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
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 tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */
for( ;; );
* 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 tasks to be created. See the memory management section on the
* FreeRTOS web site for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */
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. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* 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
to ms. While in the Blocked state this task will not consume any CPU
time. */
* 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
* time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
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. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
configTOGGLE_LED();
@ -191,4 +193,3 @@ unsigned long ulReceivedValue;
}
}
/*-----------------------------------------------------------*/

View file

@ -93,13 +93,13 @@
#define mainDONT_BLOCK ( 0UL )
/* 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
equivalent in ticks using the portTICK_PERIOD_MS constant. */
* have been reported by any of the standard demo tasks. ms are converted to the
* equivalent in ticks using the portTICK_PERIOD_MS constant. */
#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
reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */
* reported in one of the standard demo tasks. ms are converted to the equivalent
* in ticks using the portTICK_PERIOD_MS constant. */
#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
* these files necessitates that they are written in an assembly file.
*/
extern void vRegTest1Task( void *pvParameters );
extern void vRegTest2Task( void *pvParameters );
extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void * pvParameters );
/*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */
* register check tasks to the check software timer. If the variables keep
* incrementing, then the register check tasks have not discovered any errors. If
* a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/
void main_full( void )
{
TimerHandle_t xCheckTimer = NULL;
TimerHandle_t xCheckTimer = NULL;
/* 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
kernel port. */
* functionality, but do demonstrate how to use the FreeRTOS API and test the
* kernel port. */
vStartDynamicPriorityTasks();
vCreateBlockTimeTasks();
vStartCountingSemaphoreTasks();
@ -143,12 +143,12 @@ TimerHandle_t xCheckTimer = NULL;
vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* 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( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* 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. */
( 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. */
@ -165,22 +165,24 @@ TimerHandle_t xCheckTimer = NULL;
vTaskStartScheduler();
/* 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
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
for more details. */
for( ;; );
* 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
* to be created. See the memory management section on the FreeRTOS web site
* for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
/* 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 )
{
@ -192,17 +194,17 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound = pdTRUE;
}
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
@ -217,6 +219,7 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound = pdTRUE;
}
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */
@ -224,17 +227,18 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound = pdTRUE;
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */
* the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
* everything is ok. A faster toggle indicates an error. */
configTOGGLE_LED();
/* Have any errors been latch in ulErrorFound? If so, shorten the
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
toggles. */
* 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
* toggles. */
if( ulErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == pdFALSE )
@ -242,11 +246,10 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must
*never* attempt to block. */
* Functions called from inside of a timer callback function must
* never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
}
/*-----------------------------------------------------------*/

View file

@ -68,7 +68,7 @@
#include "QueueOverwrite.h"
/* 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
/*-----------------------------------------------------------*/
@ -93,7 +93,7 @@ int main( void )
prvSetupHardware();
/* 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
{
main_blinky();
@ -120,49 +120,52 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
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.
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
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
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
* 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.
* 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
* 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
* FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; )
for( ; ; )
{
__asm volatile( "NOP" );
};
__asm volatile ( "NOP" );
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* 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
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
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
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. */
* 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
* to block in any way (for example, call xQueueReceive() with a block time
* specified, or call vTaskDelay()). If the application makes use of the
* vTaskDelete() API function (as this demo application does) then it is also
* important that vApplicationIdleHook() is permitted to return to its calling
* 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. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; )
for( ; ; )
{
__asm volatile( "NOP" );
__asm volatile ( "NOP" );
}
}
/*-----------------------------------------------------------*/
@ -170,15 +173,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
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
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
* 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
* code must not attempt to block, and only the interrupt safe FreeRTOS API
* functions can be used (those that end in FromISR()). */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{
/* 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();
/* Test the ISR safe queue overwrite functions. */
@ -190,27 +193,27 @@ void vApplicationTickHook( void )
#ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void)
{
long lHigherPriorityTaskWoken = pdFALSE;
void Dummy_IRQHandler( void )
{
long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. */
* task with an interrupt. A semaphore is used for this purpose. Note
* lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* 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
higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
* 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
* interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
* internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
* portEND_SWITCHING_ISR() macro will result in a context switch being pended to
* ensure this interrupt returns directly to the unblocked, higher priority,
* task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
}
#endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -74,16 +74,16 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter
functionality. */
* functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
@ -92,8 +92,8 @@ functionality. */
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*
* Called by main() to create the simply blinky style application if
@ -116,7 +116,7 @@ void main_blinky( void )
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
* file. */
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. */
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
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 tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */
for( ;; )
* 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 tasks to be created. See the memory management section on the
* FreeRTOS web site for more details. */
for( ; ; )
{
__asm volatile( "NOP" );
__asm volatile ( "NOP" );
}
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */
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. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* 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
to ms. While in the Blocked state this task will not consume any CPU
time. */
* 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
* time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
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. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
configTOGGLE_LED();
@ -194,4 +194,3 @@ unsigned long ulReceivedValue;
}
}
/*-----------------------------------------------------------*/

View file

@ -95,13 +95,13 @@
#define mainDONT_BLOCK ( 0UL )
/* 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
equivalent in ticks using the portTICK_PERIOD_MS constant. */
* have been reported by any of the standard demo tasks. ms are converted to the
* equivalent in ticks using the portTICK_PERIOD_MS constant. */
#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
reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */
* reported in one of the standard demo tasks. ms are converted to the equivalent
* in ticks using the portTICK_PERIOD_MS constant. */
#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
* these files necessitates that they are written in an assembly file.
*/
static void vRegTest1Task( void *pvParameters );
static void vRegTest2Task( void *pvParameters );
static void vRegTest1Task( void * pvParameters );
static void vRegTest2Task( void * pvParameters );
/*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */
* register check tasks to the check software timer. If the variables keep
* incrementing, then the register check tasks have not discovered any errors. If
* a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/
void main_full( void )
{
TimerHandle_t xCheckTimer = NULL;
TimerHandle_t xCheckTimer = NULL;
/* 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
kernel port. */
* functionality, but do demonstrate how to use the FreeRTOS API and test the
* kernel port. */
vStartQueueSetTasks();
vStartQueueOverwriteTask( tskIDLE_PRIORITY );
vStartDynamicPriorityTasks();
@ -145,12 +145,12 @@ TimerHandle_t xCheckTimer = NULL;
vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* 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( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* 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. */
( 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. */
@ -167,25 +167,25 @@ TimerHandle_t xCheckTimer = NULL;
vTaskStartScheduler();
/* 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
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
for more details. */
for( ;; )
* 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
* to be created. See the memory management section on the FreeRTOS web site
* for more details. */
for( ; ; )
{
__asm volatile( "NOP" );
__asm volatile ( "NOP" );
}
}
/*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
/* 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 )
{
@ -197,17 +197,17 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound = pdTRUE;
}
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
@ -227,6 +227,7 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound = pdTRUE;
}
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */
@ -234,17 +235,18 @@ unsigned long ulErrorFound = pdFALSE;
{
ulErrorFound = pdTRUE;
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */
* the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
* everything is ok. A faster toggle indicates an error. */
configTOGGLE_LED();
/* Have any errors been latch in ulErrorFound? If so, shorten the
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
toggles. */
* 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
* toggles. */
if( ulErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == pdFALSE )
@ -252,8 +254,8 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must
*never* attempt to block. */
* Functions called from inside of a timer callback function must
* never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
@ -261,11 +263,11 @@ unsigned long ulErrorFound = pdFALSE;
/*-----------------------------------------------------------*/
/* This is a naked function. */
static void vRegTest1Task( void *pvParameters )
static void vRegTest1Task( void * pvParameters )
{
__asm volatile
(
" \n" /* Fill the core registers with known values. */
" \n"/* Fill the core registers with known values. */
" mov r0, #100 \n"
" mov r1, #101 \n"
" mov r2, #102 \n"
@ -280,7 +282,7 @@ static void vRegTest1Task( void *pvParameters )
" mov r11, #111 \n"
" mov r12, #112 \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 d2, r4, r5 \n"
" vmov d3, r6, r7 \n"
@ -297,8 +299,8 @@ static void vRegTest1Task( void *pvParameters )
" vmov d14, r4, r5 \n"
" vmov d15, r6, r7 \n"
" \n"
"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. */
"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. */
" \n"
" vmov r0, r1, d0 \n"
" cmp r0, #100 \n"
@ -381,12 +383,12 @@ static void vRegTest1Task( void *pvParameters )
" cmp r1, #107 \n"
" bne reg1_error_loopf \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"
" 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"
"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"
"reg1_loopf_pass: \n"
" \n"
@ -417,28 +419,28 @@ static void vRegTest1Task( void *pvParameters )
" cmp r12, #112 \n"
" bne reg1_error_loop \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 r1, [r0] \n"
" adds r1, r1, #1 \n"
" str r1, [r0] \n"
" pop { r0-r1 } \n"
" \n"
" b reg1_loop \n" /* Start again. */
" b reg1_loop \n"/* Start again. */
" \n"
"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. */
"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. */
" nop "
);
}
/*-----------------------------------------------------------*/
/* This is a naked function. */
static void vRegTest2Task( void *pvParameters )
static void vRegTest2Task( void * pvParameters )
{
__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 r2, #2 \n"
" mov r3, #3 \n"
@ -452,7 +454,7 @@ static void vRegTest2Task( void *pvParameters )
" mov r11, #11 \n"
" mov r12, #12 \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 d2, r4, r5 \n"
" vmov d3, r6, r7 \n"
@ -471,8 +473,8 @@ static void vRegTest2Task( void *pvParameters )
" \n"
"reg2_loop: \n"
" \n"
" 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. */
" 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. */
" cmp r0, #-1 \n"
" bne reg2_error_loopf \n"
" cmp r1, #1 \n"
@ -553,12 +555,12 @@ static void vRegTest2Task( void *pvParameters )
" cmp r1, #7 \n"
" bne reg2_error_loopf \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"
" 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"
"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"
"reg2_loopf_pass: \n"
" \n"
@ -589,26 +591,23 @@ static void vRegTest2Task( void *pvParameters )
" cmp r12, #12 \n"
" bne reg2_error_loop \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 r1, [r0] \n"
" adds r1, r1, #1 \n"
" str r1, [r0] \n"
" \n"
" movs r0, #0x01 \n" /* Yield to increase test coverage. */
" ldr r1, =0xe000ed04 \n" /*NVIC_INT_CTRL */
" lsl r0, r0, #28 \n" /* Shift to PendSV bit */
" movs r0, #0x01 \n"/* Yield to increase test coverage. */
" ldr r1, =0xe000ed04 \n"/*NVIC_INT_CTRL */
" lsl r0, r0, #28 \n"/* Shift to PendSV bit */
" str r0, [r1] \n"
" dsb \n"
" pop { r0-r1 } \n"
" \n"
" b reg2_loop \n" /* Start again. */
" b reg2_loop \n"/* Start again. */
" \n"
"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. */
"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. */
" nop \n"
);
}

View file

@ -57,8 +57,8 @@
/*-----------------------------------------------------------*/
/* 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
formatter project option to "small". */
* error then set the printf formatter project option to "tiny" and the scanf
* formatter project option to "small". */
/*
* Set up the hardware ready to run this demo.
@ -82,8 +82,8 @@ int main( void )
prvSetupHardware();
/* The configCREATE_SIMPLE_TICKLESS_DEMO setting is described at the top
of this file. */
#if( configCREATE_SIMPLE_TICKLESS_DEMO == 1 )
* of this file. */
#if ( configCREATE_SIMPLE_TICKLESS_DEMO == 1 )
{
main_blinky();
}
@ -99,11 +99,11 @@ int main( 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
main_blinky() as the full demo uses a fast clock and the blinky demo uses
a slow clock. */
* main_blinky() as the full demo uses a fast clock and the blinky demo uses
* a slow clock. */
/* Stop the watchdog timer. */
MAP_WDT_A_holdTimer();
@ -121,54 +121,62 @@ extern void FPU_enableModule( void );
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
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.
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
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
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
* 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.
* 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
* 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
* FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* 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
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
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
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. */
* 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
* to block in any way (for example, call xQueueReceive() with a block time
* specified, or call vTaskDelay()). If the application makes use of the
* vTaskDelete() API function (as this demo application does) then it is also
* important that vApplicationIdleHook() is permitted to return to its calling
* 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. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
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
malloc. */
* malloc. */
Interrupt_disableMaster();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/

View file

@ -143,20 +143,20 @@
#define mainDONT_BLOCK ( 0UL )
/* 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
equivalent in ticks using the portTICK_PERIOD_MS constant. */
* have been reported by any of the standard demo tasks. ms are converted to the
* equivalent in ticks using the portTICK_PERIOD_MS constant. */
#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
reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */
* reported in one of the standard demo tasks. ms are converted to the equivalent
* in ticks using the portTICK_PERIOD_MS constant. */
#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 0 to create a much more
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
information. */
* 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
* the documentation page on the http://www.FreeRTOS.org web site for more
* information. */
#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
* these files necessitates that they are written in an assembly file.
*/
extern void vRegTest1Task( void *pvParameters );
extern void vRegTest2Task( void *pvParameters );
extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void * pvParameters );
extern void vRegTestClearFlopRegistersToParameterValue( 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
* 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
@ -208,65 +208,67 @@ static void prvOptionallyCreateComprehensveTestApplication( void );
/*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */
* register check tasks to the check software timer. If the variables keep
* incrementing, then the register check tasks have not discovered any errors. If
* a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/* The following variables are used to verify that the interrupt nesting depth
is as intended. ulFPUInterruptNesting is incremented on entry to an interrupt
that uses the FPU, and decremented on exit of the same interrupt.
ulMaxFPUInterruptNesting latches the highest value reached by
ulFPUInterruptNesting. These variables have no other purpose. */
* is as intended. ulFPUInterruptNesting is incremented on entry to an interrupt
* that uses the FPU, and decremented on exit of the same interrupt.
* ulMaxFPUInterruptNesting latches the highest value reached by
* ulFPUInterruptNesting. These variables have no other purpose. */
volatile unsigned long ulFPUInterruptNesting = 0UL, ulMaxFPUInterruptNesting = 0UL;
/* The semaphore used to demonstrate a task being synchronised with an
interrupt. */
* interrupt. */
static SemaphoreHandle_t xTestSemaphore = NULL;
/* The variable that is incremented by the task synchronised with the button
interrupt. */
* interrupt. */
volatile unsigned long ulButtonPressCounts = 0UL;
/*-----------------------------------------------------------*/
int main(void)
int main( void )
{
/* Configure the hardware ready to run the test. */
prvSetupHardware();
/* 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
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
more information. */
* 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
* 0 (at the top of this file). See the comments at the top of this file for
* more information. */
vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );
/* 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
file). See the comments at the top of this file for more information. */
* 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. */
prvOptionallyCreateComprehensveTestApplication();
/* Start the scheduler. */
vTaskStartScheduler();
/* 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
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
for more details. */
for( ;; );
* 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
* to be created. See the memory management section on the FreeRTOS web site
* for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
long lErrorFound = pdFALSE;
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
long lErrorFound = pdFALSE;
/* 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 )
{
@ -288,17 +290,17 @@ long lErrorFound = pdFALSE;
lErrorFound = pdTRUE;
}
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
lErrorFound = pdTRUE;
}
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
lErrorFound = pdTRUE;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
lErrorFound = pdTRUE;
}
@ -323,6 +325,7 @@ long lErrorFound = pdFALSE;
{
lErrorFound = pdTRUE;
}
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */
@ -330,17 +333,18 @@ long lErrorFound = pdFALSE;
{
lErrorFound = pdTRUE;
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */
* the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
* everything is ok. A faster toggle indicates an error. */
vParTestToggleLED( mainCHECK_LED );
/* Have any errors been latch in lErrorFound? If so, shorten the
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
toggles. */
* 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
* toggles. */
if( lErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == pdFALSE )
@ -348,28 +352,28 @@ long lErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must
*never* attempt to block. */
* Functions called from inside of a timer callback function must
* never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
}
/*-----------------------------------------------------------*/
static void prvButtonTestTask( void *pvParameters )
static void prvButtonTestTask( void * pvParameters )
{
configASSERT( xTestSemaphore );
/* 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
will unblock, increment its execution counter, then return to block
again. */
* an interrupt. Each time the button interrupt gives the semaphore, this task
* will unblock, increment its execution counter, then return to block
* again. */
/* Take the semaphore before started to ensure it is in the correct
state. */
* state. */
xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );
for( ;; )
for( ; ; )
{
xSemaphoreTake( xTestSemaphore, portMAX_DELAY );
ulButtonPressCounts++;
@ -389,8 +393,8 @@ static void prvSetupHardware( void )
vParTestInitialise();
/* 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
from the button interrupt handler. */
* lowest interrupt priority, so it is ok to use the ISR safe FreeRTOS API
* from the button interrupt handler. */
STM_EVAL_PBInit( BUTTON_USER, BUTTON_MODE_EXTI );
}
/*-----------------------------------------------------------*/
@ -400,37 +404,37 @@ void vApplicationTickHook( void )
#if ( mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY == 0 )
{
/* 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++;
/* Fill the FPU registers with 0. */
vRegTestClearFlopRegistersToParameterValue( 0UL );
/* Trigger a timer 2 interrupt, which will fill the registers with a
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
just used for convenience. */
* 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
* just used for convenience. */
NVIC_SetPendingIRQ( TIM2_IRQn );
/* Ensure that, after returning from the nested interrupts, all the FPU
registers contain the value to which they were set by the tick hook
function. */
* registers contain the value to which they were set by the tick hook
* function. */
configASSERT( ulRegTestCheckFlopRegistersContainParameterValue( 0UL ) );
ulFPUInterruptNesting--;
}
#endif
#endif /* if ( mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY == 0 ) */
}
/*-----------------------------------------------------------*/
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,
just its interrupt vector to force nesting from software. TIM2 must have
a lower priority than TIM3, and both must have priorities above
configMAX_SYSCALL_INTERRUPT_PRIORITY. */
* just its interrupt vector to force nesting from software. TIM2 must have
* a lower priority than TIM3, and both must have priorities above
* configMAX_SYSCALL_INTERRUPT_PRIORITY. */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY - 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
@ -438,9 +442,9 @@ NVIC_InitTypeDef NVIC_InitStructure;
NVIC_Init( &NVIC_InitStructure );
/* 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
a lower priority than TIM3, and both must have priorities above
configMAX_SYSCALL_INTERRUPT_PRIORITY. */
* just its interrupt vector to force nesting from software. TIM2 must have
* a lower priority than TIM3, and both must have priorities above
* configMAX_SYSCALL_INTERRUPT_PRIORITY. */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY - 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
@ -452,20 +456,20 @@ NVIC_InitTypeDef NVIC_InitStructure;
void TIM3_IRQHandler( void )
{
/* 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++;
/* This is the highest priority interrupt in the chain of forced nesting
interrupts, so latch the maximum value reached by ulFPUInterruptNesting.
This is done purely to allow verification that the nesting depth reaches
that intended. */
* interrupts, so latch the maximum value reached by ulFPUInterruptNesting.
* This is done purely to allow verification that the nesting depth reaches
* that intended. */
if( ulFPUInterruptNesting > ulMaxFPUInterruptNesting )
{
ulMaxFPUInterruptNesting = ulFPUInterruptNesting;
}
/* Fill the FPU registers with 99 to overwrite the values written by
TIM2_IRQHandler(). */
* TIM2_IRQHandler(). */
vRegTestClearFlopRegistersToParameterValue( 99UL );
ulFPUInterruptNesting--;
@ -475,19 +479,19 @@ void TIM3_IRQHandler( void )
void TIM2_IRQHandler( void )
{
/* 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++;
/* Fill the FPU registers with 1. */
vRegTestClearFlopRegistersToParameterValue( 1UL );
/* Trigger a timer 3 interrupt, which will fill the registers with a
different value. */
* different value. */
NVIC_SetPendingIRQ( TIM3_IRQn );
/* Ensure that, after returning from the nesting interrupt, all the FPU
registers contain the value to which they were set by this interrupt
function. */
* registers contain the value to which they were set by this interrupt
* function. */
configASSERT( ulRegTestCheckFlopRegistersContainParameterValue( 1UL ) );
ulFPUInterruptNesting--;
@ -501,7 +505,7 @@ static void prvOptionallyCreateComprehensveTestApplication( void )
TimerHandle_t xCheckTimer = NULL;
/* Configure the interrupts used to test FPU registers being used from
nested interrupts. */
* nested interrupts. */
prvSetupNestedFPUInterruptsTest();
/* Start all the other standard demo/test tasks. */
@ -519,19 +523,19 @@ static void prvOptionallyCreateComprehensveTestApplication( void )
vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* 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( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the semaphore that is used to demonstrate a task being
synchronised with an interrupt. */
* synchronised with an interrupt. */
vSemaphoreCreateBinary( xTestSemaphore );
/* Create the task that is unblocked by the demonstration interrupt. */
xTaskCreate( prvButtonTestTask, "BtnTest", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* 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. */
( 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. */
@ -545,13 +549,13 @@ static void prvOptionallyCreateComprehensveTestApplication( void )
}
/* 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 );
}
#else /* mainCREATE_SIMPLE_LED_FLASHER_DEMO_ONLY */
{
/* 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 ) vRegTest2Task;
( 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
the interrupt. */
* the interrupt. */
EXTI_ClearITPendingBit( EXTI_Line6 );
/* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. First the handler releases a semaphore.
lHigherPriorityTaskWoken has been initialised to zero. */
* task with an interrupt. First the handler releases a semaphore.
* lHigherPriorityTaskWoken has been initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* 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
higher than the currently executing task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE.
Passing pdTRUE into the following macro call will cause this interrupt to
return directly to the unblocked, higher priority, task. */
* semaphore caused the task to unblock, and the unblocked task has a priority
* higher than the currently executing task (the task that this interrupt
* interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE.
* Passing pdTRUE into the following macro call will cause this interrupt to
* return directly to the unblocked, higher priority, task. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/
@ -587,43 +591,50 @@ long lHigherPriorityTaskWoken = pdFALSE;
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
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.
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
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
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
* 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.
* 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
* 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
* FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* 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
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
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
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. */
* 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
* to block in any way (for example, call xQueueReceive() with a block time
* specified, or call vTaskDelay()). If the application makes use of the
* vTaskDelete() API function (as this demo application does) then it is also
* important that vApplicationIdleHook() is permitted to return to its calling
* 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. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/

View file

@ -75,15 +75,15 @@ extern void main_full( void );
int main( void )
{
/* See http://www.FreeRTOS.org/TI_CC3220_SimpleLink_FreeRTOS_Demo.html for
instructions. */
* instructions. */
/* Prepare the hardware to run this demo. */
prvSetupHardware();
/* The configCREATE_SIMPLE_TICKLESS_DEMO setting is described at the top
of this file. */
#if( configCREATE_SIMPLE_TICKLESS_DEMO == 1 )
* of this file. */
#if ( configCREATE_SIMPLE_TICKLESS_DEMO == 1 )
{
main_blinky();
}
@ -108,7 +108,7 @@ static void prvSetupHardware( void )
void vMainToggleLED( void )
{
static uint32_t ulLEDState = Board_GPIO_LED_OFF;
static uint32_t ulLEDState = Board_GPIO_LED_OFF;
ulLEDState = !ulLEDState;
GPIO_write( Board_LED0, ulLEDState );
@ -118,118 +118,134 @@ static uint32_t ulLEDState = Board_GPIO_LED_OFF;
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
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.
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
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
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
* 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.
* 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
* 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
* FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* 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
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
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
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. */
* 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
* to block in any way (for example, call xQueueReceive() with a block time
* specified, or call vTaskDelay()). If the application makes use of the
* vTaskDelete() API function (as this demo application does) then it is also
* important that vApplicationIdleHook() is permitted to return to its calling
* 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. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
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
malloc. */
* malloc. */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
* used by the Idle task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* 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;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
* application must provide an implementation of vApplicationGetTimerTaskMemory()
* to provide the memory that is used by the Timer service task. */
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
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* 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;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
/*-----------------------------------------------------------*/
/* 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();
while( xSetToNonZeroToStepOutOfLoop == 0 )
{
/* Use the variables to prevent compiler warnings and in an attempt to
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
view the variables they are copied to. */
* 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
* view the variables they are copied to. */
( void ) pcFileName;
( void ) ulLineNumber;
}
@ -237,11 +253,11 @@ volatile BaseType_t xSetToNonZeroToStepOutOfLoop = 0;
/*-----------------------------------------------------------*/
/* To enable the libraries to build. */
void PowerCC32XX_enterLPDS( void *driverlibFunc )
void PowerCC32XX_enterLPDS( void * driverlibFunc )
{
( void ) driverlibFunc;
/* This function is not implemented so trap any calls to it by halting
here. */
* here. */
configASSERT( driverlibFunc == NULL );
}

View file

@ -57,7 +57,7 @@
#include "board.h"
/* 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
/*-----------------------------------------------------------*/
@ -78,10 +78,11 @@ static void prvSetupHardware( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
* within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void );
/*-----------------------------------------------------------*/
@ -92,8 +93,8 @@ int main( void )
prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
* of this file. */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{
main_blinky();
}
@ -124,24 +125,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
@ -150,15 +152,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
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
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
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
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */
* 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
* 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
* configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
* RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -171,7 +173,7 @@ void vApplicationTickHook( void )
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{
/* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */
* prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests();
/* 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. */
xNotifyTaskFromISR();
}
#endif
#endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
}
/*-----------------------------------------------------------*/

View file

@ -57,7 +57,7 @@
#include "board.h"
/* 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
/*-----------------------------------------------------------*/
@ -78,10 +78,11 @@ static void prvSetupHardware( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
* within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void );
/*-----------------------------------------------------------*/
@ -92,8 +93,8 @@ int main( void )
prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
* of this file. */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{
main_blinky();
}
@ -124,24 +125,25 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
@ -150,15 +152,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
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
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
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
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */
* 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
* 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
* configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
* RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */
@ -171,7 +173,7 @@ void vApplicationTickHook( void )
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{
/* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */
* prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests();
/* 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. */
xNotifyTaskFromISR();
}
#endif
#endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
}
/*-----------------------------------------------------------*/

View file

@ -42,7 +42,7 @@
#include "semphr.h"
/* 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 "QueueOverwrite.h"
#include "EventGroupsDemo.h"
@ -51,7 +51,7 @@ defined in this file. */
#include "TaskNotify.h"
/* 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
/*-----------------------------------------------------------*/
@ -70,17 +70,18 @@ static void prvSystemClockConfig( void );
* 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.
*/
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
extern void main_blinky( void );
#else
extern void main_full( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
* within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void );
/*-----------------------------------------------------------*/
@ -91,8 +92,8 @@ int main( void )
prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
* of this file. */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{
main_blinky();
}
@ -108,10 +109,10 @@ int main( void )
static void prvSetupHardware( void )
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
/* Configure Flash prefetch and Instruction cache through ART accelerator. */
#if( ART_ACCLERATOR_ENABLE != 0 )
#if ( ART_ACCLERATOR_ENABLE != 0 )
{
__HAL_FLASH_ART_ENABLE();
}
@ -127,7 +128,7 @@ GPIO_InitTypeDef GPIO_InitStruct;
prvSystemClockConfig();
/* 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();
__HAL_RCC_GPIOF_CLK_ENABLE();
@ -145,20 +146,20 @@ GPIO_InitTypeDef GPIO_InitStruct;
static void prvSystemClockConfig( void )
{
/* The system Clock is configured as follow :
System Clock source = PLL (HSE)
SYSCLK(Hz) = 200000000
HCLK(Hz) = 200000000
AHB Prescaler = 1
APB1 Prescaler = 4
APB2 Prescaler = 2
HSE Frequency(Hz) = 25000000
PLL_M = 25
PLL_N = 400
PLL_P = 2
PLL_Q = 7
VDD(V) = 3.3
Main regulator output voltage = Scale1 mode
Flash Latency(WS) = 7 */
* System Clock source = PLL (HSE)
* SYSCLK(Hz) = 200000000
* HCLK(Hz) = 200000000
* AHB Prescaler = 1
* APB1 Prescaler = 4
* APB2 Prescaler = 2
* HSE Frequency(Hz) = 25000000
* PLL_M = 25
* PLL_N = 400
* PLL_P = 2
* PLL_Q = 7
* VDD(V) = 3.3
* Main regulator output voltage = Scale1 mode
* Flash Latency(WS) = 7 */
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
@ -172,40 +173,41 @@ static void prvSystemClockConfig( void )
RCC_OscInitStruct.PLL.PLLN = 400;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
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
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
* clocks dividers */
RCC_ClkInitStruct.ClockType = ( RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 );
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
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 )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
/* Force an assert. */
configASSERT( ( volatile void * ) NULL );
@ -214,15 +216,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
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
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
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
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */
* 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
* 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
* configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
* RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize();
/* 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 ) ulLine;
@ -240,7 +243,7 @@ volatile unsigned long ul = 0;
taskENTER_CRITICAL();
{
/* Set ul to a non-zero value using the debugger to step out of this
function. */
* function. */
while( ul == 0 )
{
__NOP();
@ -252,10 +255,10 @@ volatile unsigned long ul = 0;
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
prodding periodically from the tick interrupt. */
* prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */
@ -273,9 +276,6 @@ void vApplicationTickHook( void )
/* Use task notifications from an ISR. */
xNotifyTaskFromISR();
}
#endif
#endif /* if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) */
}
/*-----------------------------------------------------------*/

View file

@ -135,34 +135,34 @@
#include "dynamic.h"
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* 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
for this demo on the FreeRTOS.org web site to see which LED this relates to. */
* 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. */
#define mainCHECK_LED ( 1UL << 3UL )
/* 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
the FreeRTOS.org web site to see which LED this relates to. */
* 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. */
#define mainTASK_CONTROLLED_LED 0x07UL
/* 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
documentation page for this demo on the FreeRTOS.org web site to see which LED
this relates to. */
* 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
* this relates to. */
#define mainTIMER_CONTROLLED_LED 0x05UL
/* 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
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. */
* 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
* FreeRTOS.org web site to see which LEDs this relates to. */
#define mainCOM_TEST_LED 0x03UL
/* 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 )
/* 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
equivalent in ticks using the portTICK_PERIOD_MS constant. */
* have been reported by any of the standard demo tasks. ms are converted to the
* equivalent in ticks using the portTICK_PERIOD_MS constant. */
#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
reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */
* reported in one of the standard demo tasks. ms are converted to the equivalent
* in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_PERIOD_MS )
/* 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 )
/* 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 )
/* A zero block time. */
@ -218,8 +218,8 @@ static void prvSetupHardware( void );
* The application specific (not common demo) tasks as described in the comments
* at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*
* 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
* 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;
/* The LED software timer. This uses prvLEDTimerCallback() as it's callback
function. */
* function. */
static TimerHandle_t xLEDTimer = NULL;
/* 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;
/* The check timer. This uses prvCheckTimerCallback() as its callback
function. */
* function. */
static TimerHandle_t xCheckTimer = NULL;
/* 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
to make debugging easier. */
static const char *pcStatusMessage = NULL;
* be set to point to a string that identifies the offending task. This is just
* to make debugging easier. */
static const char * pcStatusMessage = NULL;
/*-----------------------------------------------------------*/
int main(void)
int main( void )
{
/* Configure the NVIC, LED outputs and button inputs. */
prvSetupHardware();
@ -277,22 +278,22 @@ int main(void)
if( xQueue != NULL )
{
/* 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( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* 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
this file. */
* if the button is not pushed within 5000ms, as described at the top of
* this file. */
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. */
( void * ) 0, /* The ID is not used, so can be set to anything. */
prvLEDTimerCallback /* The callback function that switches the LED off. */
);
/* 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. */
( 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. */
@ -301,7 +302,7 @@ int main(void)
);
/* 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. */
( 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. */
@ -310,8 +311,8 @@ int main(void)
);
/* Create a lot of 'standard demo' tasks. Over 40 tasks are created in
this demo. For a much simpler demo, select the 'blinky' build
configuration. */
* this demo. For a much simpler demo, select the 'blinky' build
* configuration. */
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
@ -326,9 +327,9 @@ int main(void)
vStartDynamicPriorityTasks();
/* 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
or not the correct/expected number of tasks are running at any given
time. */
* 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. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* 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
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
to be created. See the memory management section on the FreeRTOS web site
for more details. */
for( ;; );
* 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
* to be created. See the memory management section on the FreeRTOS web site
* for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
/* 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 )
{
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
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
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
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
only one timer can be running at any one time. */
* the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
* 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
* 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
* only one timer can be running at any one time. */
if( ( FM3_GPIO->PDOR3 & mainCHECK_LED ) != 0 )
{
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
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
toggles. */
* 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
* toggles. */
if( pcStatusMessage != NULL )
{
/* This call to xTimerChangePeriod() uses a zero block time. Functions
called from inside of a timer callback function must *never* attempt
to block. */
* called from inside of a timer callback function must *never* attempt
* to 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 )
{
/* 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 );
}
/*-----------------------------------------------------------*/
@ -449,14 +452,14 @@ static void prvLEDTimerCallback( TimerHandle_t xTimer )
static void prvDigitCounterTimerCallback( TimerHandle_t xTimer )
{
/* 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 long lCounter = 0L;
const long lNumberOfDigits = 10L;
unsigned short usCheckLEDState;
static const unsigned short usNumbersPatterns[] = { 0x8004, 0xF204, 0x4804, 0x6004, 0x3204, 0x2404, 0x0404, 0xF104, 0x0004, 0x2004 };
static long lCounter = 0L;
const long lNumberOfDigits = 10L;
unsigned short usCheckLEDState;
/* 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 port as only one timer can be executing at any one time. */
* 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. */
usCheckLEDState = ( FM3_GPIO->PDOR3 & mainCHECK_LED );
/* Display the next number, counting up. */
@ -476,78 +479,78 @@ unsigned short usCheckLEDState;
/* The ISR executed when the user button is pushed. */
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
LED timer. The LED timer will turn the LED off if the button is not
pushed within 5000ms. */
* LED timer. The LED timer will turn the LED off if the button is not
* pushed within 5000ms. */
vParTestSetLEDFromISR( mainTIMER_CONTROLLED_LED, pdTRUE );
/* This interrupt safe FreeRTOS function can be called from this interrupt
because the interrupt priority is below the
configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
* because the interrupt priority is below the
* configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken );
/* 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;
/* If calling xTimerResetFromISR() caused a task (in this case the timer
service/daemon task) to unblock, and the unblocked task has a priority
higher than or equal to the task that was interrupted, then
xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
* service/daemon task) to unblock, and the unblocked task has a priority
* higher than or equal to the task that was interrupted, then
* xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
* portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* 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,
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
service task will drain the command queue, and now the check and digit
counter timers can be started successfully. */
* 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
* 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
* counter timers can be started successfully. */
xTimerStart( xCheckTimer, portMAX_DELAY );
xTimerStart( xDigitCounterTimer, portMAX_DELAY );
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* 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
to ms. While in the Blocked state this task will not consume any CPU
time. */
* 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
* time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
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
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
vParTestToggleLED( mainTASK_CONTROLLED_LED );
@ -558,7 +561,7 @@ unsigned long ulReceivedValue;
static void prvSetupHardware( void )
{
const unsigned short usButtonInputBit = 0x01U;
const unsigned short usButtonInputBit = 0x01U;
SystemInit();
SystemCoreClockUpdate();
@ -591,42 +594,48 @@ const unsigned short usButtonInputBit = 0x01U;
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ;; );
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
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
does nothing useful, other than report the amount of FreeRTOS heap that
remains unallocated. */
* does nothing useful, other than report the amount of FreeRTOS heap that
* remains unallocated. */
xFreeStackSpace = xPortGetFreeHeapSize();
if( xFreeStackSpace > 100 )
{
/* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */
* if there is a lot of heap remaining unallocated then
* the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
* reduced accordingly. */
}
}
/*-----------------------------------------------------------*/
@ -634,8 +643,7 @@ volatile size_t xFreeStackSpace;
void vApplicationTickHook( void )
{
/* 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();
}
/*-----------------------------------------------------------*/

View file

@ -88,12 +88,12 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* 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.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*
* 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;
/* The LED software timer. This uses vLEDTimerCallback() as its callback
function. */
* function. */
static TimerHandle_t xLEDTimer = NULL;
/*-----------------------------------------------------------*/
int main(void)
int main( void )
{
/* Configure the NVIC, LED outputs and button inputs. */
prvSetupHardware();
@ -143,13 +143,13 @@ int main(void)
if( xQueue != NULL )
{
/* 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( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* 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
this file. */
* if the button is not pushed within 5000ms, as described at the top of
* this file. */
xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */
( 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. */
@ -162,21 +162,23 @@ int main(void)
}
/* 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
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
for more details. */
for( ;; );
* 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
* to be created. See the memory management section on the FreeRTOS web site
* for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void vLEDTimerCallback( TimerHandle_t xTimer )
{
/* 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
a critical section because it is accessed from multiple tasks, and the
button interrupt - in this trivial case, for simplicity, the critical
section is omitted. */
* 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
* button interrupt - in this trivial case, for simplicity, the critical
* section is omitted. */
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. */
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
LED timer. The LED timer will turn the LED off if the button is not
pushed within 5000ms. */
* LED timer. The LED timer will turn the LED off if the button is not
* pushed within 5000ms. */
FM3_GPIO->PDOR3 &= ~mainTIMER_CONTROLLED_LED;
/* This interrupt safe FreeRTOS function can be called from this interrupt
because the interrupt priority is below the
configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
* because the interrupt priority is below the
* configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken );
/* 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;
/* If calling xTimerResetFromISR() caused a task (in this case the timer
service/daemon task) to unblock, and the unblocked task has a priority
higher than or equal to the task that was interrupted, then
xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
* service/daemon task) to unblock, and the unblocked task has a priority
* higher than or equal to the task that was interrupted, then
* xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
* portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* 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
to ms. While in the Blocked state this task will not consume any CPU
time. */
* 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
* time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
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
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
/* NOTE - accessing the LED port should use a critical section
because it is accessed from multiple tasks, and the button interrupt
- in this trivial case, for simplicity, the critical section is
omitted. */
* because it is accessed from multiple tasks, and the button interrupt
* - in this trivial case, for simplicity, the critical section is
* omitted. */
if( ( FM3_GPIO->PDOR3 & mainTASK_CONTROLLED_LED ) != 0 )
{
FM3_GPIO->PDOR3 &= ~mainTASK_CONTROLLED_LED;
@ -268,7 +270,7 @@ unsigned long ulReceivedValue;
static void prvSetupHardware( void )
{
const unsigned short usButtonInputBit = 0x01U;
const unsigned short usButtonInputBit = 0x01U;
SystemInit();
SystemCoreClockUpdate();
@ -313,54 +315,55 @@ const unsigned short usButtonInputBit = 0x01U;
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ;; );
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
for( ;; );
* configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* A tick hook is used by the "Full" build configuration. The Full and
blinky build configurations share a FreeRTOSConfig.h header file, so this
simple build configuration also has to define a tick hook - even though it
does not actually use it for anything. */
* blinky build configurations share a FreeRTOSConfig.h header file, so this
* simple build configuration also has to define a tick hook - even though it
* does not actually use it for anything. */
}
/*-----------------------------------------------------------*/
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
does nothing useful, other than report the amount of FreeRTOS heap that
remains unallocated. */
* does nothing useful, other than report the amount of FreeRTOS heap that
* remains unallocated. */
xFreeHeapSpace = xPortGetFreeHeapSize();
if( xFreeHeapSpace > 100 )
{
/* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */
* if there is a lot of heap remaining unallocated then
* the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
* reduced accordingly. */
}
}
/*-----------------------------------------------------------*/

View file

@ -136,34 +136,34 @@
#include "dynamic.h"
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* 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
for this demo on the FreeRTOS.org web site to see which LED this relates to. */
* 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. */
#define mainCHECK_LED 0x07UL
/* 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
the FreeRTOS.org web site to see which LED this relates to. */
* 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. */
#define mainTASK_CONTROLLED_LED 0x06UL
/* 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
documentation page for this demo on the FreeRTOS.org web site to see which LED
this relates to. */
* 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
* this relates to. */
#define mainTIMER_CONTROLLED_LED 0x05UL
/* 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
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. */
* 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
* FreeRTOS.org web site to see which LEDs this relates to. */
#define mainCOM_TEST_LED ( 3 )
/* 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 )
/* 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
equivalent in ticks using the portTICK_PERIOD_MS constant. */
* have been reported by any of the standard demo tasks. ms are converted to the
* equivalent in ticks using the portTICK_PERIOD_MS constant. */
#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
reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */
* reported in one of the standard demo tasks. ms are converted to the equivalent
* in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_PERIOD_MS )
/* 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 )
/* 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 )
/* A zero block time. */
@ -219,8 +219,8 @@ static void prvSetupHardware( void );
* The application specific (not common demo) tasks as described in the comments
* at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*
* 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
* 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;
/* The LED software timer. This uses prvLEDTimerCallback() as it's callback
function. */
* function. */
static TimerHandle_t xLEDTimer = NULL;
/* 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;
/* The check timer. This uses prvCheckTimerCallback() as its callback
function. */
* function. */
static TimerHandle_t xCheckTimer = NULL;
/* 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
to make debugging easier. */
static const char *pcStatusMessage = NULL;
* be set to point to a string that identifies the offending task. This is just
* to make debugging easier. */
static const char * pcStatusMessage = NULL;
/*-----------------------------------------------------------*/
int main(void)
int main( void )
{
/* Configure the NVIC, LED outputs and button inputs. */
prvSetupHardware();
@ -278,22 +279,22 @@ int main(void)
if( xQueue != NULL )
{
/* 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( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* 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
this file. */
* if the button is not pushed within 5000ms, as described at the top of
* this file. */
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. */
( void * ) 0, /* The ID is not used, so can be set to anything. */
prvLEDTimerCallback /* The callback function that switches the LED off. */
);
/* 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. */
( 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. */
@ -302,7 +303,7 @@ int main(void)
);
/* 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. */
( 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. */
@ -311,8 +312,8 @@ int main(void)
);
/* Create a lot of 'standard demo' tasks. Over 40 tasks are created in
this demo. For a much simpler demo, select the 'blinky' build
configuration. */
* this demo. For a much simpler demo, select the 'blinky' build
* configuration. */
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
@ -327,9 +328,9 @@ int main(void)
vStartDynamicPriorityTasks();
/* 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
or not the correct/expected number of tasks are running at any given
time. */
* 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. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* 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
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
to be created. See the memory management section on the FreeRTOS web site
for more details. */
for( ;; );
* 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
* to be created. See the memory management section on the FreeRTOS web site
* for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
/* 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 )
{
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
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */
* the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
* everything is ok. A faster toggle indicates an error. */
vParTestToggleLED( mainCHECK_LED );
/* Have any errors been latch in pcStatusMessage? If so, shorten the
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
toggles. */
* 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
* toggles. */
if( pcStatusMessage != NULL )
{
/* This call to xTimerChangePeriod() uses a zero block time. Functions
called from inside of a timer callback function must *never* attempt
to block. */
* called from inside of a timer callback function must *never* attempt
* to 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 )
{
/* 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 );
}
/*-----------------------------------------------------------*/
@ -439,9 +442,9 @@ static void prvLEDTimerCallback( TimerHandle_t xTimer )
static void prvDigitCounterTimerCallback( TimerHandle_t xTimer )
{
/* 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 long lCounter = 0L;
const long lNumberOfDigits = 10L;
static const unsigned short usNumbersPatterns[] = { 0xC000U, 0xF900U, 0xA400U, 0xB000U, 0x9900U, 0x9200U, 0x8200U, 0xF800U, 0x8000U, 0x9000U };
static long lCounter = 0L;
const long lNumberOfDigits = 10L;
/* Display the next number, counting up. */
FM3_GPIO->PDOR1 = usNumbersPatterns[ lCounter ];
@ -460,78 +463,78 @@ const long lNumberOfDigits = 10L;
/* The ISR executed when the user button is pushed. */
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
LED timer. The LED timer will turn the LED off if the button is not
pushed within 5000ms. */
* LED timer. The LED timer will turn the LED off if the button is not
* pushed within 5000ms. */
vParTestSetLEDFromISR( mainTIMER_CONTROLLED_LED, pdTRUE );
/* This interrupt safe FreeRTOS function can be called from this interrupt
because the interrupt priority is below the
configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
* because the interrupt priority is below the
* configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken );
/* 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;
/* If calling xTimerResetFromISR() caused a task (in this case the timer
service/daemon task) to unblock, and the unblocked task has a priority
higher than or equal to the task that was interrupted, then
xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
* service/daemon task) to unblock, and the unblocked task has a priority
* higher than or equal to the task that was interrupted, then
* xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
* portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* 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,
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
service task will drain the command queue, and now the check and digit
counter timers can be started successfully. */
* 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
* 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
* counter timers can be started successfully. */
xTimerStart( xCheckTimer, portMAX_DELAY );
xTimerStart( xDigitCounterTimer, portMAX_DELAY );
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* 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
to ms. While in the Blocked state this task will not consume any CPU
time. */
* 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
* time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
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
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
vParTestToggleLED( mainTASK_CONTROLLED_LED );
@ -542,7 +545,7 @@ unsigned long ulReceivedValue;
static void prvSetupHardware( void )
{
const unsigned short usButtonInputBit = 0x01U;
const unsigned short usButtonInputBit = 0x01U;
SystemInit();
SystemCoreClockUpdate();
@ -575,42 +578,48 @@ const unsigned short usButtonInputBit = 0x01U;
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ;; );
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
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
does nothing useful, other than report the amount of FreeRTOS heap that
remains unallocated. */
* does nothing useful, other than report the amount of FreeRTOS heap that
* remains unallocated. */
xFreeStackSpace = xPortGetFreeHeapSize();
if( xFreeStackSpace > 100 )
{
/* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */
* if there is a lot of heap remaining unallocated then
* the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
* reduced accordingly. */
}
}
/*-----------------------------------------------------------*/
@ -618,8 +627,7 @@ volatile size_t xFreeStackSpace;
void vApplicationTickHook( void )
{
/* 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();
}
/*-----------------------------------------------------------*/

View file

@ -89,12 +89,12 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* 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.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*
* 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;
/* The LED software timer. This uses vLEDTimerCallback() as its callback
function. */
* function. */
static TimerHandle_t xLEDTimer = NULL;
/*-----------------------------------------------------------*/
int main(void)
int main( void )
{
/* Configure the NVIC, LED outputs and button inputs. */
prvSetupHardware();
@ -144,15 +144,15 @@ int main(void)
if( xQueue != NULL )
{
/* 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( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* 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
this file. */
* if the button is not pushed within 5000ms, as described at the top of
* this file. */
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. */
( void * ) 0, /* The ID is not used, so can be set to anything. */
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
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
to be created. See the memory management section on the FreeRTOS web site
for more details. */
for( ;; );
* 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
* to be created. See the memory management section on the FreeRTOS web site
* for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void vLEDTimerCallback( TimerHandle_t xTimer )
{
/* 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
a critical section because it is accessed from multiple tasks, and the
button interrupt - in this trivial case, for simplicity, the critical
section is omitted. */
* 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
* button interrupt - in this trivial case, for simplicity, the critical
* section is omitted. */
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. */
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
LED timer. The LED timer will turn the LED off if the button is not
pushed within 5000ms. */
* LED timer. The LED timer will turn the LED off if the button is not
* pushed within 5000ms. */
FM3_GPIO->PDOR1 &= ~mainTIMER_CONTROLLED_LED;
/* This interrupt safe FreeRTOS function can be called from this interrupt
because the interrupt priority is below the
configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
* because the interrupt priority is below the
* configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken );
/* 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;
/* If calling xTimerResetFromISR() caused a task (in this case the timer
service/daemon task) to unblock, and the unblocked task has a priority
higher than or equal to the task that was interrupted, then
xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
* service/daemon task) to unblock, and the unblocked task has a priority
* higher than or equal to the task that was interrupted, then
* xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
* portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* 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
to ms. While in the Blocked state this task will not consume any CPU
time. */
* 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
* time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
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
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
/* NOTE - accessing the LED port should use a critical section
because it is accessed from multiple tasks, and the button interrupt
- in this trivial case, for simplicity, the critical section is
omitted. */
* because it is accessed from multiple tasks, and the button interrupt
* - in this trivial case, for simplicity, the critical section is
* omitted. */
if( ( FM3_GPIO->PDOR3 & mainTASK_CONTROLLED_LED ) != 0 )
{
FM3_GPIO->PDOR3 &= ~mainTASK_CONTROLLED_LED;
@ -269,8 +271,8 @@ unsigned long ulReceivedValue;
static void prvSetupHardware( void )
{
const unsigned short usButtonInputBit = 0x01U;
const unsigned short usGPIOState = 0xFF00U;
const unsigned short usButtonInputBit = 0x01U;
const unsigned short usGPIOState = 0xFF00U;
SystemInit();
SystemCoreClockUpdate();
@ -315,54 +317,55 @@ const unsigned short usGPIOState = 0xFF00U;
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ;; );
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
for( ;; );
* configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* A tick hook is used by the "Full" build configuration. The Full and
blinky build configurations share a FreeRTOSConfig.h header file, so this
simple build configuration also has to define a tick hook - even though it
does not actually use it for anything. */
* blinky build configurations share a FreeRTOSConfig.h header file, so this
* simple build configuration also has to define a tick hook - even though it
* does not actually use it for anything. */
}
/*-----------------------------------------------------------*/
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
does nothing useful, other than report the amount of FreeRTOS heap that
remains unallocated. */
* does nothing useful, other than report the amount of FreeRTOS heap that
* remains unallocated. */
xFreeHeapSpace = xPortGetFreeHeapSize();
if( xFreeHeapSpace > 100 )
{
/* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */
* if there is a lot of heap remaining unallocated then
* the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
* reduced accordingly. */
}
}
/*-----------------------------------------------------------*/

View file

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

View file

@ -70,7 +70,7 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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 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 )
/* 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_TIMER ( 200UL )
@ -87,8 +87,8 @@ queue send software timer respectively. */
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*
* 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 ***/
void main_blinky( void )
{
const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS;
const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS;
/* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );
@ -116,12 +116,12 @@ const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS;
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
* file. */
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. */
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. */
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. */
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. */
pdTRUE, /* xAutoReload is set to pdTRUE, so this is an auto-reload timer. */
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. */
@ -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
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 tasks to be created. See the memory management section on the
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( ;; );
* 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 tasks to be created. See the memory management section on the
* 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( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const TickType_t xBlockTime = mainTASK_SEND_FREQUENCY_MS;
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK;
TickType_t xNextWakeTime;
const TickType_t xBlockTime = mainTASK_SEND_FREQUENCY_MS;
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK;
/* Prevent the compiler warning about the unused parameter. */
( void ) pvParameters;
@ -161,18 +163,18 @@ const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* 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
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. */
* 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.
* While in the Blocked state this task will not consume any CPU time. */
vTaskDelayUntil( &xNextWakeTime, xBlockTime );
/* 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
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. */
* 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
* have at least one space at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U );
}
}
@ -180,44 +182,44 @@ const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK;
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
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
if a key is not pressed for two seconds. */
* 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
* if a key is not pressed for two seconds. */
/* Avoid compiler warnings resulting from the unused parameter. */
( void ) xTimerHandle;
/* 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
must not block. Hence the block time is set to 0. */
* 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. */
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. */
( void ) pvParameters;
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. It will not use any CPU time while it is in the
Blocked state. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. It will not use any CPU time while it is in the
* Blocked state. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
/* 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" );
}
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 )
/* Stack sizes are defined relative to configMINIMAL_STACK_SIZE so they scale
across projects that have that constant set differently - in this case the
constant is different depending on the compiler in use. */
* across projects that have that constant set differently - in this case the
* constant is different depending on the compiler in use. */
#define mainMESSAGE_BUFFER_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
* 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();
/* 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
or not the correct/expected number of tasks are running at any given time. */
* 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. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
@ -155,27 +155,29 @@ void main_full( void )
vTaskStartScheduler();
/* If configSUPPORT_STATIC_ALLOCATION was false then execution would only
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
to reach here. */
for( ;; );
* 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
* to reach here. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
/* See the comments at the top of this file. */
static void prvCheckTask( void *pvParameters )
static void prvCheckTask( void * pvParameters )
{
static const char * pcMessage = "PASS";
const TickType_t xTaskPeriod = pdMS_TO_TICKS( 5000UL );
TickType_t xPreviousWakeTime;
extern uint32_t ulNestCount;
static const char * pcMessage = "PASS";
const TickType_t xTaskPeriod = pdMS_TO_TICKS( 5000UL );
TickType_t xPreviousWakeTime;
extern uint32_t ulNestCount;
/* Avoid warning about unused parameter. */
( void ) pvParameters;
xPreviousWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
vTaskDelayUntil( &xPreviousWakeTime, xTaskPeriod );
@ -188,6 +190,7 @@ extern uint32_t ulNestCount;
{
pcMessage = "xAreMessageBufferTasksStillRunning() returned false";
}
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreGenericQueueTasksStillRunning() returned false";
@ -278,8 +281,8 @@ extern uint32_t ulNestCount;
}
/* It is normally not good to call printf() from an embedded system,
although it is ok in this simulated case. */
printf( "%s : %d (%d)\r\n", pcMessage, (int) xTaskGetTickCount(), ( int ) ulNestCount );
* although it is ok in this simulated case. */
printf( "%s : %d (%d)\r\n", pcMessage, ( int ) xTaskGetTickCount(), ( int ) ulNestCount );
}
}
/*-----------------------------------------------------------*/
@ -287,7 +290,7 @@ extern uint32_t ulNestCount;
void vFullDemoTickHookFunction( void )
{
/* 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();
/* Call the event group ISR tests. */
@ -316,4 +319,3 @@ void vFullDemoTickHookFunction( void )
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"
/* Standard demo includes - just needed for the LED (ParTest) initialisation
function. */
* function. */
#include "partest.h"
/* Library includes. */
#include "het.h"
/* 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
/*-----------------------------------------------------------*/
@ -72,14 +72,14 @@ extern void main_full( void );
/*-----------------------------------------------------------*/
/* 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 )
{
/* Prepare the hardware to run this demo. */
prvSetupHardware();
/* 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
{
main_blinky();
@ -97,7 +97,7 @@ int main( void )
static void prvSetupHardware( void )
{
/* Perform any configuration necessary to use the ParTest LED output
functions. */
* functions. */
vParTestInitialise();
}
/*-----------------------------------------------------------*/
@ -105,54 +105,60 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
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.
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
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
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
* 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.
* 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
* 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
* FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* 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
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
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
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. */
* 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
* to block in any way (for example, call xQueueReceive() with a block time
* specified, or call vTaskDelay()). If the application makes use of the
* vTaskDelete() API function (as this demo application does) then it is also
* important that vApplicationIdleHook() is permitted to return to its calling
* 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. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
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
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
* 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
* code must not attempt to block, and only the interrupt safe FreeRTOS API
* functions can be used (those that end in FromISR()). */
}
/*-----------------------------------------------------------*/

View file

@ -77,16 +77,16 @@
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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 )
/* 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
the queue empty. */
* will remove items as they are added, meaning the send task should always find
* the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter
functionality. */
* functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
@ -95,8 +95,8 @@ functionality. */
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*
* Called by main() to create the simply blinky style application if
@ -119,7 +119,7 @@ void main_blinky( void )
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
* file. */
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. */
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
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 tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */
for( ;; );
* 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 tasks to be created. See the memory management section on the
* FreeRTOS web site for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
static void prvQueueSendTask( void * pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */
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. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* 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
to ms. While in the Blocked state this task will not consume any CPU
time. */
* 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
* time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* 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
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
* 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
* be empty at this point in the code. */
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. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
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.
*/
extern void vRegTestTask1( void *pvParameters );
extern void vRegTestTask2( void *pvParameters );
extern void vRegTestTask1( void * pvParameters );
extern void vRegTestTask2( void * pvParameters );
/*-----------------------------------------------------------*/
/* 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
variables to ensure they are still incrementing as expected. If a variable
stops incrementing then it is likely that its associate task has stalled. */
* 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
* stops incrementing then it is likely that its associate task has stalled. */
volatile unsigned long ulRegTest1Counter = 0, ulRegTest2Counter = 0;
/*-----------------------------------------------------------*/
void main_full( void )
{
TimerHandle_t xTimer = NULL;
TimerHandle_t xTimer = NULL;
/* Start all the standard demo/test tasks. These have not particular
functionality, but do demonstrate how to use the FreeRTOS API, and test the
kernel port. */
* functionality, but do demonstrate how to use the FreeRTOS API, and test the
* kernel port. */
vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
@ -169,7 +169,7 @@ TimerHandle_t xTimer = NULL;
/* 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. */
( 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. */
@ -183,9 +183,9 @@ TimerHandle_t xTimer = NULL;
}
/* 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. */
( 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. */
( void * ) 0, /* The ID is not used, so can be set to anything. */
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
created last as they keep account of the number of tasks they expect to see
running. */
* created last as they keep account of the number of tasks they expect to see
* running. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the scheduler. */
vTaskStartScheduler();
/* 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
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
for more details. */
for( ;; );
* 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
* to be created. See the memory management section on the FreeRTOS web site
* for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
static long lChangeToRedLEDsAlready = pdFALSE;
static unsigned long ulLastRegTest1Counter = 0, ulLastRegTest2Counter = 0;
unsigned long ulErrorFound = pdFALSE;
static long lChangeToRedLEDsAlready = pdFALSE;
static unsigned long ulLastRegTest1Counter = 0, ulLastRegTest2Counter = 0;
unsigned long ulErrorFound = pdFALSE;
/* LEDs are defaulted to use the Green LEDs. The Red LEDs are used if an error
is found. */
static unsigned long ulLED1 = 8, ulLED2 = 11;
const unsigned long ulRedLED1 = 6, ulRedLED2 = 9;
* is found. */
static unsigned long ulLED1 = 8, ulLED2 = 11;
const unsigned long ulRedLED1 = 6, ulRedLED2 = 9;
/* 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 )
{
@ -241,17 +244,17 @@ const unsigned long ulRedLED1 = 6, ulRedLED2 = 9;
ulErrorFound = pdTRUE;
}
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
if( xAreRecursiveMutexTasksStillRunning() != 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
incrementing their loop counters if they encounter an error. */
* incrementing their loop counters if they encounter an error. */
if( ulRegTest1Counter == ulLastRegTest1Counter )
{
ulErrorFound = pdTRUE;
@ -297,13 +300,13 @@ const unsigned long ulRedLED1 = 6, ulRedLED2 = 9;
ulLastRegTest2Counter = ulRegTest2Counter;
/* 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
LEDs are toggling, then an error has been reported in at least one task. */
* 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. */
vParTestToggleLED( ulLED1 );
vParTestToggleLED( ulLED2 );
/* 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( lChangeToRedLEDsAlready == pdFALSE )
@ -322,8 +325,8 @@ const unsigned long ulRedLED1 = 6, ulRedLED2 = 9;
static void prvLEDTimerCallback( TimerHandle_t xTimer )
{
const unsigned long ulNumWhiteLEDs = 6;
static unsigned long ulLit1 = 2, ulLit2 = 1;
const unsigned long ulNumWhiteLEDs = 6;
static unsigned long ulLit1 = 2, ulLit2 = 1;
vParTestSetLED( ulLit2, pdFALSE );
@ -338,4 +341,3 @@ static unsigned long ulLit1 = 2, ulLit2 = 1;
vParTestSetLED( ulLit1, pdTRUE );
}
/*-----------------------------------------------------------*/

View file

@ -86,7 +86,7 @@
/* 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_ERROR ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
@ -114,25 +114,25 @@ check task has detected an error or not. */
static void prvSetupHardware( void );
/* 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
(USART1). */
static void prvUSARTEchoTask( void *pvParameters );
* (USART1). */
static void prvUSARTEchoTask( void * pvParameters );
/*-----------------------------------------------------------*/
int main( void )
{
#ifdef DEBUG
#ifdef DEBUG
debug();
#endif
#endif
/* Set up the clocks and memory interface. */
prvSetupHardware();
/* 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 );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
@ -151,25 +151,27 @@ int main( void )
vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle
task. The idle task is created within vTaskStartScheduler(). */
for( ;; );
* task. The idle task is created within vTaskStartScheduler(). */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
/* Described at the top of this file. */
static void prvCheckTask( void *pvParameters )
static void prvCheckTask( void * pvParameters )
{
TickType_t xLastExecutionTime;
unsigned long ulTicksToWait = mainCHECK_DELAY_NO_ERROR;
TickType_t xLastExecutionTime;
unsigned long ulTicksToWait = mainCHECK_DELAY_NO_ERROR;
/* Just to remove the compiler warning about the unused parameter. */
( void ) pvParameters;
/* Initialise the variable used to control our iteration rate prior to
its first use. */
* its first use. */
xLastExecutionTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Wait until it is time to run the tests again. */
vTaskDelayUntil( &xLastExecutionTime, ulTicksToWait );
@ -178,8 +180,8 @@ unsigned long ulTicksToWait = mainCHECK_DELAY_NO_ERROR;
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
/* Reduce the time between cycles of this task - which has the
effect of increasing the rate at which the 'check' LED toggles to
indicate the existence of an error to an observer. */
* effect of increasing the rate at which the 'check' LED toggles to
* indicate the existence of an error to an observer. */
ulTicksToWait = mainCHECK_DELAY_ERROR;
}
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
@ -209,26 +211,26 @@ unsigned long ulTicksToWait = mainCHECK_DELAY_NO_ERROR;
/*-----------------------------------------------------------*/
/* 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
what the optimisation level. */
static const char *pcLongishString =
"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 "
"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 "
"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 "
"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 "
"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 "
"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, "
"introspective lyrics with different compositions.";
* what the optimisation level. */
static const char * pcLongishString =
"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 "
"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 "
"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 "
"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 "
"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 "
"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, "
"introspective lyrics with different compositions.";
/* Just to avoid compiler warnings. */
( void ) pvParameters;
@ -237,10 +239,10 @@ static const char *pcLongishString =
lCOMPortInit( mainCOM0, mainBAUD_RATE );
/* 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 ) );
for( ;; )
for( ; ; )
{
/* Block to wait for a character to be received on COM0. */
xSerialGetChar( mainCOM0, &cChar, portMAX_DELAY );
@ -254,13 +256,15 @@ static const char *pcLongishString =
static void prvSetupHardware( void )
{
/* RCC system reset(for debug purpose). */
RCC_DeInit ();
RCC_DeInit();
/* Enable HSE. */
RCC_HSEConfig( RCC_HSE_ON );
/* Wait till HSE is ready. */
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
while( RCC_GetFlagStatus( RCC_FLAG_HSERDY ) == RESET )
{
}
/* HCLK = SYSCLK. */
RCC_HCLKConfig( RCC_SYSCLK_Div1 );
@ -275,7 +279,7 @@ static void prvSetupHardware( void )
RCC_ADCCLKConfig( RCC_PCLK2_Div4 );
/* Flash 2 wait state. */
*( volatile unsigned long * )0x40022000 = 0x01;
*( volatile unsigned long * ) 0x40022000 = 0x01;
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_9 );
@ -284,16 +288,20 @@ static void prvSetupHardware( void )
RCC_PLLCmd( ENABLE );
/* 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. */
RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK);
RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );
/* 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 */
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 );
/* 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
parameters are corrupt then inspect pxCurrentTCB to find which was the
offending task. */
* parameters are corrupt then inspect pxCurrentTCB to find which was the
* offending task. */
( void ) pxTask;
( 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 ) ulLine;
for( ;; );
for( ; ; )
{
}
}

View file

@ -98,7 +98,7 @@
#define mainCOLUMN_INCREMENT ( 16 )
/* The maximum number of message that can be waiting for display at any one
time. */
* time. */
#define mainLCD_QUEUE_SIZE ( 3 )
/* The check task uses the sprintf function so requires a little more stack. */
@ -117,7 +117,7 @@ time. */
#define mainCOM_TEST_BAUD_RATE ( 115200 )
/* The LED used by the comtest tasks. See the comtest.c file for more
information. */
* information. */
#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
* the message to the gatekeeper.
*/
static void vLCDTask( void *pvParameters );
static void vLCDTask( void * pvParameters );
/*
* 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
@ -155,7 +156,7 @@ int fputc( int ch, FILE *f );
* Messages are not written directly to the terminal, but passed to vLCDTask
* via a queue.
*/
static void vCheckTask( void *pvParameters );
static void vCheckTask( void * pvParameters );
/*
* Configures the timers and interrupts for the fast interrupt test as
@ -172,14 +173,14 @@ QueueHandle_t xLCDQueue;
int main( void )
{
#ifdef DEBUG
#ifdef DEBUG
debug();
#endif
#endif
prvSetupHardware();
/* 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 ) );
/* Start the standard demo tasks. */
@ -196,8 +197,8 @@ int main( void )
xTaskCreate( vLCDTask, "LCD", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
/* 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
or not the correct/expected number of tasks are running at any given time. */
* 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. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Configure the timers used by the fast interrupt timer test. */
@ -207,23 +208,25 @@ int main( void )
vTaskStartScheduler();
/* Will only get here if there was not enough heap space to create the
idle task. */
* idle task. */
return 0;
}
/*-----------------------------------------------------------*/
void vLCDTask( void *pvParameters )
void vLCDTask( void * pvParameters )
{
xLCDMessage xMessage;
xLCDMessage xMessage;
/* Initialise the LCD and display a startup message. */
prvConfigureLCD();
LCD_DrawMonoPict( ( unsigned long * ) pcBitmap );
for( ;; )
for( ; ; )
{
/* 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. */
printf( ( char const * ) xMessage.pcMessage );
@ -231,17 +234,17 @@ xLCDMessage xMessage;
}
/*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters )
static void vCheckTask( void * pvParameters )
{
TickType_t xLastExecutionTime;
xLCDMessage xMessage;
static signed char cPassMessage[ mainMAX_MSG_LEN ];
extern unsigned short usMaxJitter;
TickType_t xLastExecutionTime;
xLCDMessage xMessage;
static signed char cPassMessage[ mainMAX_MSG_LEN ];
extern unsigned short usMaxJitter;
xLastExecutionTime = xTaskGetTickCount();
xMessage.pcMessage = cPassMessage;
for( ;; )
for( ; ; )
{
/* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
@ -319,7 +322,7 @@ static void prvSetupHardware( void )
RCC_PLLCmd( ENABLE );
/* 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 */
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 );
/* SPI2 Periph clock enable */
@ -353,7 +356,7 @@ static void prvSetupHardware( void )
static void prvConfigureLCD( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure LCD Back Light (PA8) as output push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
@ -362,7 +365,7 @@ GPIO_InitTypeDef GPIO_InitStructure;
GPIO_Init( GPIOA, &GPIO_InitStructure );
/* Set the Backlight Pin */
GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET);
GPIO_WriteBit( GPIOA, GPIO_Pin_8, Bit_SET );
/* Initialize the LCD */
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 char ucLine = 0;
static unsigned short usColumn = 0, usRefColumn = mainCOLUMN_START;
static unsigned char ucLine = 0;
if( ( usColumn == 0 ) && ( ucLine == 0 ) )
{
@ -390,13 +394,14 @@ static unsigned char ucLine = 0;
if( ch != '\n' )
{
/* Display one character on LCD */
LCD_DisplayChar( ucLine, usRefColumn, (u8) ch );
LCD_DisplayChar( ucLine, usRefColumn, ( u8 ) ch );
/* Decrement the column position by 16 */
usRefColumn -= mainCOLUMN_INCREMENT;
/* Increment the character counter */
usColumn++;
if( usColumn == mainMAX_COLUMN )
{
ucLine += mainROW_INCREMENT;
@ -424,10 +429,11 @@ static unsigned char ucLine = 0;
#ifdef DEBUG
/* Keep the linker happy. */
void assert_failed( unsigned char* pcFile, unsigned long ulLine )
{
for( ;; )
void assert_failed( unsigned char * pcFile,
unsigned long ulLine )
{
for( ; ; )
{
}
}
}
#endif

View file

@ -98,7 +98,7 @@
#define mainCOLUMN_INCREMENT ( 16 )
/* The maximum number of message that can be waiting for display at any one
time. */
* time. */
#define mainLCD_QUEUE_SIZE ( 3 )
/* The check task uses the sprintf function so requires a little more stack. */
@ -117,7 +117,7 @@ time. */
#define mainCOM_TEST_BAUD_RATE ( 115200 )
/* The LED used by the comtest tasks. See the comtest.c file for more
information. */
* information. */
#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
* the message to the gatekeeper.
*/
static void vLCDTask( void *pvParameters );
static void vLCDTask( void * pvParameters );
/*
* 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
@ -155,7 +156,7 @@ int fputc( int ch, FILE *f );
* Messages are not written directly to the terminal, but passed to vLCDTask
* via a queue.
*/
static void vCheckTask( void *pvParameters );
static void vCheckTask( void * pvParameters );
/*
* Configures the timers and interrupts for the fast interrupt test as
@ -172,14 +173,14 @@ QueueHandle_t xLCDQueue;
int main( void )
{
#ifdef DEBUG
#ifdef DEBUG
debug();
#endif
#endif
prvSetupHardware();
/* 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 ) );
/* Start the standard demo tasks. */
@ -196,8 +197,8 @@ int main( void )
xTaskCreate( vLCDTask, "LCD", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
/* 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
or not the correct/expected number of tasks are running at any given time. */
* 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. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Configure the timers used by the fast interrupt timer test. */
@ -207,23 +208,25 @@ int main( void )
vTaskStartScheduler();
/* Will only get here if there was not enough heap space to create the
idle task. */
* idle task. */
return 0;
}
/*-----------------------------------------------------------*/
void vLCDTask( void *pvParameters )
void vLCDTask( void * pvParameters )
{
xLCDMessage xMessage;
xLCDMessage xMessage;
/* Initialise the LCD and display a startup message. */
prvConfigureLCD();
LCD_DrawMonoPict( ( unsigned long * ) pcBitmap );
for( ;; )
for( ; ; )
{
/* 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. */
printf( ( char const * ) xMessage.pcMessage );
@ -231,17 +234,17 @@ xLCDMessage xMessage;
}
/*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters )
static void vCheckTask( void * pvParameters )
{
TickType_t xLastExecutionTime;
xLCDMessage xMessage;
static signed char cPassMessage[ mainMAX_MSG_LEN ];
extern unsigned short usMaxJitter;
TickType_t xLastExecutionTime;
xLCDMessage xMessage;
static signed char cPassMessage[ mainMAX_MSG_LEN ];
extern unsigned short usMaxJitter;
xLastExecutionTime = xTaskGetTickCount();
xMessage.pcMessage = cPassMessage;
for( ;; )
for( ; ; )
{
/* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
@ -319,7 +322,7 @@ static void prvSetupHardware( void )
RCC_PLLCmd( ENABLE );
/* 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 */
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 );
/* SPI2 Periph clock enable */
@ -353,7 +356,7 @@ static void prvSetupHardware( void )
static void prvConfigureLCD( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure LCD Back Light (PA8) as output push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
@ -362,7 +365,7 @@ GPIO_InitTypeDef GPIO_InitStructure;
GPIO_Init( GPIOA, &GPIO_InitStructure );
/* Set the Backlight Pin */
GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET);
GPIO_WriteBit( GPIOA, GPIO_Pin_8, Bit_SET );
/* Initialize the LCD */
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 char ucLine = 0;
static unsigned short usColumn = 0, usRefColumn = mainCOLUMN_START;
static unsigned char ucLine = 0;
if( ( usColumn == 0 ) && ( ucLine == 0 ) )
{
@ -390,13 +394,14 @@ static unsigned char ucLine = 0;
if( ch != '\n' )
{
/* Display one character on LCD */
LCD_DisplayChar( ucLine, usRefColumn, (u8) ch );
LCD_DisplayChar( ucLine, usRefColumn, ( u8 ) ch );
/* Decrement the column position by 16 */
usRefColumn -= mainCOLUMN_INCREMENT;
/* Increment the character counter */
usColumn++;
if( usColumn == mainMAX_COLUMN )
{
ucLine += mainROW_INCREMENT;
@ -424,10 +429,11 @@ static unsigned char ucLine = 0;
#ifdef DEBUG
/* Keep the linker happy. */
void assert_failed( unsigned char* pcFile, unsigned long ulLine )
{
for( ;; )
void assert_failed( unsigned char * pcFile,
unsigned long ulLine )
{
for( ; ; )
{
}
}
}
#endif

View file

@ -64,7 +64,7 @@
*/
/* 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"
/* Standard includes. */
@ -83,9 +83,9 @@ utilised, although CircleOS itself is not used. */
#include "QPeek.h"
/* 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
parameter to 0 excludes the bitmap from the build, freeing up Flash space for
extra code. */
* 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
* extra code. */
#define mainINCLUDE_BITMAP 0
#if mainINCLUDE_BITMAP == 1
@ -111,14 +111,14 @@ extra code. */
#define mainLCD_MAX_Y ( 110 )
/* The maximum number of message that can be waiting for display at any one
time. */
* time. */
#define mainLCD_QUEUE_SIZE ( 3 )
/* The check task uses the sprintf function so requires a little more stack. */
#define mainCHECK_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 50 )
/* 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 )
/* Dimensions the buffer into which the jitter time is written. */
@ -144,7 +144,7 @@ these can require a larger stack. */
typedef struct
{
portBASE_TYPE xMessageType;
signed char *pcMessage;
signed char * pcMessage;
} xLCDMessage;
/*-----------------------------------------------------------*/
@ -160,7 +160,7 @@ static void prvSetupHardware( void );
* access the LCD directly. Other tasks wanting to display a message send
* 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
@ -175,7 +175,7 @@ static void prvLCDTask( void *pvParameters );
* The check task also receives instructions to update the MEMS input, which
* 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
@ -187,12 +187,14 @@ extern void vSetupTimerTest( void );
* A cut down version of sprintf() used to percent the HUGE GCC library
* 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.
*/
static void prvFlashTask( void *pvParameters );
static void prvFlashTask( void * pvParameters );
/*-----------------------------------------------------------*/
@ -210,7 +212,7 @@ int main( void )
prvSetupHardware();
/* 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 ) );
/* Start the standard demo tasks. */
@ -232,17 +234,17 @@ int main( void )
vTaskStartScheduler();
/* Will only get here if there was not enough heap space to create the
idle task. */
* idle task. */
return 0;
}
/*-----------------------------------------------------------*/
void prvLCDTask( void *pvParameters )
void prvLCDTask( void * pvParameters )
{
xLCDMessage xMessage;
char cY = mainLCD_CHAR_HEIGHT;
const char * const pcString = "www.FreeRTOS.org";
const char * const pcBlankLine = " ";
xLCDMessage xMessage;
char cY = mainLCD_CHAR_HEIGHT;
const char * const pcString = "www.FreeRTOS.org";
const char * const pcBlankLine = " ";
DRAW_Init();
@ -255,10 +257,12 @@ const char * const pcBlankLine = " ";
vTaskDelay( mainSPLASH_SCREEN_DELAY );
LCD_FillRect( 0, 0, CHIP_SCREEN_WIDTH, CHIP_SCREEN_HEIGHT, RGB_WHITE );
for( ;; )
for( ; ; )
{
/* 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. */
if( xMessage.xMessageType == mainUPDATE_BALL_MESSAGE )
@ -270,10 +274,11 @@ const char * const pcBlankLine = " ";
else
{
/* 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 ) );
cY -= mainLCD_CHAR_HEIGHT;
if( cY <= ( mainLCD_CHAR_HEIGHT - 1 ) )
{
/* 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;
xLCDMessage xMessage;
static signed char cPassMessage[ mainMAX_MSG_LEN ];
extern unsigned short usMaxJitter;
TickType_t xLastExecutionTime;
xLCDMessage xMessage;
static signed char cPassMessage[ mainMAX_MSG_LEN ];
extern unsigned short usMaxJitter;
/* Initialise the xLastExecutionTime variable on task entry. */
xLastExecutionTime = xTaskGetTickCount();
@ -301,18 +306,19 @@ extern unsigned short usMaxJitter;
xMessage.xMessageType = mainWRITE_STRING_MESSAGE;
xMessage.pcMessage = cPassMessage;
for( ;; )
for( ; ; )
{
/* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
/* 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
the PASS message. */
* we are going to send to the LCD task to an error message instead of
* the PASS message. */
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN GEN Q";
}
if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN BLOCK Q";
@ -332,9 +338,9 @@ extern unsigned short usMaxJitter;
else
{
/* No errors were found in any task, so send a pass message
with the max measured jitter time also included (as per the
fast interrupt test described at the top of this file and on
the online documentation page for this demo application). */
* with the max measured jitter time also included (as per the
* fast interrupt test described at the top of this file and on
* the online documentation page for this demo application). */
sprintf( ( char * ) cPassMessage, "PASS [%uns]", ( ( unsigned long ) usMaxJitter ) * mainNS_PER_CLOCK );
}
@ -346,13 +352,14 @@ extern unsigned short usMaxJitter;
void vApplicationTickHook( void )
{
static unsigned long ulCallCount;
static const xLCDMessage xMemsMessage = { mainUPDATE_BALL_MESSAGE, NULL };
static portBASE_TYPE xHigherPriorityTaskWoken;
static unsigned long ulCallCount;
static const xLCDMessage xMemsMessage = { mainUPDATE_BALL_MESSAGE, NULL };
static portBASE_TYPE xHigherPriorityTaskWoken;
/* 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++;
if( ulCallCount >= mainMEMS_DELAY )
{
ulCallCount = 0;
@ -394,7 +401,7 @@ static void prvSetupHardware( void )
RCC_PLLCmd( ENABLE );
/* 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 */
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 );
/* SPI2 Periph clock enable */
@ -423,7 +430,7 @@ static void prvSetupHardware( void )
SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK );
/* Misc initialisation, including some of the CircleOS features. Note
that CircleOS itself is not used. */
* that CircleOS itself is not used. */
vParTestInitialise();
MEMS_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. */
xLastExecutionTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Simple toggle the LED periodically. This just provides some timing
verification. */
* verification. */
vTaskDelayUntil( &xLastExecutionTime, mainFLASH_DELAY );
vParTestToggleLED( 0 );
}
@ -452,6 +459,3 @@ void starting_delay( unsigned long ul )
{
vTaskDelay( ( TickType_t ) ul );
}

View file

@ -61,10 +61,11 @@ extern void main_low_power( void );
extern void main_full( void );
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
* within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void );
/*-----------------------------------------------------------*/
@ -75,7 +76,7 @@ int main( void )
prvSetupHardware();
/* The configCREATE_LOW_POWER_DEMO setting is described at the top of
this file. */
* this file. */
#if configCREATE_LOW_POWER_DEMO == 1
{
main_low_power();
@ -94,10 +95,11 @@ int main( void )
static void prvSetupHardware( void )
{
/* GPIO, EXTI and NVIC Init structure declaration */
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
void SystemCoreClockUpdate( void );
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
void SystemCoreClockUpdate( void );
/* System function that updates the SystemCoreClock variable. */
SystemCoreClockUpdate();
@ -112,19 +114,21 @@ void SystemCoreClockUpdate( void );
RCC_MSIRangeConfig( RCC_MSIRange_6 );
/* 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. */
RCC_APB1PeriphClockCmd( RCC_APB1Periph_COMP, ENABLE );
/* Enable SYSCFG clocks. */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG , ENABLE );
RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG, ENABLE );
/* Set internal voltage regulator to 1.5V. */
PWR_VoltageScalingConfig( PWR_VoltageScaling_Range2 );
/* 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 */
GPIO_InitStructure.GPIO_Pin = USERBUTTON_GPIO_PIN;
@ -137,7 +141,7 @@ void SystemCoreClockUpdate( void );
SYSCFG_EXTILineConfig( EXTI_PortSourceGPIOA, EXTI_PinSource0 );
/* 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_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
@ -167,60 +171,68 @@ void SystemCoreClockUpdate( void );
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
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.
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
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
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
* 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.
* 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
* 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
* FreeRTOSConfig.h, and the xPortGetFreeHeapSize() 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 fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* 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
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
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
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. */
* 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
* to block in any way (for example, call xQueueReceive() with a block time
* specified, or call vTaskDelay()). If the application makes use of the
* vTaskDelete() API function (as this demo application does) then it is also
* important that vApplicationIdleHook() is permitted to return to its calling
* 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. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
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
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
* 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
* code must not attempt to block, and only the interrupt safe FreeRTOS API
* 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. */
( void ) ulLine;
@ -231,12 +243,11 @@ volatile unsigned long ulSetToNonZeroInDebuggerToContinue = 0;
while( ulSetToNonZeroInDebuggerToContinue == 0 )
{
/* Use the debugger to set ulSetToNonZeroInDebuggerToContinue to a
non zero value to step out of this function to the point that raised
this assert(). */
__asm volatile( "NOP" );
__asm volatile( "NOP" );
* non zero value to step out of this function to the point that raised
* this assert(). */
__asm volatile ( "NOP" );
__asm volatile ( "NOP" );
}
}
taskEXIT_CRITICAL();
}

View file

@ -94,13 +94,13 @@
#define mainDONT_BLOCK ( 0UL )
/* 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
equivalent in ticks using the portTICK_PERIOD_MS constant. */
* have been reported by any of the standard demo tasks. ms are converted to the
* equivalent in ticks using the portTICK_PERIOD_MS constant. */
#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
reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */
* reported in one of the standard demo tasks. ms are converted to the equivalent
* in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/*-----------------------------------------------------------*/
@ -119,14 +119,14 @@ static void prvConfigureLCD( void );
void main_full( void )
{
TimerHandle_t xCheckTimer = NULL;
TimerHandle_t xCheckTimer = NULL;
/* The LCD is only used in the Full demo. */
prvConfigureLCD();
/* 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
kernel port. */
* functionality, but do demonstrate how to use the FreeRTOS API and test the
* kernel port. */
vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks();
@ -137,7 +137,7 @@ TimerHandle_t xCheckTimer = NULL;
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
/* 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. */
( 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. */
@ -154,21 +154,23 @@ TimerHandle_t xCheckTimer = NULL;
vTaskStartScheduler();
/* 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
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
for more details. */
for( ;; );
* 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
* to be created. See the memory management section on the FreeRTOS web site
* for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
static long lChangedTimerPeriodAlready = pdFALSE;
unsigned long ulErrorFound = pdFALSE;
static long lChangedTimerPeriodAlready = pdFALSE;
unsigned long ulErrorFound = pdFALSE;
/* 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 )
{
@ -180,17 +182,17 @@ unsigned long ulErrorFound = pdFALSE;
ulErrorFound = pdTRUE;
}
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
@ -206,14 +208,14 @@ unsigned long ulErrorFound = pdFALSE;
}
/* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */
* the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
* everything is ok. A faster toggle indicates an error. */
GPIO_TOGGLE( LD_GPIO_PORT, LD_GREEN_GPIO_PIN );
/* Have any errors been latch in ulErrorFound? If so, shorten the
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
toggles. */
* 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
* toggles. */
if( ulErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == pdFALSE )
@ -221,8 +223,8 @@ unsigned long ulErrorFound = pdFALSE;
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time.
Functions called from inside of a timer callback function must
*never* attempt to block. */
* Functions called from inside of a timer callback function must
* never* attempt to block. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
@ -231,7 +233,7 @@ unsigned long ulErrorFound = pdFALSE;
static void prvConfigureLCD( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable necessary clocks. */
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC, ENABLE );
@ -242,7 +244,7 @@ GPIO_InitTypeDef GPIO_InitStructure;
RCC_RTCCLKCmd( ENABLE );
/* 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_Init( GPIOA, &GPIO_InitStructure );
@ -274,7 +276,7 @@ GPIO_InitTypeDef GPIO_InitStructure;
GPIO_PinAFConfig( GPIOB, GPIO_PinSource15, GPIO_AF_LCD );
/* 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_Init( GPIOC, &GPIO_InitStructure );
@ -293,4 +295,3 @@ GPIO_InitTypeDef GPIO_InitStructure;
LCD_GLASS_Init();
LCD_GLASS_DisplayString( "F'RTOS" );
}

View file

@ -124,8 +124,8 @@
#define configQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* 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
empty. */
* remove items as they are added so the Tx task should always find the queue
* empty. */
#define mainQUEUE_LENGTH ( 1 )
/* 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.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/
@ -156,7 +156,7 @@ static QueueHandle_t xQueue = NULL;
TickType_t xSendBlockTime = ( 100UL / portTICK_PERIOD_MS );
/* 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 );
/* The semaphore on which the Tx task blocks. */
@ -183,25 +183,27 @@ void main_low_power( void )
vTaskStartScheduler();
/* 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
there was insufficient FreeRTOS heap available for the idle task and/or
timer task to be created. See http://www.freertos.org/a00111.html. */
for( ;; );
* 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
* timer task to be created. See http://www.freertos.org/a00111.html. */
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. */
( void ) pvParameters;
for( ;; )
for( ; ; )
{
/* Enter the Blocked state to wait for the semaphore. The task will
leave the Blocked state if either the semaphore is received or
xSendBlockTime ticks pass without the semaphore being received. */
* leave the Blocked state if either the semaphore is received or
* xSendBlockTime ticks pass without the semaphore being received. */
xSemaphoreTake( xTxSemaphore, xSendBlockTime );
/* 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. */
( void ) pvParameters;
for( ;; )
for( ; ; )
{
/* Wait until something arrives in the queue. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* 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 )
{
/* LED on... */
@ -240,13 +242,13 @@ unsigned long ulReceivedValue;
/*-----------------------------------------------------------*/
/* 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
indefinitely, and this interrupt is bringing the MCU out of STOP low power
mode. */
* indefinitely, and this interrupt is bringing the MCU out of STOP low power
* mode. */
if( xSendBlockTime == portMAX_DELAY )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
@ -255,24 +257,24 @@ static const TickType_t xIncrement = 200UL / portTICK_PERIOD_MS;
xSemaphoreGiveFromISR( xTxSemaphore, &xHigherPriorityTaskWoken );
/* Start over with the 'short' block time as described at the top of
this file. */
* this file. */
xSendBlockTime = xMinBlockTime;
/* Request a yield if calling xSemaphoreGiveFromISR() caused a task to
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
(which it will have). */
* 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
* (which it will have). */
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
else
{
/* Increase the block time used by the Tx task, as described at the top
of this file. */
* of this file. */
xSendBlockTime += xIncrement;
/* 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
mode. */
* an infinite block time to allow the MCU to go into its STOP low power
* mode. */
if( xSendBlockTime > xMaxBlockTime )
{
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
STOP low power mode. The macro is set in FreeRTOSConfig.h to call
vMainPostStopProcessing(). */
* STOP low power mode. The macro is set in FreeRTOSConfig.h to call
* vMainPostStopProcessing(). */
void vMainPostStopProcessing( void )
{
extern void SetSysClock( void );
extern void SetSysClock( void );
/* The STOP low power mode has been exited. Reconfigure the system clocks
ready for normally running again. */
* ready for normally running again. */
SetSysClock();
}
/*-----------------------------------------------------------*/

View file

@ -87,7 +87,7 @@
* 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
* error.
*/
*/
/* Standard includes. */
#include <stdio.h>
@ -115,19 +115,19 @@
#define mainGENERIC_QUEUE_TEST_PRIORITY ( tskIDLE_PRIORITY )
/* 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 )
/* 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
cMessageID member of the message structure (defined below). */
* exactly what the message it just received was. These are sent in the
* cMessageID member of the message structure (defined below). */
#define mainMESSAGE_BUTTON_UP ( 1 )
#define mainMESSAGE_BUTTON_SEL ( 2 )
#define mainMESSAGE_STATUS ( 3 )
/* When the cMessageID member of the message sent to the LCD task is
mainMESSAGE_STATUS then these definitions are sent in the lMessageValue member
of the same message and indicate what the status actually is. */
* mainMESSAGE_STATUS then these definitions are sent in the lMessageValue member
* of the same message and indicate what the status actually is. */
#define mainERROR_DYNAMIC_TASKS ( pdPASS + 1 )
#define mainERROR_COM_TEST ( pdPASS + 2 )
#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 )
/* The LED used by the comtest tasks. See the comtest.c file for more
information. */
* information. */
#define mainCOM_TEST_LED ( 3 )
/* 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 )
/*-----------------------------------------------------------*/
@ -155,37 +155,38 @@ static void prvSetupHardware( void );
* Definition of the LCD/controller task described in the comments at the top
* 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
* this file.
*/
static void prvButtonPollTask( void *pvParameters );
static void prvButtonPollTask( void * pvParameters );
/*
* Converts a status message value into an appropriate string for display on
* 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.
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
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
consistency when combining the two in case a timer overflow occurs as the
value is being read. */
* 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
* 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
* consistency when combining the two in case a timer overflow occurs as the
* value is being read. */
unsigned long ulTIM6_OverflowCount = 0UL;
/* 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;
/* The definition of each message sent from tasks and interrupts to the LCD
task. */
* task. */
typedef struct
{
char cMessageID; /* << States what the message is. */
@ -197,23 +198,23 @@ typedef struct
void main( void )
{
/* 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();
/* Create the queue used by tasks and interrupts to send strings to the LCD
task. */
* task. */
xLCDQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( xQueueMessage ) );
/* 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 )
{
/* 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" );
/* 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( 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
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
hook function, if one is configured. */
for( ;; );
* 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
* hook function, if one is configured. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvLCDTask( void *pvParameters )
static void prvLCDTask( void * pvParameters )
{
xQueueMessage xReceivedMessage;
long lLine = Line1;
const long lFontHeight = (((sFONT *)LCD_GetFont())->Height);
xQueueMessage xReceivedMessage;
long lLine = Line1;
const long lFontHeight = ( ( ( sFONT * ) LCD_GetFont() )->Height );
/* 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
stack, which is too small to hold such a variable. The stack size is configured
when the task is created. */
static char cBuffer[ 512 ];
* 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
* when the task is created. */
static char cBuffer[ 512 ];
/* 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
will be necessary.
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
can be viewed in the terminal IO window within the IAR Embedded Workbench. */
* used from any other function then some sort of mutual exclusion on stdout
* will be necessary.
*
* 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
* can be viewed in the terminal IO window within the IAR Embedded Workbench. */
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
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
function return value and the function will only return when a value
has been received. */
* 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
* function return value and the function will only return when a value
* has been received. */
xQueueReceive( xLCDQueue, &xReceivedMessage, portMAX_DELAY );
/* 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? */
switch( xReceivedMessage.cMessageID )
{
case mainMESSAGE_BUTTON_UP : /* The button poll task has just
informed this task that the up
button on the joystick input has
been pressed or released. */
case mainMESSAGE_BUTTON_UP: /* The button poll task has just
* informed this task that the up
* button on the joystick input has
* been pressed or released. */
sprintf( cBuffer, "Button up = %d", xReceivedMessage.lMessageValue );
break;
case mainMESSAGE_BUTTON_SEL : /* The select button interrupt
just informed this task that the
select button was pressed.
Generate a table of task run time
statistics and output this to
the terminal IO window in the IAR
embedded workbench. */
case mainMESSAGE_BUTTON_SEL: /* The select button interrupt
* just informed this task that the
* select button was pressed.
* Generate a table of task run time
* statistics and output this to
* the terminal IO window in the IAR
* embedded workbench. */
printf( "\nTask\t Abs Time\t %%Time\n*****************************************" );
vTaskGetRunTimeStats( cBuffer );
printf( cBuffer );
/* Also print out a message to
the LCD - in this case the
pointer to the string to print
is sent directly in the
lMessageValue member of the
message. This just demonstrates
a different communication
technique. */
* the LCD - in this case the
* pointer to the string to print
* is sent directly in the
* lMessageValue member of the
* message. This just demonstrates
* a different communication
* technique. */
sprintf( cBuffer, "%s", ( char * ) xReceivedMessage.lMessageValue );
break;
case mainMESSAGE_STATUS : /* The tick interrupt hook
function has just informed this
task of the system status.
Generate a string in accordance
with the status value. */
case mainMESSAGE_STATUS: /* The tick interrupt hook
* function has just informed this
* task of the system status.
* Generate a string in accordance
* with the status value. */
prvGenerateStatusMessage( cBuffer, xReceivedMessage.lMessageValue );
break;
default : sprintf( cBuffer, "Unknown message" );
default:
sprintf( cBuffer, "Unknown message" );
break;
}
/* Output the message that was placed into the cBuffer array within the
switch statement above. */
* switch statement above. */
LCD_DisplayStringLine( lLine, ( uint8_t * ) cBuffer );
/* Move onto the next LCD line, ready for the next iteration of this
loop. */
* loop. */
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
string for output onto the LCD. */
* string for output onto the LCD. */
switch( lStatusValue )
{
case pdPASS : sprintf( pcBuffer, "Task status = PASS" );
case pdPASS:
sprintf( pcBuffer, "Task status = PASS" );
break;
case mainERROR_DYNAMIC_TASKS : sprintf( pcBuffer, "Error: Dynamic tasks" );
case mainERROR_DYNAMIC_TASKS:
sprintf( pcBuffer, "Error: Dynamic tasks" );
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;
case mainERROR_GEN_QUEUE_TEST : sprintf( pcBuffer, "Error: Gen Q test" );
case mainERROR_GEN_QUEUE_TEST:
sprintf( pcBuffer, "Error: Gen Q test" );
break;
default : sprintf( pcBuffer, "Unknown status" );
default:
sprintf( pcBuffer, "Unknown status" );
break;
}
}
@ -351,44 +365,45 @@ static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue )
void EXTI9_5_IRQHandler( void )
{
/* Define the message sent to the LCD task from this interrupt. */
const xQueueMessage xMessage = { mainMESSAGE_BUTTON_SEL, ( unsigned long ) "Select Interrupt!" };
long lHigherPriorityTaskWoken = pdFALSE;
const xQueueMessage xMessage = { mainMESSAGE_BUTTON_SEL, ( unsigned long ) "Select Interrupt!" };
long lHigherPriorityTaskWoken = pdFALSE;
/* 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 );
EXTI_ClearITPendingBit( SEL_BUTTON_EXTI_LINE );
/* 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,
then lHigherPriorityTaskWoken will have been set to pdTRUE internally within
xQueuesendFromISR(), and portEND_SWITCHING_ISR() will ensure that this
interrupt returns directly to the higher priority unblocked task. */
* has a priority equal to or above the task that this interrupt interrupted,
* then lHigherPriorityTaskWoken will have been set to pdTRUE internally within
* xQueuesendFromISR(), and portEND_SWITCHING_ISR() will ensure that this
* interrupt returns directly to the higher priority unblocked task. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
static unsigned long ulCounter = 0;
static const unsigned long ulCheckFrequency = 5000UL / portTICK_PERIOD_MS;
long lHigherPriorityTaskWoken = pdFALSE;
static unsigned long ulCounter = 0;
static const unsigned long ulCheckFrequency = 5000UL / portTICK_PERIOD_MS;
long lHigherPriorityTaskWoken = pdFALSE;
/* Define the status message that is sent to the LCD task. By default the
status is PASS. */
static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };
* status is PASS. */
static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };
/* This is called from within the tick interrupt and performs the 'check'
functionality as described in the comments at the top of this file.
Is it time to perform the 'check' functionality again? */
* functionality as described in the comments at the top of this file.
*
* Is it time to perform the 'check' functionality again? */
ulCounter++;
if( ulCounter >= ulCheckFrequency )
{
/* 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
any tasks set reports an error. */
* the message that is sent to the LCD task from PASS to an error code if
* any tasks set reports an error. */
if( xAreDynamicPriorityTasksStillRunning() != pdPASS )
{
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
needed (a context switch is going to be performed anyway), but it must
still be provided. */
* needed (a context switch is going to be performed anyway), but it must
* still be provided. */
xQueueSendFromISR( xLCDQueue, &xStatusMessage, &lHigherPriorityTaskWoken );
ulCounter = 0;
}
}
/*-----------------------------------------------------------*/
static void prvButtonPollTask( void *pvParameters )
static void prvButtonPollTask( void * pvParameters )
{
long lLastState = pdTRUE;
long lState;
xQueueMessage xMessage;
long lLastState = pdTRUE;
long lState;
xQueueMessage xMessage;
/* This tasks performs the button polling functionality as described at the
top of this file. */
for( ;; )
* top of this file. */
for( ; ; )
{
/* Check the button state. */
lState = STM_EVAL_PBGetState( BUTTON_UP );
if( lState != lLastState )
{
/* 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
time and debouncing of the button is not necessary. */
* time and debouncing of the button is not necessary. */
vTaskDelay( 10 / portTICK_PERIOD_MS );
}
}
@ -444,7 +460,7 @@ xQueueMessage xMessage;
static void prvSetupHardware( void )
{
/* Ensure that all 4 interrupt priority bits are used as the pre-emption
priority. */
* priority. */
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
/* Initialise the LEDs. */
@ -457,11 +473,11 @@ static void prvSetupHardware( void )
STM_EVAL_PBInit( BUTTON_RIGHT, BUTTON_MODE_GPIO );
/* The select button in the middle of the joystick is configured to generate
an interrupt. The Eval board library will configure the interrupt
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
below that set by the configMAX_SYSCALL_INTERRUPT_PRIORITY value set in
FreeRTOSConfig.h. */
* an interrupt. The Eval board library will configure the interrupt
* 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
* below that set by the configMAX_SYSCALL_INTERRUPT_PRIORITY value set in
* FreeRTOSConfig.h. */
STM_EVAL_PBInit( BUTTON_SEL, BUTTON_MODE_EXTI );
/* Initialize the LCD */
@ -475,26 +491,26 @@ static void prvSetupHardware( void )
void vConfigureTimerForRunTimeStats( void )
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* 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, 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 the current TIM6 counter value. Care
must be taken with data consistency when combining the two in case a timer
overflow occurs as the value is being read.
The portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro (in FreeRTOSConfig.h) is
defined to call this function, so the kernel will call this function
automatically at the appropriate time. */
* 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 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 consistency when combining the two in case a timer
* overflow occurs as the value is being read.
*
* The portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro (in FreeRTOSConfig.h) is
* defined to call this function, so the kernel will call this function
* automatically at the appropriate time. */
/* TIM6 clock enable */
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM6, ENABLE );
/* 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_Prescaler = 5000;
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_IRQChannelSubPriority = 0x00; /* Not used as 4 bits are used for the pre-emption priority. */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_Init( &NVIC_InitStructure );
TIM_ClearITPendingBit( TIM6, TIM_IT_Update );
TIM_Cmd( TIM6, ENABLE );
@ -523,15 +539,15 @@ NVIC_InitTypeDef NVIC_InitStructure;
void TIM6_IRQHandler( void )
{
/* Interrupt handler for TIM 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, 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 the current TIM6 counter value. Care
must be taken with data consistency when combining the two in case a timer
overflow occurs as the value is being read. */
if( TIM_GetITStatus( TIM6, TIM_IT_Update) != RESET)
*
* 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, 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 the current TIM6 counter value. Care
* must be taken with data consistency when combining the two in case a timer
* overflow occurs as the value is being read. */
if( TIM_GetITStatus( TIM6, TIM_IT_Update ) != RESET )
{
ulTIM6_OverflowCount++;
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 ) pxTask;
/* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
for( ;; );
* configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues or
semaphores. */
for( ;; );
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues or
* semaphores. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* 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 );
}

View file

@ -76,11 +76,11 @@
/*-----------------------------------------------------------*/
/* 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 )
/* 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 )
/* 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
* file.
*/
static void prvCheckTask( void *pvParameters );
static void prvCheckTask( void * pvParameters );
/*
* Implement the 'Reg test' functionality as described at the top of this file.
*/
static void vRegTest1Task( void *pvParameters );
static void vRegTest2Task( void *pvParameters );
static void vRegTest1Task( void * pvParameters );
static void vRegTest2Task( void * pvParameters );
/*-----------------------------------------------------------*/
@ -127,11 +127,11 @@ static volatile unsigned long ulRegTest1Counter = 0x11111111, ulRegTest2Counter
int main( void )
{
extern void vBasicWEBServer( void *pv );
extern void vBasicWEBServer( void * pv );
/* Setup the hardware ready for this demo. */
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. */
vStartLEDFlashTasks( tskIDLE_PRIORITY );
@ -150,33 +150,33 @@ extern void vBasicWEBServer( void *pv );
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
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. */
* 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. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle
task. */
for( ;; )
* task. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvCheckTask( void *pvParameters )
static void prvCheckTask( void * pvParameters )
{
unsigned ulTicksToWait = mainNO_ERROR_PERIOD, ulError = 0, ulLastRegTest1Count = 0, ulLastRegTest2Count = 0;
TickType_t xLastExecutionTime;
unsigned ulTicksToWait = mainNO_ERROR_PERIOD, ulError = 0, ulLastRegTest1Count = 0, ulLastRegTest2Count = 0;
TickType_t xLastExecutionTime;
( void ) pvParameters;
/* Initialise the variable used to control our iteration rate prior to
its first use. */
* its first use. */
xLastExecutionTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Wait until it is time to run the tests again. */
vTaskDelayUntil( &xLastExecutionTime, ulTicksToWait );
@ -231,7 +231,7 @@ TickType_t xLastExecutionTime;
ulLastRegTest2Count = ulRegTest2Counter;
/* 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 )
{
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
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
it will increase the context switch time. */
* 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
* it will increase the context switch time. */
( void ) pxTask;
( void ) pcTaskName;
for( ;; )
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void vRegTest1Task( void *pvParameters )
static void vRegTest1Task( void * pvParameters )
{
/* Sanity check - did we receive the parameter expected? */
if( pvParameters != &ulRegTest1Counter )
{
/* 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
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
task to recognise the error. */
* 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
* task to recognise the error. */
asm volatile ( "reg_test_1_start: \n\t"
" moveq #1, d0 \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? */
if( pvParameters != &ulRegTest2Counter )
{
/* 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
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
task to recognise the error. */
* 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
* task to recognise the error. */
asm volatile ( "reg_test_2_start: \n\t"
" moveq #10, d0 \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 )
/* 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 mainERROR_FLASH_PERIOD ( ( TickType_t ) 250 )
@ -112,8 +112,8 @@ an error has been detected. */
#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
an LED. There are only 8 LEDs (excluding the on board LED) wired in and these
are all used by the flash tasks. */
* an LED. There are only 8 LEDs (excluding the on board LED) wired in and these
* are all used by the flash tasks. */
#define mainCOM_TEST_LED ( 200 )
/* 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 )
/* 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 )
/* 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
as it is accessed from vErrorChecks(), which has a higher priority. */
* main. c has detected an error. A critical region is used around xLatchError
* as it is accessed from vErrorChecks(), which has a higher priority. */
#define mainLATCH_ERROR() \
{ \
{ \
portENTER_CRITICAL(); \
xLatchedError = pdTRUE; \
portEXIT_CRITICAL(); \
}
}
/*
* 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.
*/
static void vErrorChecks( void *pvParameters );
static void vErrorChecks( void * pvParameters );
/*
* 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.
*/
static void vFLOPCheck1( void *pvParameters );
static void vFLOPCheck1( void * pvParameters );
/*
* 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
tasks. */
* tasks. */
static portBASE_TYPE xLatchedError = pdFALSE;
/*-----------------------------------------------------------*/
@ -184,11 +184,11 @@ static portBASE_TYPE xLatchedError = pdFALSE;
void main( void )
{
/* Initialise the hardware including the system clock and on board
LED. */
* LED. */
prvSetupHardware();
/* Initialise the port that controls the external LED's utilized by the
flash tasks. */
* flash tasks. */
vParTestInitialise();
/* Start the used standard demo tasks. */
@ -199,7 +199,7 @@ void main( void )
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
/* 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
{
xTaskCreate( vRegisterCheck, "RegChck", configMINIMAL_STACK_SIZE, mainDUMMY_POINTER, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL );
@ -214,7 +214,7 @@ void main( void )
vTaskStartScheduler();
/* 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 )
{
unsigned char ucOriginalSFRPage;
unsigned char ucOriginalSFRPage;
/* Remember the SFR page before it is changed so it can get set back
before the function exits. */
* before the function exits. */
ucOriginalSFRPage = SFRPAGE;
/* Setup the SFR page to access the config SFR's. */
SFRPAGE = CONFIG_PAGE;
/* 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;
/* Disable the watchdog. */
@ -246,7 +246,7 @@ unsigned char ucOriginalSFRPage;
P1MDOUT |= mainPORT_1_BIT_6;
/* 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;
P0MDOUT |= mainCOMS_LINES_TO_PUSH_PULL;
@ -263,9 +263,9 @@ unsigned char ucOriginalSFRPage;
static void prvSetupSystemClock( void )
{
volatile unsigned short usWait;
const unsigned short usWaitTime = ( unsigned short ) 0x2ff;
unsigned char ucOriginalSFRPage;
volatile unsigned short usWait;
const unsigned short usWaitTime = ( unsigned short ) 0x2ff;
unsigned char ucOriginalSFRPage;
/* Remember the SFR page so we can set it back at the end. */
ucOriginalSFRPage = SFRPAGE;
@ -275,7 +275,9 @@ unsigned char ucOriginalSFRPage;
OSCICN = mainSELECT_INTERNAL_OSC | mainDIVIDE_CLOCK_BY_1;
/* Ensure the clock is stable. */
for( usWait = 0; usWait < usWaitTime; usWait++ );
for( usWait = 0; usWait < usWaitTime; usWait++ )
{
}
/* Setup the clock source for the PLL. */
PLL0CN &= ~mainPLL_USES_INTERNAL_OSC;
@ -296,10 +298,13 @@ unsigned char ucOriginalSFRPage;
PLL0MUL = mainPLL_MULTIPLICATION;
/* 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. */
PLL0CN |= mainENABLE_PLL;
for( usWait = 0; usWait < usWaitTime; usWait++ )
{
if( PLL0CN & mainPLL_LOCKED )
@ -333,34 +338,32 @@ static void prvToggleOnBoardLED( void )
/*
* 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. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The delay period depends on whether an error
has ever been detected. */
for( ;; )
* operating without error. The delay period depends on whether an error
* has ever been detected. */
for( ; ; )
{
if( xLatchedError == pdFALSE )
{
/* 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 );
}
else
{
/* We have at some time recognised an error in one of the demo
application tasks, delay for a shorter period. The on board LED
will get toggled every mainERROR_FLASH_PERIOD ms. */
* application tasks, delay for a shorter period. The on board LED
* will get toggled every mainERROR_FLASH_PERIOD ms. */
vTaskDelay( mainERROR_FLASH_PERIOD );
}
/* Check the demo application tasks for errors. */
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
increase. */
* increase. */
if( xErrorHasOccurred == pdTRUE )
{
xLatchedError = pdTRUE;
}
/* Toggle the LED to indicate the completion of a check cycle. The
frequency of check cycles is dependent on whether or not we have
latched an error. */
* frequency of check cycles is dependent on whether or not we have
* latched an error. */
prvToggleOnBoardLED();
}
}
@ -402,25 +405,27 @@ portBASE_TYPE xErrorHasOccurred = pdFALSE;
* See the documentation at the top of this file. Also see the standard FLOP
* 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;
for( ;; )
for( ; ; )
{
fVal1 = ( portFLOAT ) -1234.5678;
fVal1 = ( portFLOAT ) - 1234.5678;
fVal2 = ( portFLOAT ) 2345.6789;
fResult = fVal1 + fVal2;
if( ( fResult > ( portFLOAT ) 1111.15 ) || ( fResult < ( portFLOAT ) 1111.05 ) )
{
mainLATCH_ERROR();
}
fResult = fVal1 / fVal2;
if( ( fResult > ( portFLOAT ) -0.51 ) || ( fResult < ( portFLOAT ) -0.53 ) )
if( ( fResult > ( portFLOAT ) - 0.51 ) || ( fResult < ( portFLOAT ) - 0.53 ) )
{
mainLATCH_ERROR();
}
@ -431,24 +436,26 @@ volatile portFLOAT fVal1, fVal2, fResult;
/*
* 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;
for( ;; )
for( ; ; )
{
fVal1 = ( portFLOAT ) -12340.5678;
fVal1 = ( portFLOAT ) - 12340.5678;
fVal2 = ( portFLOAT ) 23450.6789;
fResult = fVal1 + fVal2;
if( ( fResult > ( portFLOAT ) 11110.15 ) || ( fResult < ( portFLOAT ) 11110.05 ) )
{
mainLATCH_ERROR();
}
fResult = fVal1 / -fVal2;
if( ( fResult > ( portFLOAT ) 0.53 ) || ( fResult < ( portFLOAT ) 0.51 ) )
{
mainLATCH_ERROR();
@ -460,11 +467,11 @@ volatile portFLOAT fVal1, fVal2, fResult;
/*
* See the documentation at the top of this file.
*/
static void vRegisterCheck( void *pvParameters )
static void vRegisterCheck( void * pvParameters )
{
( void ) pvParameters;
for( ;; )
for( ; ; )
{
if( SP != configSTACK_START )
{
@ -488,6 +495,7 @@ static void vRegisterCheck( void *pvParameters )
{
mainLATCH_ERROR();
}
_asm
MOV ACC, ar2
_endasm;
@ -496,6 +504,7 @@ static void vRegisterCheck( void *pvParameters )
{
mainLATCH_ERROR();
}
_asm
MOV ACC, ar3
_endasm;
@ -504,6 +513,7 @@ static void vRegisterCheck( void *pvParameters )
{
mainLATCH_ERROR();
}
_asm
MOV ACC, ar4
_endasm;
@ -512,6 +522,7 @@ static void vRegisterCheck( void *pvParameters )
{
mainLATCH_ERROR();
}
_asm
MOV ACC, ar5
_endasm;
@ -520,6 +531,7 @@ static void vRegisterCheck( void *pvParameters )
{
mainLATCH_ERROR();
}
_asm
MOV ACC, ar6
_endasm;
@ -528,6 +540,7 @@ static void vRegisterCheck( void *pvParameters )
{
mainLATCH_ERROR();
}
_asm
MOV ACC, ar7
_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
toggling. Now if an error occurs the check task enters an infinite loop,
toggling the LED rapidly.
Changes from V1.2.3
+ toggling. Now if an error occurs the check task enters an infinite loop,
+ toggling the LED rapidly.
+
+ Changes from V1.2.3
+
+ The integer and comtest tasks are now used when the cooperative scheduler
is being used. Previously they were only used with the preemptive
scheduler.
Changes from V1.2.5
+ is being used. Previously they were only used with the preemptive
+ scheduler.
+
+ Changes from V1.2.5
+
+ 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
TickType_t rather than unsigned long.
*/
+ TickType_t rather than unsigned long.
*/
#include <stdlib.h>
#include <conio.h>
@ -113,14 +113,14 @@ Changes from V2.0.0
#define mainLED_REG ( ( unsigned short ) 0xff7a )
/* 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 )
/* 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
the top of the file. */
* the top of the file. */
static void prvCheckOtherTasksAreStillRunning( void );
/* 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 );
/* Key presses can be used to start/stop the trace visualisation utility or stop
the scheduler. */
* the scheduler. */
static void prvCheckForKeyPresses( void );
/* 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 );
/* 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 );
/* Set the scheduler running. This function will not return unless a task
calls vTaskEndScheduler(). */
* calls vTaskEndScheduler(). */
vTaskStartScheduler();
return 1;
}
/*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters )
static void vErrorChecks( void * pvParameters )
{
TickType_t xExpectedWakeTime;
const TickType_t xPrintRate = ( TickType_t ) 5000 / portTICK_PERIOD_MS;
const long lMaxAllowableTimeDifference = ( long ) 0;
TickType_t xWakeTime;
long lTimeDifference;
const char *pcReceivedMessage;
const char * const pcTaskBlockedTooLongMsg = "Print task blocked too long!\r\n";
TickType_t xExpectedWakeTime;
const TickType_t xPrintRate = ( TickType_t ) 5000 / portTICK_PERIOD_MS;
const long lMaxAllowableTimeDifference = ( long ) 0;
TickType_t xWakeTime;
long lTimeDifference;
const char * pcReceivedMessage;
const char * const pcTaskBlockedTooLongMsg = "Print task blocked too long!\r\n";
/* Stop warnings. */
( void ) pvParameters;
/* Loop continuously, blocking, then checking all the other tasks are still
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
message becoming available. */
for( ;; )
* 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
* message becoming available. */
for( ; ; )
{
/* 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 += xPrintRate;
/* Block waiting for either a time out or a message to be posted that
required displaying. */
* required displaying. */
pcReceivedMessage = pcPrintGetNextMessage( xPrintRate );
/* Was a message received? */
if( pcReceivedMessage == NULL )
{
/* A message was not received so we timed out, did we unblock at the
expected time? */
* expected time? */
xWakeTime = xTaskGetTickCount();
/* Calculate the difference between the time we unblocked and the
time we should have unblocked. */
* time we should have unblocked. */
if( xWakeTime > xExpectedWakeTime )
{
lTimeDifference = ( long ) ( xWakeTime - xExpectedWakeTime );
@ -215,7 +215,7 @@ const char * const pcTaskBlockedTooLongMsg = "Print task blocked too long!\r\n";
if( lTimeDifference > lMaxAllowableTimeDifference )
{
/* We blocked too long - create a message that will get
printed out the next time around. */
* printed out the next time around. */
vPrintDisplayMessage( &pcTaskBlockedTooLongMsg );
}
@ -225,12 +225,12 @@ const char * const pcTaskBlockedTooLongMsg = "Print task blocked too long!\r\n";
else
{
/* We unblocked due to a message becoming available. Send the message
for printing. */
* for printing. */
vDisplayMessage( pcReceivedMessage );
}
/* Key presses are used to invoke the trace visualisation utility, or
end the program. */
* end the program. */
prvCheckForKeyPresses();
}
} /*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 )
{
#ifdef USE_STDIO
short sIn;
@ -252,40 +251,42 @@ static void prvCheckForKeyPresses( void )
unsigned long ulBufferLength;
/* Key presses can be used to start/stop the trace utility, or end the
program. */
* program. */
sIn = getch();
switch( sIn )
{
/* Only define keys for turning on and off the trace if the trace
is being used. */
* is being used. */
#if configUSE_TRACE_FACILITY == 1
case 't' : vTaskList( pcWriteBuffer );
case 't':
vTaskList( pcWriteBuffer );
vWriteMessageToDisk( pcWriteBuffer );
break;
/* The legacy trace is no longer supported. Use FreeRTOS+Trace instead.
case 's' : vTaskStartTrace( pcWriteBuffer, mainDEBUG_LOG_BUFFER_SIZE );
break;
case 'e' : ulBufferLength = ulTaskEndTrace();
vWriteBufferToDisk( pcWriteBuffer, ulBufferLength );
break;*/
* case 's' : vTaskStartTrace( pcWriteBuffer, mainDEBUG_LOG_BUFFER_SIZE );
* break;
*
* case 'e' : ulBufferLength = ulTaskEndTrace();
* vWriteBufferToDisk( pcWriteBuffer, ulBufferLength );
* break;*/
#endif
default : vTaskEndScheduler();
default:
vTaskEndScheduler();
break;
}
}
#else
#else /* ifdef USE_STDIO */
( void ) pcWriteBuffer;
#endif
#endif /* ifdef USE_STDIO */
}
/*-----------------------------------------------------------*/
static void prvCheckOtherTasksAreStillRunning( void )
{
short sErrorHasOccurred = pdFALSE;
short sErrorHasOccurred = pdFALSE;
if( xAreComTestTasksStillRunning() != pdTRUE )
{
@ -326,16 +327,17 @@ short sErrorHasOccurred = pdFALSE;
if( sErrorHasOccurred == pdFALSE )
{
vDisplayMessage( "OK " );
/* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */
* using console IO. */
prvToggleLED();
}
else
{
for( ;; )
for( ; ; )
{
/* 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();
vTaskDelay( mainERROR_FLASH_RATE );
}
@ -345,8 +347,8 @@ short sErrorHasOccurred = pdFALSE;
static void prvInitLED( void )
{
unsigned short usPortDirection;
const unsigned short usLEDOut = 0x400;
unsigned short usPortDirection;
const unsigned short usLEDOut = 0x400;
/* Set the LED bit to an output. */
@ -358,12 +360,13 @@ const unsigned short usLEDOut = 0x400;
static void prvToggleLED( void )
{
static short sLED = pdTRUE;
unsigned short usLEDState;
const unsigned short usLEDBit = 0x400;
static short sLED = pdTRUE;
unsigned short usLEDState;
const unsigned short usLEDBit = 0x400;
/* Flip the state of the LED. */
usLEDState = inpw( mainLED_REG );
if( sLED )
{
usLEDState &= ~usLEDBit;
@ -372,9 +375,8 @@ const unsigned short usLEDBit = 0x400;
{
usLEDState |= usLEDBit;
}
outpw( mainLED_REG, usLEDState );
sLED = !sLED;
}

View file

@ -1,4 +1,3 @@
/*
* FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
@ -69,8 +68,8 @@
/*-----------------------------------------------------------
Definitions.
-----------------------------------------------------------*/
* Definitions.
* -----------------------------------------------------------*/
/* Priorities assigned to demo application tasks. */
#define mainFLASH_PRIORITY ( tskIDLE_PRIORITY + 2 )
@ -81,9 +80,9 @@
#define mainDEATH_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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
the LED is toggled with mainCHECK_PERIOD frequency. If an error is found
then the toggle rate increases to mainERROR_CHECK_PERIOD. */
* 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
* then the toggle rate increases to mainERROR_CHECK_PERIOD. */
#define mainCHECK_TASK_LED ( 7 )
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / 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).
IMPORTANT: The function COM0_SetBaudRateValue() which is generated by the
Processor Expert is used to set the baud rate. As configured in the FreeRTOS
download this value must be one of the following:
0 to configure for 38400 baud.
1 to configure for 19200 baud.
2 to configure for 9600 baud.
3 to configure for 4800 baud. */
* IMPORTANT: The function COM0_SetBaudRateValue() which is generated by the
* Processor Expert is used to set the baud rate. As configured in the FreeRTOS
* download this value must be one of the following:
*
* 0 to configure for 38400 baud.
* 1 to configure for 19200 baud.
* 2 to configure for 9600 baud.
* 3 to configure for 4800 baud. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 2 )
/* 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 )
/*-----------------------------------------------------------
Local functions prototypes.
-----------------------------------------------------------*/
* Local functions prototypes.
* -----------------------------------------------------------*/
/*
* 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
@ -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
their status. If an error is detected in one of the locally defined tasks then
this flag is set to pdTRUE. */
* their status. If an error is detected in one of the locally defined tasks then
* this flag is set to pdTRUE. */
portBASE_TYPE xLocalError = pdFALSE;
@ -159,7 +158,7 @@ void vMain( void )
vStartIntegerMathTasks( tskIDLE_PRIORITY );
/* 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 );
/* Must be the last demo created. */
@ -169,29 +168,31 @@ void vMain( void )
vTaskStartScheduler();
/* Should not reach here! */
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters )
static void vErrorChecks( void * pvParameters )
{
TickType_t xDelayPeriod = mainCHECK_PERIOD;
TickType_t xLastWakeTime;
TickType_t xDelayPeriod = mainCHECK_PERIOD;
TickType_t xLastWakeTime;
/* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil()
functions correctly. */
* functions correctly. */
xLastWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Delay until it is time to execute again. The delay period is
shorter following an error. */
* shorter following an error. */
vTaskDelayUntil( &xLastWakeTime, xDelayPeriod );
/* Check all the demo application tasks are executing without
error. If an error is found the delay period is shortened - this
has the effect of increasing the flash rate of the 'check' task
LED. */
* error. If an error is found the delay period is shortened - this
* has the effect of increasing the flash rate of the 'check' task
* LED. */
if( prvCheckOtherTasksAreStillRunning() == pdFAIL )
{
/* An error has been detected in one of the tasks - flash faster. */
@ -206,7 +207,7 @@ TickType_t xLastWakeTime;
static long prvCheckOtherTasksAreStillRunning( void )
{
portBASE_TYPE xAllTasksPassed = pdPASS;
portBASE_TYPE xAllTasksPassed = pdPASS;
if( xArePollingQueuesStillRunning() != pdTRUE )
{
@ -251,13 +252,13 @@ portBASE_TYPE xAllTasksPassed = pdPASS;
void vApplicationIdleHook( void )
{
/* This variable is effectively set to a constant so it is made volatile to
ensure the compiler does not just get rid of it. */
volatile long lValue;
* ensure the compiler does not just get rid of it. */
volatile long lValue;
/* Keep performing a calculation and checking the result against a constant. */
/* 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 += intgCONST2;
lValue *= intgCONST3;
@ -280,6 +281,3 @@ volatile long lValue;
#endif
}
/*-----------------------------------------------------------*/

View file

@ -98,8 +98,8 @@
#include "ButtonInterrupt.h"
/*-----------------------------------------------------------
Definitions.
-----------------------------------------------------------*/
* Definitions.
* -----------------------------------------------------------*/
/* Priorities assigned to demo application tasks. */
#define mainFLASH_PRIORITY ( tskIDLE_PRIORITY + 2 )
@ -108,9 +108,9 @@
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* 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
the LED is toggled with mainCHECK_PERIOD frequency. If an error is found
then the toggle rate increases to mainERROR_CHECK_PERIOD. */
* 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
* then the toggle rate increases to mainERROR_CHECK_PERIOD. */
#define mainCHECK_TASK_LED ( 7 )
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / 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 )
/* 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
/*-----------------------------------------------------------
Local functions prototypes.
-----------------------------------------------------------*/
* Local functions prototypes.
* -----------------------------------------------------------*/
/*
* 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.
*/
static void vButtonTask( void *pvParameters );
static void vButtonTask( void * pvParameters );
/*
* 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
their status. If an error is detected in one of the locally defined tasks then
this flag is set to pdTRUE. */
* their status. If an error is detected in one of the locally defined tasks then
* this flag is set to pdTRUE. */
portBASE_TYPE xLocalError = pdFALSE;
/* The queue used to send data from the button push ISR to the Button Push
task. */
* task. */
static QueueHandle_t xButtonQueue;
@ -183,7 +183,7 @@ void vMain( void )
vStartDynamicPriorityTasks();
/* 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( vButtonTask, "Button", configMINIMAL_STACK_SIZE, NULL, mainBUTTON_TASK_PRIORITY, NULL );
@ -191,29 +191,31 @@ void vMain( void )
vTaskStartScheduler();
/* Should not reach here! */
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters )
static void vErrorChecks( void * pvParameters )
{
TickType_t xDelayPeriod = mainCHECK_PERIOD;
TickType_t xLastWakeTime;
TickType_t xDelayPeriod = mainCHECK_PERIOD;
TickType_t xLastWakeTime;
/* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil()
functions correctly. */
* functions correctly. */
xLastWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Delay until it is time to execute again. The delay period is
shorter following an error. */
* shorter following an error. */
vTaskDelayUntil( &xLastWakeTime, xDelayPeriod );
/* Check all the demo application tasks are executing without
error. If an error is found the delay period is shortened - this
has the effect of increasing the flash rate of the 'check' task
LED. */
* error. If an error is found the delay period is shortened - this
* has the effect of increasing the flash rate of the 'check' task
* LED. */
if( prvCheckOtherTasksAreStillRunning() == pdFAIL )
{
/* An error has been detected in one of the tasks - flash faster. */
@ -228,7 +230,7 @@ TickType_t xLastWakeTime;
static long prvCheckOtherTasksAreStillRunning( void )
{
portBASE_TYPE xAllTasksPassed = pdPASS;
portBASE_TYPE xAllTasksPassed = pdPASS;
if( xArePollingQueuesStillRunning() != pdTRUE )
{
@ -253,14 +255,14 @@ portBASE_TYPE xAllTasksPassed = pdPASS;
void vApplicationIdleHook( void )
{
/* This variable is effectively set to a constant so it is made volatile to
ensure the compiler does not just get rid of it. */
volatile long lValue;
* ensure the compiler does not just get rid of it. */
volatile long lValue;
/* Keep performing a calculation and checking the result against a constant. */
for( ;; )
for( ; ; )
{
/* 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 += intgCONST2;
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. */
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. */
ButtonInterrupt_Enable();
for( ;; )
for( ; ; )
{
/* Simply wait for data to arrive from the button push interrupt. */
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. */
for( ;; );
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
/* Button push ISR. */
void interrupt vButtonPush( void )
{
/* Button push ISR. */
void interrupt vButtonPush( void )
{
static unsigned portBASE_TYPE uxValToSend = 0;
static unsigned long xHigherPriorityTaskWoken;
@ -343,21 +347,19 @@ unsigned portBASE_TYPE uxExpected = 1, uxReceived;
PIFP = 1;
/* 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
it will wake and a context switch should be performed before leaving
the ISR. */
* 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
* the ISR. */
xQueueSendFromISR( xButtonQueue, &uxValToSend, &xHigherPriorityTaskWoken );
if( xHigherPriorityTaskWoken )
{
/* NOTE: This macro can only be used if there are no local
variables defined. This function uses a static variable so it's
use is permitted. If the variable were not static portYIELD()
would have to be used in it's place. */
* variables defined. This function uses a static variable so it's
* use is permitted. If the variable were not static portYIELD()
* would have to be used in it's place. */
portTASK_SWITCH_FROM_ISR();
}
}
}
#pragma CODE_SEG DEFAULT

View file

@ -1,4 +1,3 @@
/*
* FreeRTOS V202212.00
* 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. */
#define mainFLASH_PRIORITY ( tskIDLE_PRIORITY + 2 )
@ -84,9 +83,9 @@ portBASE_TYPE xArePollingQueuesStillRunning( void );
#define mainDEATH_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* 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
the LED is toggled with mainCHECK_PERIOD frequency. If an error is found
then the toggle rate increases to mainERROR_CHECK_PERIOD. */
* 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
* then the toggle rate increases to mainERROR_CHECK_PERIOD. */
#define mainCHECK_TASK_LED ( 7 )
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / 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).
IMPORTANT: The function COM0_SetBaudRateValue() which is generated by the
Processor Expert is used to set the baud rate. As configured in the FreeRTOS
download this value must be one of the following:
0 to configure for 38400 baud.
1 to configure for 19200 baud.
2 to configure for 9600 baud.
3 to configure for 4800 baud. */
* IMPORTANT: The function COM0_SetBaudRateValue() which is generated by the
* Processor Expert is used to set the baud rate. As configured in the FreeRTOS
* download this value must be one of the following:
*
* 0 to configure for 38400 baud.
* 1 to configure for 19200 baud.
* 2 to configure for 9600 baud.
* 3 to configure for 4800 baud. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 2 )
/* 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 )
/*-----------------------------------------------------------
Local functions prototypes.
-----------------------------------------------------------*/
* Local functions prototypes.
* -----------------------------------------------------------*/
/*
* 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
@ -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
their status. If an error is detected in one of the locally defined tasks then
this flag is set to pdTRUE. */
* their status. If an error is detected in one of the locally defined tasks then
* this flag is set to pdTRUE. */
portBASE_TYPE xLocalError = pdFALSE;
/*-----------------------------------------------------------*/
/* This is called from startup. */
int ATTR_BANK0 main ( void )
int ATTR_BANK0 main( void )
{
/* Start some of the standard demo tasks. */
vStartLEDFlashTasks( mainFLASH_PRIORITY );
@ -160,7 +159,7 @@ int ATTR_BANK0 main ( void )
vStartIntegerMathTasks( tskIDLE_PRIORITY );
/* 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 );
/* Must be the last demo created. */
@ -170,30 +169,33 @@ int ATTR_BANK0 main ( void )
vTaskStartScheduler();
/* Should not reach here! */
for( ;; );
for( ; ; )
{
}
return 0;
}
/*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters )
static void vErrorChecks( void * pvParameters )
{
TickType_t xDelayPeriod = mainCHECK_PERIOD;
TickType_t xLastWakeTime;
TickType_t xDelayPeriod = mainCHECK_PERIOD;
TickType_t xLastWakeTime;
/* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil()
functions correctly. */
* functions correctly. */
xLastWakeTime = xTaskGetTickCount();
for( ;; )
for( ; ; )
{
/* Delay until it is time to execute again. The delay period is
shorter following an error. */
* shorter following an error. */
vTaskDelayUntil( &xLastWakeTime, xDelayPeriod );
/* Check all the demo application tasks are executing without
error. If an error is found the delay period is shortened - this
has the effect of increasing the flash rate of the 'check' task
LED. */
* error. If an error is found the delay period is shortened - this
* has the effect of increasing the flash rate of the 'check' task
* LED. */
if( prvCheckOtherTasksAreStillRunning() == pdFAIL )
{
/* An error has been detected in one of the tasks - flash faster. */
@ -208,7 +210,7 @@ TickType_t xLastWakeTime;
static long prvCheckOtherTasksAreStillRunning( void )
{
portBASE_TYPE xAllTasksPassed = pdPASS;
portBASE_TYPE xAllTasksPassed = pdPASS;
if( xArePollingQueuesStillRunning() != pdTRUE )
{
@ -253,13 +255,13 @@ portBASE_TYPE xAllTasksPassed = pdPASS;
void vApplicationIdleHook( void )
{
/* This variable is effectively set to a constant so it is made volatile to
ensure the compiler does not just get rid of it. */
volatile long lValue;
* ensure the compiler does not just get rid of it. */
volatile long lValue;
/* Keep performing a calculation and checking the result against a constant. */
/* 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 += intgCONST2;
lValue *= intgCONST3;
@ -282,4 +284,3 @@ volatile long lValue;
#endif
}
/*-----------------------------------------------------------*/

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