Fix formatting in kernel demo application files (#1148)

* Fix formatting in kernel demo application files

* Fix header check fail in the demo files

* Add ignored patterns in core header check file

* Fix formatting

* Update vApplicationStackOverflowHook for AVR_ATMega4809_MPLAB.X/main.c

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

* Update vApplicationStackOverflowHook for AVR_ATMega4809_MPLAB.X/main.c

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

* Update vApplicationStackOverflowHook for AVR_Dx_IAR/main.c

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

* Update vApplicationStackOverflowHook for AVR_Dx_IAR/main.c

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

* Update vApplicationStackOverflowHook for AVR_Dx_MPLAB.X/main.c

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

* Update vApplicationMallocFailedHook for AVR_Dx_MPLAB.X/main.c

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

* Fix formatting AVR32_UC3

---------

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

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -25,12 +25,12 @@
*/ */
/* /*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used. * these demo application projects then ensure Supervisor mode is used.
*/ */
/* /*
@ -84,44 +84,44 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Constants for the ComTest tasks. */ /* Constants for the ComTest tasks. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 )
#define mainCOM_TEST_LED ( 5 ) #define mainCOM_TEST_LED ( 5 )
/* Priorities for the demo application tasks. */ /* Priorities for the demo application tasks. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* The rate at which the on board LED will toggle when there is/is not an /* The rate at which the on board LED will toggle when there is/is not an
error. */ * error. */
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
#define mainON_BOARD_LED_BIT ( ( unsigned long ) 7 ) #define mainON_BOARD_LED_BIT ( ( unsigned long ) 7 )
/* Constants used by the vMemCheckTask() task. */ /* Constants used by the vMemCheckTask() task. */
#define mainCOUNT_INITIAL_VALUE ( ( unsigned long ) 0 ) #define mainCOUNT_INITIAL_VALUE ( ( unsigned long ) 0 )
#define mainNO_TASK ( 0 ) #define mainNO_TASK ( 0 )
/* The size of the memory blocks allocated by the vMemCheckTask() task. */ /* The size of the memory blocks allocated by the vMemCheckTask() task. */
#define mainMEM_CHECK_SIZE_1 ( ( size_t ) 51 ) #define mainMEM_CHECK_SIZE_1 ( ( size_t ) 51 )
#define mainMEM_CHECK_SIZE_2 ( ( size_t ) 52 ) #define mainMEM_CHECK_SIZE_2 ( ( size_t ) 52 )
#define mainMEM_CHECK_SIZE_3 ( ( size_t ) 151 ) #define mainMEM_CHECK_SIZE_3 ( ( size_t ) 151 )
#define MAX_WAIT_STATES 8 #define MAX_WAIT_STATES 8
static const unsigned long ululCSRWaitValues[ MAX_WAIT_STATES + 1 ] = static const unsigned long ululCSRWaitValues[ MAX_WAIT_STATES + 1 ] =
{ {
WaitState1,/* There is no "zero wait state" value, so use one wait state */ WaitState1, /* There is no "zero wait state" value, so use one wait state */
WaitState1, WaitState1,
WaitState2, WaitState2,
WaitState3, WaitState3,
WaitState4, WaitState4,
WaitState5, WaitState5,
WaitState6, WaitState6,
WaitState7, WaitState7,
WaitState8 WaitState8
}; };
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -136,14 +136,14 @@ static long prvCheckOtherTasksAreStillRunning( unsigned long ulMemCheckTaskCount
* prvCheckOtherTasksAreStillRunning(). See the description at the top * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Dynamically created and deleted during each cycle of the vErrorChecks() * Dynamically created and deleted during each cycle of the vErrorChecks()
* task. This is done to check the operation of the memory allocator. * task. This is done to check the operation of the memory allocator.
* See the top of vErrorChecks for more details. * See the top of vErrorChecks for more details.
*/ */
static void vMemCheckTask( void *pvParameters ); static void vMemCheckTask( void * pvParameters );
/* /*
* Configure the processor for use with the Olimex demo board. This includes * Configure the processor for use with the Olimex demo board. This includes
@ -158,309 +158,312 @@ static void prvSetupHardware( void );
*/ */
int main( void ) int main( void )
{ {
/* Setup the hardware for use with the Olimex demo board. */ /* Setup the hardware for use with the Olimex demo board. */
prvSetupHardware(); prvSetupHardware();
/* Start the demo/test application tasks. */ /* Start the demo/test application tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartLEDFlashTasks( mainLED_TASK_PRIORITY ); vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartMathTasks( tskIDLE_PRIORITY ); vStartMathTasks( tskIDLE_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
/* Start the check task - which is defined in this file. */ /* Start the check task - which is defined in this file. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Now all the tasks have been started - start the scheduler. /* Now all the tasks have been started - start the scheduler.
*
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* 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();
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. /* Should never reach here! */
The processor MUST be in supervisor mode when vTaskStartScheduler is return 0;
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! */
return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
unsigned long ulMemCheckTaskRunningCount; unsigned long ulMemCheckTaskRunningCount;
TaskHandle_t xCreatedTask; TaskHandle_t xCreatedTask;
/* Just to stop compiler warnings. */ /* Just to stop compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period * operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so * is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. * the on board LED flash rate will increase.
*
* In addition to the standard tests the memory allocator is tested through
* the dynamic creation and deletion of a task each cycle. Each time the
* task is created memory must be allocated for its stack. When the task is
* deleted this memory is returned to the heap. If the task cannot be created
* then it is likely that the memory allocation failed. */
In addition to the standard tests the memory allocator is tested through for( ; ; )
the dynamic creation and deletion of a task each cycle. Each time the {
task is created memory must be allocated for its stack. When the task is /* Reset xCreatedTask. This is modified by the task about to be
deleted this memory is returned to the heap. If the task cannot be created * created so we can tell if it is executing correctly or not. */
then it is likely that the memory allocation failed. */ xCreatedTask = mainNO_TASK;
for( ;; ) /* Dynamically create a task - passing ulMemCheckTaskRunningCount as a
{ * parameter. */
/* Reset xCreatedTask. This is modified by the task about to be ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;
created so we can tell if it is executing correctly or not. */
xCreatedTask = mainNO_TASK;
/* Dynamically create a task - passing ulMemCheckTaskRunningCount as a if( xTaskCreate( vMemCheckTask, "MEM_CHECK", configMINIMAL_STACK_SIZE, ( void * ) &ulMemCheckTaskRunningCount, tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )
parameter. */ {
ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE; /* Could not create the task - we have probably run out of heap. */
if( xTaskCreate( vMemCheckTask, "MEM_CHECK", configMINIMAL_STACK_SIZE, ( void * ) &ulMemCheckTaskRunningCount, tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS ) xDelayPeriod = mainERROR_FLASH_PERIOD;
{ }
/* Could not create the task - we have probably run out of heap. */
xDelayPeriod = mainERROR_FLASH_PERIOD;
}
/* Delay until it is time to execute again. */ /* Delay until it is time to execute again. */
vTaskDelay( xDelayPeriod ); vTaskDelay( xDelayPeriod );
/* Delete the dynamically created task. */ /* Delete the dynamically created task. */
if( xCreatedTask != mainNO_TASK ) if( xCreatedTask != mainNO_TASK )
{ {
vTaskDelete( xCreatedTask ); vTaskDelete( xCreatedTask );
} }
/* Check all the standard demo application tasks are executing without /* Check all the standard demo application tasks are executing without
error. ulMemCheckTaskRunningCount is checked to ensure it was * error. ulMemCheckTaskRunningCount is checked to ensure it was
modified by the task just deleted. */ * modified by the task just deleted. */
if( prvCheckOtherTasksAreStillRunning( ulMemCheckTaskRunningCount ) != pdPASS ) if( prvCheckOtherTasksAreStillRunning( ulMemCheckTaskRunningCount ) != pdPASS )
{ {
/* An error has been detected in one of the tasks - flash faster. */ /* An error has been detected in one of the tasks - flash faster. */
xDelayPeriod = mainERROR_FLASH_PERIOD; xDelayPeriod = mainERROR_FLASH_PERIOD;
} }
/* The toggle rate of the LED depends on how long this task delays for. /* The toggle rate of the LED depends on how long this task delays for.
An error reduces the delay period and so increases the toggle rate. */ * An error reduces the delay period and so increases the toggle rate. */
vParTestToggleLED( mainON_BOARD_LED_BIT ); vParTestToggleLED( mainON_BOARD_LED_BIT );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
long lCount; long lCount;
#ifdef RUN_FROM_ROM #ifdef RUN_FROM_ROM
{ {
portFLOAT nsecsPerClockTick; portFLOAT nsecsPerClockTick;
long lNumWaitStates; long lNumWaitStates;
unsigned long ulCSRWaitValue; unsigned long ulCSRWaitValue;
/* We are compiling to run from ROM (either on-chip or off-chip flash). /* We are compiling to run from ROM (either on-chip or off-chip flash).
Leave the RAM/flash mapped the way they are on reset * Leave the RAM/flash mapped the way they are on reset
(flash @ 0x00000000, RAM @ 0x00300000), and set up the * (flash @ 0x00000000, RAM @ 0x00300000), and set up the
proper flash wait states (starts out at the maximum number * proper flash wait states (starts out at the maximum number
of wait states on reset, so we should be able to reduce it). * of wait states on reset, so we should be able to reduce it).
Most of this code will probably get removed by the compiler * Most of this code will probably get removed by the compiler
if optimization is enabled, since these calculations are * if optimization is enabled, since these calculations are
based on constants. But the compiler should still produce * based on constants. But the compiler should still produce
a correct wait state register value. */ * a correct wait state register value. */
nsecsPerClockTick = ( portFLOAT ) 1000000000 / configCPU_CLOCK_HZ; nsecsPerClockTick = ( portFLOAT ) 1000000000 / configCPU_CLOCK_HZ;
lNumWaitStates = ( long )( ( configFLASH_SPEED_NSEC / nsecsPerClockTick ) + 0.5 ) - 1; lNumWaitStates = ( long ) ( ( configFLASH_SPEED_NSEC / nsecsPerClockTick ) + 0.5 ) - 1;
if( lNumWaitStates < 0 ) if( lNumWaitStates < 0 )
{ {
lNumWaitStates = 0; lNumWaitStates = 0;
} }
if( lNumWaitStates > MAX_WAIT_STATES ) if( lNumWaitStates > MAX_WAIT_STATES )
{ {
lNumWaitStates = MAX_WAIT_STATES; lNumWaitStates = MAX_WAIT_STATES;
} }
ulCSRWaitValue = ululCSRWaitValues[ lNumWaitStates ]; ulCSRWaitValue = ululCSRWaitValues[ lNumWaitStates ];
ulCSRWaitValue = WaitState5; ulCSRWaitValue = WaitState5;
AT91C_BASE_EBI->EBI_CSR[ 0 ] = ulCSRWaitValue | DataBus16 | WaitStateEnable AT91C_BASE_EBI->EBI_CSR[ 0 ] = ulCSRWaitValue | DataBus16 | WaitStateEnable
| PageSize1M | tDF_0cycle | PageSize1M | tDF_0cycle
| ByteWriteAccessType | CSEnable | ByteWriteAccessType | CSEnable
| 0x00000000 /* Base Address */; | 0x00000000 /* Base Address */;
} }
#else /* else we are compiling to run from on-chip RAM */ #else /* else we are compiling to run from on-chip RAM */
{ {
/* If compiling to run from RAM, we expect the on-chip RAM to already /* If compiling to run from RAM, we expect the on-chip RAM to already
be mapped at 0x00000000. This is typically done with an initialization * be mapped at 0x00000000. This is typically done with an initialization
script for the JTAG emulator you are using to download and run the * script for the JTAG emulator you are using to download and run the
demo application. So there is nothing to do here in this case. */ * demo application. So there is nothing to do here in this case. */
} }
#endif #endif /* ifdef RUN_FROM_ROM */
/* Disable all interrupts at the AIC level initially... */ /* Disable all interrupts at the AIC level initially... */
AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF; AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;
/* Set all SVR and SMR entries to default values (start with a clean slate)... */ /* Set all SVR and SMR entries to default values (start with a clean slate)... */
for( lCount = 0; lCount < 32; lCount++ ) for( lCount = 0; lCount < 32; lCount++ )
{ {
AT91C_BASE_AIC->AIC_SVR[ lCount ] = (unsigned long) 0; AT91C_BASE_AIC->AIC_SVR[ lCount ] = ( unsigned long ) 0;
AT91C_BASE_AIC->AIC_SMR[ lCount ] = AIC_SRCTYPE_INT_EDGE_TRIGGERED; AT91C_BASE_AIC->AIC_SMR[ lCount ] = AIC_SRCTYPE_INT_EDGE_TRIGGERED;
} }
/* Disable clocks to all peripherals initially... */ /* Disable clocks to all peripherals initially... */
AT91C_BASE_PS->PS_PCDR = 0xFFFFFFFF; AT91C_BASE_PS->PS_PCDR = 0xFFFFFFFF;
/* Clear all interrupts at the AIC level initially... */ /* Clear all interrupts at the AIC level initially... */
AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF; AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF;
/* Perform 8 "End Of Interrupt" cmds to make sure AIC will not Lock out /* Perform 8 "End Of Interrupt" cmds to make sure AIC will not Lock out
nIRQ */ * nIRQ */
for( lCount = 0; lCount < 8; lCount++ ) for( lCount = 0; lCount < 8; lCount++ )
{ {
AT91C_BASE_AIC->AIC_EOICR = 0; AT91C_BASE_AIC->AIC_EOICR = 0;
} }
/* Initialise LED outputs. */ /* Initialise LED outputs. */
vParTestInitialise(); vParTestInitialise();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static long prvCheckOtherTasksAreStillRunning( unsigned long ulMemCheckTaskCount ) static long prvCheckOtherTasksAreStillRunning( unsigned long ulMemCheckTaskCount )
{ {
long lReturn = ( long ) pdPASS; long lReturn = ( long ) pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected * that they are all still running, and that none of them have detected
an error. */ * an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreComTestTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( ulMemCheckTaskCount == mainCOUNT_INITIAL_VALUE ) if( ulMemCheckTaskCount == mainCOUNT_INITIAL_VALUE )
{ {
/* The vMemCheckTask did not increment the counter - it must /* The vMemCheckTask did not increment the counter - it must
have failed. */ * have failed. */
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
return lReturn; return lReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vMemCheckTask( void *pvParameters ) static void vMemCheckTask( void * pvParameters )
{ {
unsigned long *pulMemCheckTaskRunningCounter; unsigned long * pulMemCheckTaskRunningCounter;
void *pvMem1, *pvMem2, *pvMem3; void * pvMem1, * pvMem2, * pvMem3;
static long lErrorOccurred = pdFALSE; static long lErrorOccurred = pdFALSE;
/* This task is dynamically created then deleted during each cycle of the /* This task is dynamically created then deleted during each cycle of the
vErrorChecks task to check the operation of the memory allocator. Each time * vErrorChecks task to check the operation of the memory allocator. Each time
the task is created memory is allocated for the stack and TCB. Each time * the task is created memory is allocated for the stack and TCB. Each time
the task is deleted this memory is returned to the heap. This task itself * the task is deleted this memory is returned to the heap. This task itself
exercises the allocator by allocating and freeing blocks. * exercises the allocator by allocating and freeing blocks.
*
* The task executes at the idle priority so does not require a delay.
*
* pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the
* vErrorChecks() task that this task is still executing without error. */
The task executes at the idle priority so does not require a delay. pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters;
pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the for( ; ; )
vErrorChecks() task that this task is still executing without error. */ {
if( lErrorOccurred == pdFALSE )
{
/* We have never seen an error so increment the counter. */
( *pulMemCheckTaskRunningCounter )++;
}
else
{
/* There has been an error so reset the counter so the check task
* can tell that an error occurred. */
*pulMemCheckTaskRunningCounter = mainCOUNT_INITIAL_VALUE;
}
pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters; /* 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. */
vTaskSuspendAll();
{
pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );
for( ;; ) if( pvMem1 == NULL )
{ {
if( lErrorOccurred == pdFALSE ) lErrorOccurred = pdTRUE;
{ }
/* We have never seen an error so increment the counter. */ else
( *pulMemCheckTaskRunningCounter )++; {
} memset( pvMem1, 0xaa, mainMEM_CHECK_SIZE_1 );
else vPortFree( pvMem1 );
{ }
/* There has been an error so reset the counter so the check task }
can tell that an error occurred. */ xTaskResumeAll();
*pulMemCheckTaskRunningCounter = mainCOUNT_INITIAL_VALUE;
}
/* Allocate some memory - just to give the allocator some extra /* Again - with a different size block. */
exercise. This has to be in a critical section to ensure the vTaskSuspendAll();
task does not get deleted while it has memory allocated. */ {
vTaskSuspendAll(); pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 );
{
pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );
if( pvMem1 == NULL )
{
lErrorOccurred = pdTRUE;
}
else
{
memset( pvMem1, 0xaa, mainMEM_CHECK_SIZE_1 );
vPortFree( pvMem1 );
}
}
xTaskResumeAll();
/* Again - with a different size block. */ if( pvMem2 == NULL )
vTaskSuspendAll(); {
{ lErrorOccurred = pdTRUE;
pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 ); }
if( pvMem2 == NULL ) else
{ {
lErrorOccurred = pdTRUE; memset( pvMem2, 0xaa, mainMEM_CHECK_SIZE_2 );
} vPortFree( pvMem2 );
else }
{ }
memset( pvMem2, 0xaa, mainMEM_CHECK_SIZE_2 ); xTaskResumeAll();
vPortFree( pvMem2 );
}
}
xTaskResumeAll();
/* Again - with a different size block. */ /* Again - with a different size block. */
vTaskSuspendAll(); vTaskSuspendAll();
{ {
pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 ); pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );
if( pvMem3 == NULL )
{ if( pvMem3 == NULL )
lErrorOccurred = pdTRUE; {
} lErrorOccurred = pdTRUE;
else }
{ else
memset( pvMem3, 0xaa, mainMEM_CHECK_SIZE_3 ); {
vPortFree( pvMem3 ); memset( pvMem3, 0xaa, mainMEM_CHECK_SIZE_3 );
} vPortFree( pvMem3 );
} }
xTaskResumeAll(); }
} xTaskResumeAll();
}
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -24,29 +24,29 @@
* *
*/ */
/* /*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used. * these demo application projects then ensure Supervisor mode is used.
*/ */
/* /*
* Creates all the demo application tasks, then starts the scheduler. The WEB * Creates all the demo application tasks, then starts the scheduler. The WEB
* documentation provides more details of the demo application tasks. The SAM7 * documentation provides more details of the demo application tasks. The SAM7
* includes a sample USB that emulates a Joystick input to a USB host. * includes a sample USB that emulates a Joystick input to a USB host.
* *
* Main.c also creates a task called "Check". This only executes every three * Main.c also creates a task called "Check". This only executes every three
* seconds but has the highest priority so is guaranteed to get processor time. * seconds but has the highest priority so is guaranteed to get processor time.
* Its main function is to check that all the other tasks are still operational. * Its main function is to check that all the other tasks are still operational.
* Each task (other than the "flash" tasks) maintains a unique count that is * Each task (other than the "flash" tasks) maintains a unique count that is
* incremented each time the task successfully completes its function. Should * incremented each time the task successfully completes its function. Should
* any error occur within such a task the count is permanently halted. The * any error occur within such a task the count is permanently halted. The
* check task inspects the count of each task to ensure it has changed since * check task inspects the count of each task to ensure it has changed since
* the last time the check task executed. If all the count variables have * the last time the check task executed. If all the count variables have
* changed all the tasks are still executing error free, and the check task * changed all the tasks are still executing error free, and the check task
* toggles the onboard LED. Should any task contain an error at any time * toggles the onboard LED. Should any task contain an error at any time
* the LED toggle rate will change from 3 seconds to 500ms. * the LED toggle rate will change from 3 seconds to 500ms.
* *
*/ */
@ -70,29 +70,29 @@
#include "USB/USBSample.h" #include "USB/USBSample.h"
/* Priorities for the demo application tasks. */ /* Priorities for the demo application tasks. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainUSB_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainUSB_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* Constants required by the 'Check' task. */ /* Constants required by the 'Check' task. */
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
#define mainCHECK_TASK_LED ( 3 ) #define mainCHECK_TASK_LED ( 3 )
/* Constants for the ComTest tasks. */ /* Constants for the ComTest tasks. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 )
#define mainCOM_TEST_LED ( 4 ) /* Off the board. */ #define mainCOM_TEST_LED ( 4 ) /* Off the board. */
/* /*
* The task that executes at the highest priority and calls * The task that executes at the highest priority and calls
* prvCheckOtherTasksAreStillRunning(). See the description at the top * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Configure the processor for use with the Atmel demo board. Setup is minimal * Configure the processor for use with the Atmel demo board. Setup is minimal
@ -111,136 +111,133 @@ static long prvCheckOtherTasksAreStillRunning( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Starts all the other tasks, then starts the scheduler. * Starts all the other tasks, then starts the scheduler.
*/ */
void main( void ) void main( void )
{ {
/* Setup any hardware that has not already been configured by the low /* Setup any hardware that has not already been configured by the low
level init routines. */ * level init routines. */
prvSetupHardware(); prvSetupHardware();
/* Initialise the LED outputs for use by the demo application tasks. */ /* Initialise the LED outputs for use by the demo application tasks. */
vParTestInitialise(); vParTestInitialise();
/* Start all the standard demo application tasks. */ /* Start all the standard demo application tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartLEDFlashTasks( mainLED_TASK_PRIORITY ); vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
/* Also start the USB demo which is just for the SAM7. */
xTaskCreate( vUSBDemoTask, "USB", configMINIMAL_STACK_SIZE, NULL, mainUSB_PRIORITY, NULL );
/* Start the check task - which is defined in this file. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Start the scheduler. /* Also start the USB demo which is just for the SAM7. */
xTaskCreate( vUSBDemoTask, "USB", configMINIMAL_STACK_SIZE, NULL, mainUSB_PRIORITY, NULL );
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. /* Start the check task - which is defined in this file. */
The processor MUST be in supervisor mode when vTaskStartScheduler is xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
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(); /* 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. */
/* We should never get here as control is now taken by the scheduler. */ vTaskStartScheduler();
return;
/* We should never get here as control is now taken by the scheduler. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* When using the JTAG debugger the hardware is not always initialised to /* When using the JTAG debugger the hardware is not always initialised to
the correct default state. This line just ensures that this does not * the correct default state. This line just ensures that this does not
cause all interrupts to be masked at the start. */ * cause all interrupts to be masked at the start. */
AT91C_BASE_AIC->AIC_EOICR = 0; AT91C_BASE_AIC->AIC_EOICR = 0;
/* Most setup is performed by the low level init function called from the
startup asm file. */
/* Configure the PIO Lines corresponding to LED1 to LED4 to be outputs as /* Most setup is performed by the low level init function called from the
well as the UART Tx line. */ * startup asm file. */
AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK );
/* Configure the PIO Lines corresponding to LED1 to LED4 to be outputs as
/* Enable the peripheral clock. */ * well as the UART Tx line. */
AT91F_PMC_EnablePeriphClock( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ); AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK );
/* Enable the peripheral clock. */
AT91F_PMC_EnablePeriphClock( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
/* The parameters are not used in this task. */ /* The parameters are not used in this task. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period * operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so * is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. */ * the on board LED flash rate will increase. */
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. */ /* Delay until it is time to execute again. */
vTaskDelay( xDelayPeriod ); vTaskDelay( xDelayPeriod );
/* Check all the standard demo application tasks are executing without /* Check all the standard demo application tasks are executing without
error. */ * error. */
if( prvCheckOtherTasksAreStillRunning() != pdPASS ) if( prvCheckOtherTasksAreStillRunning() != pdPASS )
{ {
/* An error has been detected in one of the tasks - flash faster. */ /* An error has been detected in one of the tasks - flash faster. */
xDelayPeriod = mainERROR_FLASH_PERIOD; xDelayPeriod = mainERROR_FLASH_PERIOD;
} }
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static long prvCheckOtherTasksAreStillRunning( void ) static long prvCheckOtherTasksAreStillRunning( void )
{ {
long lReturn = ( long ) pdPASS; long lReturn = ( long ) pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected * that they are all still running, and that none of them have detected
an error. */ * an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreComTestTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
return lReturn; return lReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -25,12 +25,12 @@
*/ */
/* /*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used. * these demo application projects then ensure Supervisor mode is used.
*/ */
/* /*
@ -58,16 +58,16 @@
*/ */
/* /*
Changes from V2.4.2 * Changes from V2.4.2
*
+ The vErrorChecks() task now dynamically creates then deletes a task each + The vErrorChecks() task now dynamically creates then deletes a task each
cycle. This tests the operation of the memory allocator. + cycle. This tests the operation of the memory allocator.
+
Changes from V2.5.2 + Changes from V2.5.2
+
+ vParTestInitialise() is called during initialisation to ensure all the + vParTestInitialise() is called during initialisation to ensure all the
LED's start off. + LED's start off.
*/ */
/* Standard includes. */ /* Standard includes. */
@ -93,53 +93,53 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Constants to setup I/O. */ /* Constants to setup I/O. */
#define mainTX_ENABLE ( ( unsigned long ) 0x0001 ) #define mainTX_ENABLE ( ( unsigned long ) 0x0001 )
#define mainRX_ENABLE ( ( unsigned long ) 0x0004 ) #define mainRX_ENABLE ( ( unsigned long ) 0x0004 )
#define mainP0_14 ( ( unsigned long ) 0x4000 ) #define mainP0_14 ( ( unsigned long ) 0x4000 )
#define mainJTAG_PORT ( ( unsigned long ) 0x3E0000UL ) #define mainJTAG_PORT ( ( unsigned long ) 0x3E0000UL )
/* Constants to setup the PLL. */ /* Constants to setup the PLL. */
#define mainPLL_MUL_4 ( ( unsigned char ) 0x0003 ) #define mainPLL_MUL_4 ( ( unsigned char ) 0x0003 )
#define mainPLL_DIV_1 ( ( unsigned char ) 0x0000 ) #define mainPLL_DIV_1 ( ( unsigned char ) 0x0000 )
#define mainPLL_ENABLE ( ( unsigned char ) 0x0001 ) #define mainPLL_ENABLE ( ( unsigned char ) 0x0001 )
#define mainPLL_CONNECT ( ( unsigned char ) 0x0003 ) #define mainPLL_CONNECT ( ( unsigned char ) 0x0003 )
#define mainPLL_FEED_BYTE1 ( ( unsigned char ) 0xaa ) #define mainPLL_FEED_BYTE1 ( ( unsigned char ) 0xaa )
#define mainPLL_FEED_BYTE2 ( ( unsigned char ) 0x55 ) #define mainPLL_FEED_BYTE2 ( ( unsigned char ) 0x55 )
#define mainPLL_LOCK ( ( unsigned long ) 0x0400 ) #define mainPLL_LOCK ( ( unsigned long ) 0x0400 )
/* Constants to setup the MAM. */ /* Constants to setup the MAM. */
#define mainMAM_TIM_3 ( ( unsigned char ) 0x03 ) #define mainMAM_TIM_3 ( ( unsigned char ) 0x03 )
#define mainMAM_MODE_FULL ( ( unsigned char ) 0x02 ) #define mainMAM_MODE_FULL ( ( unsigned char ) 0x02 )
/* Constants to setup the peripheral bus. */ /* Constants to setup the peripheral bus. */
#define mainBUS_CLK_FULL ( ( unsigned char ) 0x01 ) #define mainBUS_CLK_FULL ( ( unsigned char ) 0x01 )
/* Constants for the ComTest tasks. */ /* Constants for the ComTest tasks. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 )
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
/* Priorities for the demo application tasks. */ /* Priorities for the demo application tasks. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 0 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 0 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 0 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 0 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* The rate at which the on board LED will toggle when there is/is not an /* The rate at which the on board LED will toggle when there is/is not an
error. */ * error. */
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
#define mainON_BOARD_LED_BIT ( ( unsigned long ) 0x80 ) #define mainON_BOARD_LED_BIT ( ( unsigned long ) 0x80 )
/* Constants used by the vMemCheckTask() task. */ /* Constants used by the vMemCheckTask() task. */
#define mainCOUNT_INITIAL_VALUE ( ( unsigned long ) 0 ) #define mainCOUNT_INITIAL_VALUE ( ( unsigned long ) 0 )
#define mainNO_TASK ( 0 ) #define mainNO_TASK ( 0 )
/* The size of the memory blocks allocated by the vMemCheckTask() task. */ /* The size of the memory blocks allocated by the vMemCheckTask() task. */
#define mainMEM_CHECK_SIZE_1 ( ( size_t ) 51 ) #define mainMEM_CHECK_SIZE_1 ( ( size_t ) 51 )
#define mainMEM_CHECK_SIZE_2 ( ( size_t ) 52 ) #define mainMEM_CHECK_SIZE_2 ( ( size_t ) 52 )
#define mainMEM_CHECK_SIZE_3 ( ( size_t ) 151 ) #define mainMEM_CHECK_SIZE_3 ( ( size_t ) 151 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -160,14 +160,14 @@ static long prvCheckOtherTasksAreStillRunning( unsigned long ulMemCheckTaskCount
* prvCheckOtherTasksAreStillRunning(). See the description at the top * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Dynamically created and deleted during each cycle of the vErrorChecks() * Dynamically created and deleted during each cycle of the vErrorChecks()
* task. This is done to check the operation of the memory allocator. * task. This is done to check the operation of the memory allocator.
* See the top of vErrorChecks for more details. * See the top of vErrorChecks for more details.
*/ */
static void vMemCheckTask( void *pvParameters ); static void vMemCheckTask( void * pvParameters );
/* /*
* Configure the processor for use with the Olimex demo board. This includes * Configure the processor for use with the Olimex demo board. This includes
@ -182,288 +182,291 @@ static void prvSetupHardware( void );
*/ */
int main( void ) int main( void )
{ {
/* Setup the hardware for use with the Olimex demo board. */ /* Setup the hardware for use with the Olimex demo board. */
prvSetupHardware(); prvSetupHardware();
/* Start the demo/test application tasks. */ /* Start the demo/test application tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartLEDFlashTasks( mainLED_TASK_PRIORITY ); vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartMathTasks( tskIDLE_PRIORITY ); vStartMathTasks( tskIDLE_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
/* Start the check task - which is defined in this file. */ /* Start the check task - which is defined in this file. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Now all the tasks have been started - start the scheduler. /* Now all the tasks have been started - start the scheduler.
*
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* 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();
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. /* Should never reach here! */
The processor MUST be in supervisor mode when vTaskStartScheduler is return 0;
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! */
return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
unsigned long ulMemCheckTaskRunningCount; unsigned long ulMemCheckTaskRunningCount;
TaskHandle_t xCreatedTask; TaskHandle_t xCreatedTask;
/* The parameters are not used in this function. */ /* The parameters are not used in this function. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period * operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so * is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. * the on board LED flash rate will increase.
*
* In addition to the standard tests the memory allocator is tested through
* the dynamic creation and deletion of a task each cycle. Each time the
* task is created memory must be allocated for its stack. When the task is
* deleted this memory is returned to the heap. If the task cannot be created
* then it is likely that the memory allocation failed. */
In addition to the standard tests the memory allocator is tested through for( ; ; )
the dynamic creation and deletion of a task each cycle. Each time the {
task is created memory must be allocated for its stack. When the task is /* Dynamically create a task - passing ulMemCheckTaskRunningCount as a
deleted this memory is returned to the heap. If the task cannot be created * parameter. */
then it is likely that the memory allocation failed. */ ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;
xCreatedTask = mainNO_TASK;
for( ;; ) if( xTaskCreate( vMemCheckTask, "MEM_CHECK", configMINIMAL_STACK_SIZE, ( void * ) &ulMemCheckTaskRunningCount, tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )
{ {
/* Dynamically create a task - passing ulMemCheckTaskRunningCount as a /* Could not create the task - we have probably run out of heap. */
parameter. */ xDelayPeriod = mainERROR_FLASH_PERIOD;
ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE; }
xCreatedTask = mainNO_TASK;
if( xTaskCreate( vMemCheckTask, "MEM_CHECK", configMINIMAL_STACK_SIZE, ( void * ) &ulMemCheckTaskRunningCount, tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS ) /* Delay until it is time to execute again. */
{ vTaskDelay( xDelayPeriod );
/* Could not create the task - we have probably run out of heap. */
xDelayPeriod = mainERROR_FLASH_PERIOD;
}
/* Delay until it is time to execute again. */ /* Delete the dynamically created task. */
vTaskDelay( xDelayPeriod ); if( xCreatedTask != mainNO_TASK )
{
vTaskDelete( xCreatedTask );
}
/* Delete the dynamically created task. */ /* Check all the standard demo application tasks are executing without
if( xCreatedTask != mainNO_TASK ) * error. ulMemCheckTaskRunningCount is checked to ensure it was
{ * modified by the task just deleted. */
vTaskDelete( xCreatedTask ); if( prvCheckOtherTasksAreStillRunning( ulMemCheckTaskRunningCount ) != pdPASS )
} {
/* An error has been detected in one of the tasks - flash faster. */
xDelayPeriod = mainERROR_FLASH_PERIOD;
}
/* Check all the standard demo application tasks are executing without prvToggleOnBoardLED();
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. */
xDelayPeriod = mainERROR_FLASH_PERIOD;
}
prvToggleOnBoardLED();
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
#ifdef RUN_FROM_RAM #ifdef RUN_FROM_RAM
/* Remap the interrupt vectors to RAM if we are are running from RAM. */ /* Remap the interrupt vectors to RAM if we are are running from RAM. */
SCB_MEMMAP = 2; SCB_MEMMAP = 2;
#endif #endif
/* Configure the RS2332 pins. All other pins remain at their default of 0. */ /* Configure the RS2332 pins. All other pins remain at their default of 0. */
PCB_PINSEL0 |= mainTX_ENABLE; PCB_PINSEL0 |= mainTX_ENABLE;
PCB_PINSEL0 |= mainRX_ENABLE; PCB_PINSEL0 |= mainRX_ENABLE;
/* Set all GPIO to output other than the P0.14 (BSL), and the JTAG pins. /* Set all GPIO to output other than the P0.14 (BSL), and the JTAG pins.
The JTAG pins are left as input as I'm not sure what will happen if the * The JTAG pins are left as input as I'm not sure what will happen if the
Wiggler is connected after powerup - not that it would be a good idea to * Wiggler is connected after powerup - not that it would be a good idea to
do that anyway. */ * do that anyway. */
GPIO_IODIR = ~( mainP0_14 + mainJTAG_PORT ); GPIO_IODIR = ~( mainP0_14 + mainJTAG_PORT );
/* Setup the PLL to multiply the XTAL input by 4. */ /* Setup the PLL to multiply the XTAL input by 4. */
SCB_PLLCFG = ( mainPLL_MUL_4 | mainPLL_DIV_1 ); SCB_PLLCFG = ( mainPLL_MUL_4 | mainPLL_DIV_1 );
/* Activate the PLL by turning it on then feeding the correct sequence of /* Activate the PLL by turning it on then feeding the correct sequence of
bytes. */ * bytes. */
SCB_PLLCON = mainPLL_ENABLE; SCB_PLLCON = mainPLL_ENABLE;
SCB_PLLFEED = mainPLL_FEED_BYTE1; SCB_PLLFEED = mainPLL_FEED_BYTE1;
SCB_PLLFEED = mainPLL_FEED_BYTE2; SCB_PLLFEED = mainPLL_FEED_BYTE2;
/* Wait for the PLL to lock... */ /* Wait for the PLL to lock... */
while( !( SCB_PLLSTAT & mainPLL_LOCK ) ); while( !( SCB_PLLSTAT & mainPLL_LOCK ) )
{
}
/* ...before connecting it using the feed sequence again. */ /* ...before connecting it using the feed sequence again. */
SCB_PLLCON = mainPLL_CONNECT; SCB_PLLCON = mainPLL_CONNECT;
SCB_PLLFEED = mainPLL_FEED_BYTE1; SCB_PLLFEED = mainPLL_FEED_BYTE1;
SCB_PLLFEED = mainPLL_FEED_BYTE2; SCB_PLLFEED = mainPLL_FEED_BYTE2;
/* Setup and turn on the MAM. Three cycle access is used due to the fast /* Setup and turn on the MAM. Three cycle access is used due to the fast
PLL used. It is possible faster overall performance could be obtained by * PLL used. It is possible faster overall performance could be obtained by
tuning the MAM and PLL settings. */ * tuning the MAM and PLL settings. */
MAM_TIM = mainMAM_TIM_3; MAM_TIM = mainMAM_TIM_3;
MAM_CR = mainMAM_MODE_FULL; MAM_CR = mainMAM_MODE_FULL;
/* Setup the peripheral bus to be the same as the PLL output. */ /* Setup the peripheral bus to be the same as the PLL output. */
SCB_VPBDIV = mainBUS_CLK_FULL; SCB_VPBDIV = mainBUS_CLK_FULL;
/* Initialise LED outputs. */ /* Initialise LED outputs. */
vParTestInitialise(); vParTestInitialise();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void prvToggleOnBoardLED( void ) void prvToggleOnBoardLED( void )
{ {
unsigned long ulState; unsigned long ulState;
ulState = GPIO0_IOPIN; ulState = GPIO0_IOPIN;
if( ulState & mainON_BOARD_LED_BIT )
{ if( ulState & mainON_BOARD_LED_BIT )
GPIO_IOCLR = mainON_BOARD_LED_BIT; {
} GPIO_IOCLR = mainON_BOARD_LED_BIT;
else }
{ else
GPIO_IOSET = mainON_BOARD_LED_BIT; {
} GPIO_IOSET = mainON_BOARD_LED_BIT;
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static long prvCheckOtherTasksAreStillRunning( unsigned long ulMemCheckTaskCount ) static long prvCheckOtherTasksAreStillRunning( unsigned long ulMemCheckTaskCount )
{ {
long lReturn = ( long ) pdPASS; long lReturn = ( long ) pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected * that they are all still running, and that none of them have detected
an error. */ * an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreComTestTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( ulMemCheckTaskCount == mainCOUNT_INITIAL_VALUE ) if( ulMemCheckTaskCount == mainCOUNT_INITIAL_VALUE )
{ {
/* The vMemCheckTask did not increment the counter - it must /* The vMemCheckTask did not increment the counter - it must
have failed. */ * have failed. */
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
return lReturn; return lReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vMemCheckTask( void *pvParameters ) static void vMemCheckTask( void * pvParameters )
{ {
unsigned long *pulMemCheckTaskRunningCounter; unsigned long * pulMemCheckTaskRunningCounter;
void *pvMem1, *pvMem2, *pvMem3; void * pvMem1, * pvMem2, * pvMem3;
static long lErrorOccurred = pdFALSE; static long lErrorOccurred = pdFALSE;
/* This task is dynamically created then deleted during each cycle of the /* This task is dynamically created then deleted during each cycle of the
vErrorChecks task to check the operation of the memory allocator. Each time * vErrorChecks task to check the operation of the memory allocator. Each time
the task is created memory is allocated for the stack and TCB. Each time * the task is created memory is allocated for the stack and TCB. Each time
the task is deleted this memory is returned to the heap. This task itself * the task is deleted this memory is returned to the heap. This task itself
exercises the allocator by allocating and freeing blocks. * exercises the allocator by allocating and freeing blocks.
*
* The task executes at the idle priority so does not require a delay.
*
* pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the
* vErrorChecks() task that this task is still executing without error. */
The task executes at the idle priority so does not require a delay. pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters;
pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the for( ; ; )
vErrorChecks() task that this task is still executing without error. */ {
if( lErrorOccurred == pdFALSE )
{
/* We have never seen an error so increment the counter. */
( *pulMemCheckTaskRunningCounter )++;
}
pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters; /* 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. */
vTaskSuspendAll();
{
pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );
for( ;; ) if( pvMem1 == NULL )
{ {
if( lErrorOccurred == pdFALSE ) lErrorOccurred = pdTRUE;
{ }
/* We have never seen an error so increment the counter. */ else
( *pulMemCheckTaskRunningCounter )++; {
} memset( pvMem1, 0xaa, mainMEM_CHECK_SIZE_1 );
vPortFree( pvMem1 );
}
}
xTaskResumeAll();
/* Allocate some memory - just to give the allocator some extra /* Again - with a different size block. */
exercise. This has to be in a critical section to ensure the vTaskSuspendAll();
task does not get deleted while it has memory allocated. */ {
vTaskSuspendAll(); pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 );
{
pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );
if( pvMem1 == NULL )
{
lErrorOccurred = pdTRUE;
}
else
{
memset( pvMem1, 0xaa, mainMEM_CHECK_SIZE_1 );
vPortFree( pvMem1 );
}
}
xTaskResumeAll();
/* Again - with a different size block. */ if( pvMem2 == NULL )
vTaskSuspendAll(); {
{ lErrorOccurred = pdTRUE;
pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 ); }
if( pvMem2 == NULL ) else
{ {
lErrorOccurred = pdTRUE; memset( pvMem2, 0xaa, mainMEM_CHECK_SIZE_2 );
} vPortFree( pvMem2 );
else }
{ }
memset( pvMem2, 0xaa, mainMEM_CHECK_SIZE_2 ); xTaskResumeAll();
vPortFree( pvMem2 );
}
}
xTaskResumeAll();
/* Again - with a different size block. */ /* Again - with a different size block. */
vTaskSuspendAll(); vTaskSuspendAll();
{ {
pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 ); pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );
if( pvMem3 == NULL )
{ if( pvMem3 == NULL )
lErrorOccurred = pdTRUE; {
} lErrorOccurred = pdTRUE;
else }
{ else
memset( pvMem3, 0xaa, mainMEM_CHECK_SIZE_3 ); {
vPortFree( pvMem3 ); memset( pvMem3, 0xaa, mainMEM_CHECK_SIZE_3 );
} vPortFree( pvMem3 );
} }
xTaskResumeAll(); }
} xTaskResumeAll();
}
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -26,12 +26,12 @@
/* /*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used. * these demo application projects then ensure Supervisor mode is used.
*/ */
/* /*
@ -70,49 +70,49 @@
#include "comtest2.h" #include "comtest2.h"
/* Priorities for the demo application tasks. */ /* Priorities for the demo application tasks. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* Constants required by the 'Check' task. */ /* Constants required by the 'Check' task. */
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
#define mainCHECK_TASK_LED ( 7 ) #define mainCHECK_TASK_LED ( 7 )
/* Constants for the ComTest tasks. */ /* Constants for the ComTest tasks. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 )
#define mainCOM_TEST_LED ( 4 ) #define mainCOM_TEST_LED ( 4 )
#define mainTX_ENABLE ( ( unsigned long ) 0x0001 ) #define mainTX_ENABLE ( ( unsigned long ) 0x0001 )
#define mainRX_ENABLE ( ( unsigned long ) 0x0004 ) #define mainRX_ENABLE ( ( unsigned long ) 0x0004 )
/* Constants to setup the PLL. */ /* Constants to setup the PLL. */
#define mainPLL_MUL_5 ( ( unsigned char ) 0x0004 ) #define mainPLL_MUL_5 ( ( unsigned char ) 0x0004 )
#define mainPLL_DIV_1 ( ( unsigned char ) 0x0000 ) #define mainPLL_DIV_1 ( ( unsigned char ) 0x0000 )
#define mainPLL_ENABLE ( ( unsigned char ) 0x0001 ) #define mainPLL_ENABLE ( ( unsigned char ) 0x0001 )
#define mainPLL_CONNECT ( ( unsigned char ) 0x0003 ) #define mainPLL_CONNECT ( ( unsigned char ) 0x0003 )
#define mainPLL_FEED_BYTE1 ( ( unsigned char ) 0xaa ) #define mainPLL_FEED_BYTE1 ( ( unsigned char ) 0xaa )
#define mainPLL_FEED_BYTE2 ( ( unsigned char ) 0x55 ) #define mainPLL_FEED_BYTE2 ( ( unsigned char ) 0x55 )
#define mainPLL_LOCK ( ( unsigned long ) 0x0400 ) #define mainPLL_LOCK ( ( unsigned long ) 0x0400 )
/* Constants to setup the MAM. */ /* Constants to setup the MAM. */
#define mainMAM_TIM_3 ( ( unsigned char ) 0x03 ) #define mainMAM_TIM_3 ( ( unsigned char ) 0x03 )
#define mainMAM_MODE_FULL ( ( unsigned char ) 0x02 ) #define mainMAM_MODE_FULL ( ( unsigned char ) 0x02 )
/* Constants to setup the peripheral bus. */ /* Constants to setup the peripheral bus. */
#define mainBUS_CLK_FULL ( ( unsigned char ) 0x01 ) #define mainBUS_CLK_FULL ( ( unsigned char ) 0x01 )
/* And finally, constant to setup the port for the LED's. */ /* And finally, constant to setup the port for the LED's. */
#define mainLED_TO_OUTPUT ( ( unsigned long ) 0xff0000 ) #define mainLED_TO_OUTPUT ( ( unsigned long ) 0xff0000 )
/* /*
* The task that executes at the highest priority and calls * The task that executes at the highest priority and calls
* prvCheckOtherTasksAreStillRunning(). See the description at the top * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Configures the processor for use with this demo. * Configures the processor for use with this demo.
@ -133,146 +133,145 @@ static long prvCheckOtherTasksAreStillRunning( void );
*/ */
void main( void ) void main( void )
{ {
/* Setup the processor. */ /* Setup the processor. */
prvSetupHardware(); prvSetupHardware();
/* Start all the standard demo application tasks. */ /* Start all the standard demo application tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartLEDFlashTasks( mainLED_TASK_PRIORITY ); vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
/* Start the check task - which is defined in this file. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Start the scheduler. /* Start the check task - which is defined in this file. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. /* Start the scheduler.
The processor MUST be in supervisor mode when vTaskStartScheduler is *
called. The demo applications included in the FreeRTOS.org download switch * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
to supervisor mode prior to main being called. If you are not using one of * The processor MUST be in supervisor mode when vTaskStartScheduler is
these demo application projects then ensure Supervisor mode is used here. * 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
vTaskStartScheduler(); * 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. */ /* We should never get here as control is now taken by the scheduler. */
return;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Setup the PLL to multiply the XTAL input by 5. */ /* Setup the PLL to multiply the XTAL input by 5. */
PLLCFG = ( mainPLL_MUL_5 | mainPLL_DIV_1 ); PLLCFG = ( mainPLL_MUL_5 | mainPLL_DIV_1 );
/* Activate the PLL by turning it on then feeding the correct sequence of /* Activate the PLL by turning it on then feeding the correct sequence of
bytes. */ * bytes. */
PLLCON = mainPLL_ENABLE; PLLCON = mainPLL_ENABLE;
PLLFEED = mainPLL_FEED_BYTE1; PLLFEED = mainPLL_FEED_BYTE1;
PLLFEED = mainPLL_FEED_BYTE2; PLLFEED = mainPLL_FEED_BYTE2;
/* Wait for the PLL to lock... */ /* Wait for the PLL to lock... */
while( !( PLLSTAT & mainPLL_LOCK ) ); while( !( PLLSTAT & mainPLL_LOCK ) )
{
}
/* ...before connecting it using the feed sequence again. */ /* ...before connecting it using the feed sequence again. */
PLLCON = mainPLL_CONNECT; PLLCON = mainPLL_CONNECT;
PLLFEED = mainPLL_FEED_BYTE1; PLLFEED = mainPLL_FEED_BYTE1;
PLLFEED = mainPLL_FEED_BYTE2; PLLFEED = mainPLL_FEED_BYTE2;
/* Setup and turn on the MAM. Three cycle access is used due to the fast /* Setup and turn on the MAM. Three cycle access is used due to the fast
PLL used. It is possible faster overall performance could be obtained by * PLL used. It is possible faster overall performance could be obtained by
tuning the MAM and PLL settings. */ * tuning the MAM and PLL settings. */
MAMTIM = mainMAM_TIM_3; MAMTIM = mainMAM_TIM_3;
MAMCR = mainMAM_MODE_FULL; MAMCR = mainMAM_MODE_FULL;
/* Setup the peripheral bus to be the same as the PLL output. */ /* Setup the peripheral bus to be the same as the PLL output. */
APBDIV = mainBUS_CLK_FULL; APBDIV = mainBUS_CLK_FULL;
/* Configure the RS2332 pins. All other pins remain at their default of 0. */
PINSEL0 |= mainTX_ENABLE;
PINSEL0 |= mainRX_ENABLE;
/* LED pins need to be output. */ /* Configure the RS2332 pins. All other pins remain at their default of 0. */
IO1DIR = mainLED_TO_OUTPUT; PINSEL0 |= mainTX_ENABLE;
PINSEL0 |= mainRX_ENABLE;
/* Setup the peripheral bus to be the same as the PLL output. */ /* LED pins need to be output. */
APBDIV = mainBUS_CLK_FULL; IO1DIR = mainLED_TO_OUTPUT;
/* Setup the peripheral bus to be the same as the PLL output. */
APBDIV = mainBUS_CLK_FULL;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
/* The parameters are not used in this task. */ /* The parameters are not used in this task. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period * operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so * is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. */ * the on board LED flash rate will increase. */
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. */ /* Delay until it is time to execute again. */
vTaskDelay( xDelayPeriod ); vTaskDelay( xDelayPeriod );
/* Check all the standard demo application tasks are executing without /* Check all the standard demo application tasks are executing without
error. */ * error. */
if( prvCheckOtherTasksAreStillRunning() != pdPASS ) if( prvCheckOtherTasksAreStillRunning() != pdPASS )
{ {
/* An error has been detected in one of the tasks - flash faster. */ /* An error has been detected in one of the tasks - flash faster. */
xDelayPeriod = mainERROR_FLASH_PERIOD; xDelayPeriod = mainERROR_FLASH_PERIOD;
} }
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static long prvCheckOtherTasksAreStillRunning( void ) static long prvCheckOtherTasksAreStillRunning( void )
{ {
long lReturn = ( long ) pdPASS; long lReturn = ( long ) pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected * that they are all still running, and that none of them have detected
an error. */ * an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreComTestTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
return lReturn; return lReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -24,29 +24,29 @@
* *
*/ */
/* /*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used. * these demo application projects then ensure Supervisor mode is used.
*/ */
/* /*
* Creates all the demo application tasks, then starts the scheduler. The WEB * Creates all the demo application tasks, then starts the scheduler. The WEB
* documentation provides more details of the demo application tasks. * documentation provides more details of the demo application tasks.
* *
* Main.c also creates a task called "Check". This only executes every three * Main.c also creates a task called "Check". This only executes every three
* seconds but has the highest priority so is guaranteed to get processor time. * seconds but has the highest priority so is guaranteed to get processor time.
* Its main function is to check that all the other tasks are still operational. * Its main function is to check that all the other tasks are still operational.
* Each task (other than the "flash" tasks) maintains a unique count that is * Each task (other than the "flash" tasks) maintains a unique count that is
* incremented each time the task successfully completes its function. Should * incremented each time the task successfully completes its function. Should
* any error occur within such a task the count is permanently halted. The * any error occur within such a task the count is permanently halted. The
* check task inspects the count of each task to ensure it has changed since * check task inspects the count of each task to ensure it has changed since
* the last time the check task executed. If all the count variables have * the last time the check task executed. If all the count variables have
* changed all the tasks are still executing error free, and the check task * changed all the tasks are still executing error free, and the check task
* toggles the onboard LED. Should any task contain an error at any time * toggles the onboard LED. Should any task contain an error at any time
* the LED toggle rate will change from 3 seconds to 500ms. * the LED toggle rate will change from 3 seconds to 500ms.
* *
*/ */
@ -71,31 +71,31 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Constants to setup I/O and processor. */ /* Constants to setup I/O and processor. */
#define mainTX_ENABLE ( ( unsigned long ) 0x00010000 ) /* UART1. */ #define mainTX_ENABLE ( ( unsigned long ) 0x00010000 ) /* UART1. */
#define mainRX_ENABLE ( ( unsigned long ) 0x00040000 ) /* UART1. */ #define mainRX_ENABLE ( ( unsigned long ) 0x00040000 ) /* UART1. */
#define mainBUS_CLK_FULL ( ( unsigned char ) 0x01 ) #define mainBUS_CLK_FULL ( ( unsigned char ) 0x01 )
#define mainLED_TO_OUTPUT ( ( unsigned long ) 0xff0000 ) #define mainLED_TO_OUTPUT ( ( unsigned long ) 0xff0000 )
/* Constants for the ComTest demo application tasks. */ /* Constants for the ComTest demo application tasks. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 )
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
/* Priorities for the demo application tasks. */ /* Priorities for the demo application tasks. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
/* Constants used by the "check" task. As described at the head of this file /* Constants used by the "check" task. As described at the head of this file
the check task toggles an LED. The rate at which the LED flashes is used to * the check task toggles an LED. The rate at which the LED flashes is used to
indicate whether an error has been detected or not. If the LED toggles every * indicate whether an error has been detected or not. If the LED toggles every
3 seconds then no errors have been detected. If the rate increases to 500ms * 3 seconds then no errors have been detected. If the rate increases to 500ms
then an error has been detected in at least one of the demo application tasks. */ * then an error has been detected in at least one of the demo application tasks. */
#define mainCHECK_LED ( 7 ) #define mainCHECK_LED ( 7 )
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -106,11 +106,11 @@ then an error has been detected in at least one of the demo application tasks. *
static long prvCheckOtherTasksAreStillRunning( void ); static long prvCheckOtherTasksAreStillRunning( void );
/* /*
* The task that executes at the highest priority and calls * The task that executes at the highest priority and calls
* prvCheckOtherTasksAreStillRunning(). See the description at the top * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Configure the processor for use with the Keil demo board. This is very * Configure the processor for use with the Keil demo board. This is very
@ -125,125 +125,125 @@ static void prvSetupHardware( void );
/* /*
* Application entry point: * Application entry point:
* Starts all the other tasks, then starts the scheduler. * Starts all the other tasks, then starts the scheduler.
*/ */
int main( void ) int main( void )
{ {
/* Setup the hardware for use with the Keil demo board. */ /* Setup the hardware for use with the Keil demo board. */
prvSetupHardware(); prvSetupHardware();
/* Start the demo/test application tasks. */ /* Start the demo/test application tasks. */
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartLEDFlashTasks( mainLED_TASK_PRIORITY ); vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
/* Start the check task - which is defined in this file. This is the task /* Start the check task - which is defined in this file. This is the task
that periodically checks to see that all the other tasks are executing * that periodically checks to see that all the other tasks are executing
without error. */ * without error. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Now all the tasks have been started - start the scheduler. /* Now all the tasks have been started - start the scheduler.
*
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* 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();
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. /* Should never reach here! If you do then there was not enough heap
The processor MUST be in supervisor mode when vTaskStartScheduler is * available for the idle task to be created. */
called. The demo applications included in the FreeRTOS.org download switch for( ; ; )
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( ;; );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
/* Parameters are not used. */ /* Parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period * operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so * is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. * the on board LED flash rate will increase.
*
* This task runs at the highest priority. */
This task runs at the highest priority. */ for( ; ; )
{
/* 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. */
vTaskDelay( xDelayPeriod );
for( ;; ) if( prvCheckOtherTasksAreStillRunning() != pdPASS )
{ {
/* The period of the delay depends on whether an error has been /* An error has been detected in one of the tasks - flash faster. */
detected or not. If an error has been detected then the period xDelayPeriod = mainERROR_FLASH_PERIOD;
is reduced to increase the LED flash rate. */ }
vTaskDelay( xDelayPeriod );
if( prvCheckOtherTasksAreStillRunning() != pdPASS ) /* Toggle the LED before going back to wait for the next cycle. */
{ vParTestToggleLED( mainCHECK_LED );
/* An error has been detected in one of the tasks - flash faster. */ }
xDelayPeriod = mainERROR_FLASH_PERIOD;
}
/* Toggle the LED before going back to wait for the next cycle. */
vParTestToggleLED( mainCHECK_LED );
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Perform the hardware setup required. This is minimal as most of the /* Perform the hardware setup required. This is minimal as most of the
setup is managed by the settings in the project file. */ * setup is managed by the settings in the project file. */
/* Configure the UART1 pins. All other pins remain at their default of 0. */ /* Configure the UART1 pins. All other pins remain at their default of 0. */
PINSEL0 |= mainTX_ENABLE; PINSEL0 |= mainTX_ENABLE;
PINSEL0 |= mainRX_ENABLE; PINSEL0 |= mainRX_ENABLE;
/* LED pins need to be output. */ /* LED pins need to be output. */
IODIR1 = mainLED_TO_OUTPUT; IODIR1 = mainLED_TO_OUTPUT;
/* Setup the peripheral bus to be the same as the PLL output. */ /* Setup the peripheral bus to be the same as the PLL output. */
VPBDIV = mainBUS_CLK_FULL; VPBDIV = mainBUS_CLK_FULL;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static long prvCheckOtherTasksAreStillRunning( void ) static long prvCheckOtherTasksAreStillRunning( void )
{ {
long lReturn = pdPASS; long lReturn = pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected * that they are all still running, and that none of them have detected
an error. */ * an error. */
if( xAreComTestTasksStillRunning() != pdPASS ) if( xAreComTestTasksStillRunning() != pdPASS )
{ {
lReturn = pdFAIL; lReturn = pdFAIL;
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
lReturn = pdFAIL; lReturn = pdFAIL;
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
lReturn = pdFAIL; lReturn = pdFAIL;
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
lReturn = pdFAIL; lReturn = pdFAIL;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
lReturn = pdFAIL; lReturn = pdFAIL;
} }
return lReturn; return lReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -75,51 +75,51 @@
#include "semtest.h" #include "semtest.h"
/* Hardware configuration definitions. */ /* Hardware configuration definitions. */
#define mainBUS_CLK_FULL ( ( unsigned char ) 0x01 ) #define mainBUS_CLK_FULL ( ( unsigned char ) 0x01 )
#define mainLED_BIT 0x80000000 #define mainLED_BIT 0x80000000
#define mainP0_14__EINT_1 ( 2 << 28 ) #define mainP0_14__EINT_1 ( 2 << 28 )
#define mainEINT_1_EDGE_SENSITIVE 2 #define mainEINT_1_EDGE_SENSITIVE 2
#define mainEINT_1_FALLING_EDGE_SENSITIVE 0 #define mainEINT_1_FALLING_EDGE_SENSITIVE 0
#define mainEINT_1_CHANNEL 15 #define mainEINT_1_CHANNEL 15
#define mainEINT_1_VIC_CHANNEL_BIT ( 1 << mainEINT_1_CHANNEL ) #define mainEINT_1_VIC_CHANNEL_BIT ( 1 << mainEINT_1_CHANNEL )
#define mainEINT_1_ENABLE_BIT ( 1 << 5 ) #define mainEINT_1_ENABLE_BIT ( 1 << 5 )
/* Demo application definitions. */ /* Demo application definitions. */
#define mainQUEUE_SIZE ( 3 ) #define mainQUEUE_SIZE ( 3 )
#define mainLED_DELAY ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainLED_DELAY ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
#define mainERROR_LED_DELAY ( ( TickType_t ) 50 / portTICK_PERIOD_MS ) #define mainERROR_LED_DELAY ( ( TickType_t ) 50 / portTICK_PERIOD_MS )
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
#define mainLIST_BUFFER_SIZE 2048 #define mainLIST_BUFFER_SIZE 2048
#define mainNO_DELAY ( 0 ) #define mainNO_DELAY ( 0 )
#define mainSHORT_DELAY ( 150 / portTICK_PERIOD_MS ) #define mainSHORT_DELAY ( 150 / portTICK_PERIOD_MS )
/* Task priorities. */ /* Task priorities. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainPRINT_TASK_PRIORITY ( tskIDLE_PRIORITY + 0 ) #define mainPRINT_TASK_PRIORITY ( tskIDLE_PRIORITY + 0 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The semaphore used to wake the button task from within the external interrupt /* The semaphore used to wake the button task from within the external interrupt
handler. */ * handler. */
SemaphoreHandle_t xButtonSemaphore; SemaphoreHandle_t xButtonSemaphore;
/* The queue that is used to send message to vPrintTask for display in the /* The queue that is used to send message to vPrintTask for display in the
terminal output window. */ * terminal output window. */
QueueHandle_t xPrintQueue; QueueHandle_t xPrintQueue;
/* The rate at which the LED will toggle. The toggle rate increases if an /* The rate at which the LED will toggle. The toggle rate increases if an
error is detected in any task. */ * error is detected in any task. */
static TickType_t xLED_Delay = mainLED_DELAY; static TickType_t xLED_Delay = mainLED_DELAY;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Simply flashes the on board LED every mainLED_DELAY milliseconds. * Simply flashes the on board LED every mainLED_DELAY milliseconds.
*/ */
static void vLEDTask( void *pvParameters ); static void vLEDTask( void * pvParameters );
/* /*
* Checks the status of all the demo tasks then prints a message to the * Checks the status of all the demo tasks then prints a message to the
@ -130,250 +130,251 @@ static void vLEDTask( void *pvParameters );
* Messages are not written directly to the terminal, but passed to vPrintTask * Messages are not written directly to the terminal, but passed to vPrintTask
* via a queue. * via a queue.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* Controls all terminal output. If a task wants to send a message to the * Controls all terminal output. If a task wants to send a message to the
* terminal IO it posts a pointer to the text to vPrintTask via a queue. This * terminal IO it posts a pointer to the text to vPrintTask via a queue. This
* ensures serial access to the terminal IO. * ensures serial access to the terminal IO.
*/ */
static void vPrintTask( void *pvParameter ); static void vPrintTask( void * pvParameter );
/* /*
* Simply waits for an interrupt to be generated from the built in button, then * Simply waits for an interrupt to be generated from the built in button, then
* generates a table of tasks states that is then written by vPrintTask to the * generates a table of tasks states that is then written by vPrintTask to the
* terminal output window within CrossStudio. * terminal output window within CrossStudio.
*/ */
static void vButtonHandlerTask( void *pvParameters ); static void vButtonHandlerTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
{ {
/* Setup the peripheral bus to be the same as the PLL output. */ /* Setup the peripheral bus to be the same as the PLL output. */
VPBDIV = mainBUS_CLK_FULL; VPBDIV = mainBUS_CLK_FULL;
/* Create the queue used to pass message to vPrintTask. */ /* Create the queue used to pass message to vPrintTask. */
xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( char * ) ); xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( char * ) );
/* Create the semaphore used to wake vButtonHandlerTask(). */ /* Create the semaphore used to wake vButtonHandlerTask(). */
vSemaphoreCreateBinary( xButtonSemaphore ); vSemaphoreCreateBinary( xButtonSemaphore );
xSemaphoreTake( xButtonSemaphore, 0 ); xSemaphoreTake( xButtonSemaphore, 0 );
/* Start the standard demo tasks. */ /* Start the standard demo tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
#if configUSE_PREEMPTION == 1 #if configUSE_PREEMPTION == 1
{ {
/* The timing of console output when not using the preemptive /* The timing of console output when not using the preemptive
scheduler causes the block time tests to detect a timing problem. */ * scheduler causes the block time tests to detect a timing problem. */
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
} }
#endif #endif
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
/* Start the tasks defined within this file. */ /* Start the tasks defined within this file. */
xTaskCreate( vLEDTask, "LED", configMINIMAL_STACK_SIZE, NULL, mainLED_TASK_PRIORITY, NULL ); xTaskCreate( vLEDTask, "LED", configMINIMAL_STACK_SIZE, NULL, mainLED_TASK_PRIORITY, NULL );
xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainPRINT_TASK_PRIORITY, NULL ); xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainPRINT_TASK_PRIORITY, NULL );
xTaskCreate( vButtonHandlerTask, "Button", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vButtonHandlerTask, "Button", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* The scheduler should now be running, so we will only ever reach here if we /* The scheduler should now be running, so we will only ever reach here if we
ran out of heap space. */ * ran out of heap space. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vLEDTask( void *pvParameters ) static void vLEDTask( void * pvParameters )
{ {
/* Just to remove compiler warnings. */ /* Just to remove compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Configure IO. */ /* Configure IO. */
IO0DIR |= mainLED_BIT; IO0DIR |= mainLED_BIT;
IO0SET = mainLED_BIT; IO0SET = mainLED_BIT;
for( ;; ) for( ; ; )
{ {
/* Not very exiting - just delay... */ /* Not very exiting - just delay... */
vTaskDelay( xLED_Delay ); vTaskDelay( xLED_Delay );
/* ...set the IO ... */ /* ...set the IO ... */
IO0CLR = mainLED_BIT; IO0CLR = mainLED_BIT;
/* ...delay again... */ /* ...delay again... */
vTaskDelay( xLED_Delay ); vTaskDelay( xLED_Delay );
/* ...then clear the IO. */ /* ...then clear the IO. */
IO0SET = mainLED_BIT; IO0SET = mainLED_BIT;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
portBASE_TYPE xErrorOccurred = pdFALSE; portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
const char * const pcPassMessage = "PASS\n"; const char * const pcPassMessage = "PASS\n";
const char * const pcFailMessage = "FAIL\n"; const char * const pcFailMessage = "FAIL\n";
/* Just to remove compiler warnings. */ /* Just to remove compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Perform this check every mainCHECK_DELAY milliseconds. */ /* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
/* Has an error been found in any task? */ /* Has an error been found in any task? */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
} }
#if configUSE_PREEMPTION == 1 #if configUSE_PREEMPTION == 1
{ {
/* The timing of console output when not using the preemptive /* The timing of console output when not using the preemptive
scheduler causes the block time tests to detect a timing problem. */ * scheduler causes the block time tests to detect a timing problem. */
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
} }
} }
#endif #endif
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
} }
/* Send either a pass or fail message. If an error is found it is /* Send either a pass or fail message. If an error is found it is
never cleared again. */ * never cleared again. */
if( xErrorOccurred == pdTRUE ) if( xErrorOccurred == pdTRUE )
{ {
xLED_Delay = mainERROR_LED_DELAY; xLED_Delay = mainERROR_LED_DELAY;
xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY ); xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY );
} }
else else
{ {
xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY ); xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY );
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters ) static void vPrintTask( void * pvParameters )
{ {
char *pcMessage; char * pcMessage;
/* Just to stop compiler warnings. */ /* Just to stop compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
/* Wait for a message to arrive. */ /* Wait for a message to arrive. */
while( xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY ) != pdPASS ); while( xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY ) != pdPASS )
{
}
/* Write the message to the terminal IO. */ /* Write the message to the terminal IO. */
#ifndef NDEBUG #ifndef NDEBUG
debug_printf( "%s", pcMessage ); debug_printf( "%s", pcMessage );
#endif #endif
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vButtonHandlerTask( void *pvParameters ) static void vButtonHandlerTask( void * pvParameters )
{ {
static char cListBuffer[ mainLIST_BUFFER_SIZE ]; static char cListBuffer[ mainLIST_BUFFER_SIZE ];
const char *pcList = &( cListBuffer[ 0 ] ); const char * pcList = &( cListBuffer[ 0 ] );
const char * const pcHeader = "\nTask State Priority Stack #\n************************************************"; const char * const pcHeader = "\nTask State Priority Stack #\n************************************************";
extern void (vButtonISRWrapper) ( void );
/* Just to stop compiler warnings. */ extern void( vButtonISRWrapper ) ( void );
( void ) pvParameters;
/* Configure the interrupt. */ /* Just to stop compiler warnings. */
portENTER_CRITICAL(); ( void ) pvParameters;
{
/* Configure P0.14 to generate interrupts. */
PINSEL0 |= mainP0_14__EINT_1;
EXTMODE = mainEINT_1_EDGE_SENSITIVE;
EXTPOLAR = mainEINT_1_FALLING_EDGE_SENSITIVE;
/* Setup the VIC for EINT 1. */ /* Configure the interrupt. */
VICIntSelect &= ~mainEINT_1_VIC_CHANNEL_BIT; portENTER_CRITICAL();
VICIntEnable |= mainEINT_1_VIC_CHANNEL_BIT; {
VICVectAddr1 = ( long ) vButtonISRWrapper; /* Configure P0.14 to generate interrupts. */
VICVectCntl1 = mainEINT_1_ENABLE_BIT | mainEINT_1_CHANNEL; PINSEL0 |= mainP0_14__EINT_1;
} EXTMODE = mainEINT_1_EDGE_SENSITIVE;
portEXIT_CRITICAL(); EXTPOLAR = mainEINT_1_FALLING_EDGE_SENSITIVE;
for( ;; ) /* Setup the VIC for EINT 1. */
{ VICIntSelect &= ~mainEINT_1_VIC_CHANNEL_BIT;
/* For debouncing, wait a while then clear the semaphore. */ VICIntEnable |= mainEINT_1_VIC_CHANNEL_BIT;
vTaskDelay( mainSHORT_DELAY ); VICVectAddr1 = ( long ) vButtonISRWrapper;
xSemaphoreTake( xButtonSemaphore, mainNO_DELAY ); VICVectCntl1 = mainEINT_1_ENABLE_BIT | mainEINT_1_CHANNEL;
}
portEXIT_CRITICAL();
/* Wait for an interrupt. */ for( ; ; )
xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ); {
/* For debouncing, wait a while then clear the semaphore. */
vTaskDelay( mainSHORT_DELAY );
xSemaphoreTake( xButtonSemaphore, mainNO_DELAY );
/* Send the column headers to the print task for display. */ /* Wait for an interrupt. */
xQueueSend( xPrintQueue, &pcHeader, portMAX_DELAY ); xSemaphoreTake( xButtonSemaphore, portMAX_DELAY );
/* Create the list of task states. */ /* Send the column headers to the print task for display. */
vTaskList( cListBuffer ); xQueueSend( xPrintQueue, &pcHeader, portMAX_DELAY );
/* Send the task status information to the print task for display. */ /* Create the list of task states. */
xQueueSend( xPrintQueue, &pcList, portMAX_DELAY ); vTaskList( cListBuffer );
}
/* Send the task status information to the print task for display. */
xQueueSend( xPrintQueue, &pcList, portMAX_DELAY );
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
/* Check pcTaskName for the name of the offending task, or pxCurrentTCB /* Check pcTaskName for the name of the offending task, or pxCurrentTCB
if pcTaskName has itself been corrupted. */ * if pcTaskName has itself been corrupted. */
( void ) pxTask; ( void ) pxTask;
( void ) pcTaskName; ( void ) pcTaskName;
for( ;; );
for( ; ; )
{
}
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -26,32 +26,32 @@
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "semphr.h" #include "semphr.h"
#define isrCLEAR_EINT_1 2 #define isrCLEAR_EINT_1 2
/* /*
* Interrupt routine that simply wakes vButtonHandlerTask on each interrupt * Interrupt routine that simply wakes vButtonHandlerTask on each interrupt
* generated by a push of the built in button. The wrapper takes care of * generated by a push of the built in button. The wrapper takes care of
* the ISR entry. This then calls the actual handler function to perform * the ISR entry. This then calls the actual handler function to perform
* the work. This work should not be done in the wrapper itself unless * the work. This work should not be done in the wrapper itself unless
* you are absolutely sure that no stack space is used. * you are absolutely sure that no stack space is used.
*/ */
void vButtonISRWrapper( void ) __attribute__ ((naked)); void vButtonISRWrapper( void ) __attribute__( ( naked ) );
void vButtonHandler( void ) __attribute__ ((noinline)); void vButtonHandler( void ) __attribute__( ( noinline ) );
void vButtonHandler( void ) void vButtonHandler( void )
{ {
extern SemaphoreHandle_t xButtonSemaphore; extern SemaphoreHandle_t xButtonSemaphore;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );
if( xHigherPriorityTaskWoken ) if( xHigherPriorityTaskWoken )
{ {
/* We have woken a task. Calling "yield from ISR" here will ensure /* We have woken a task. Calling "yield from ISR" here will ensure
the interrupt returns to the woken task if it has a priority higher * the interrupt returns to the woken task if it has a priority higher
than the interrupted task. */ * than the interrupted task. */
portYIELD_FROM_ISR(); portYIELD_FROM_ISR();
} }
EXTINT = isrCLEAR_EINT_1; EXTINT = isrCLEAR_EINT_1;
VICVectAddr = 0; VICVectAddr = 0;
@ -60,17 +60,14 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
void vButtonISRWrapper( void ) void vButtonISRWrapper( void )
{ {
/* Save the context of the interrupted task. */ /* Save the context of the interrupted task. */
portSAVE_CONTEXT(); portSAVE_CONTEXT();
/* Call the handler to do the work. This must be a separate function to /* Call the handler to do the work. This must be a separate function to
the wrapper to ensure the correct stack frame is set up. */ * the wrapper to ensure the correct stack frame is set up. */
__asm volatile( "bl vButtonHandler" ); __asm volatile ( "bl vButtonHandler" );
/* Restore the context of whichever task is going to run once the interrupt /* Restore the context of whichever task is going to run once the interrupt
completes. */ * completes. */
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -25,12 +25,12 @@
*/ */
/* /*
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode. * NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is * The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch * called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of * to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used. * these demo application projects then ensure Supervisor mode is used.
*/ */
/* /*
* Creates all the demo application tasks, then starts the scheduler. The WEB * Creates all the demo application tasks, then starts the scheduler. The WEB
@ -69,28 +69,28 @@
#include "comtest2.h" #include "comtest2.h"
/* Priorities for the demo application tasks. */ /* Priorities for the demo application tasks. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* Constants required by the 'Check' task. */ /* Constants required by the 'Check' task. */
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
#define mainCHECK_TASK_LED ( 4 ) #define mainCHECK_TASK_LED ( 4 )
/* Constants for the ComTest tasks. */ /* Constants for the ComTest tasks. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 )
#define mainCOM_TEST_LED ( 6 ) /* The LED built onto the kickstart board. */ #define mainCOM_TEST_LED ( 6 ) /* The LED built onto the kickstart board. */
/* /*
* The task that executes at the highest priority and calls * The task that executes at the highest priority and calls
* prvCheckOtherTasksAreStillRunning(). See the description at the top * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Configure the processor for use with the IAR STR71x demo board. This * Configure the processor for use with the IAR STR71x demo board. This
@ -112,37 +112,36 @@ static long prvCheckOtherTasksAreStillRunning( void );
*/ */
void main( void ) void main( void )
{ {
/* Setup any hardware that has not already been configured by the low /* Setup any hardware that has not already been configured by the low
level init routines. */ * level init routines. */
prvSetupHardware(); prvSetupHardware();
/* Initialise the LED outputs for use by the demo application tasks. */ /* Initialise the LED outputs for use by the demo application tasks. */
vParTestInitialise(); vParTestInitialise();
/* Start all the standard demo application tasks. */ /* Start all the standard demo application tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartLEDFlashTasks( mainLED_TASK_PRIORITY ); vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
/* Start the check task - which is defined in this file. */ /* Start the check task - which is defined in this file. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Start the scheduler. /* Start the scheduler.
*
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* 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. vTaskStartScheduler();
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. */
/* We should never get here as control is now taken by the scheduler. */
return;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -151,90 +150,88 @@ static void prvSetupHardware( void )
/* Setup the PLL to generate a 48MHz clock from the 4MHz CLK. */ /* Setup the PLL to generate a 48MHz clock from the 4MHz CLK. */
/* Turn of the div by two. */ /* Turn of the div by two. */
RCCU_Div2Config( DISABLE ); RCCU_Div2Config( DISABLE );
/* 48MHz = ( 4MHz * 12 ) / 1 */ /* 48MHz = ( 4MHz * 12 ) / 1 */
RCCU_PLL1Config( RCCU_PLL1_Mul_12, RCCU_Div_1 ); RCCU_PLL1Config( RCCU_PLL1_Mul_12, RCCU_Div_1 );
RCCU_RCLKSourceConfig( RCCU_PLL1_Output ); RCCU_RCLKSourceConfig( RCCU_PLL1_Output );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_FLASH_PERIOD;
TickType_t xLastWakeTime; TickType_t xLastWakeTime;
/* The parameters are not used in this task. */ /* The parameters are not used in this task. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil() /* Initialise xLastWakeTime to ensure the first call to vTaskDelayUntil()
functions correctly. */ * functions correctly. */
xLastWakeTime = xTaskGetTickCount(); xLastWakeTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period * operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so * is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. */ * the on board LED flash rate will increase. */
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. The delay period is /* Delay until it is time to execute again. The delay period is
shorter following an error so the LED flashes faster. */ * shorter following an error so the LED flashes faster. */
vTaskDelayUntil( &xLastWakeTime, xDelayPeriod ); vTaskDelayUntil( &xLastWakeTime, xDelayPeriod );
/* Check all the standard demo application tasks are executing without /* Check all the standard demo application tasks are executing without
error. */ * error. */
if( prvCheckOtherTasksAreStillRunning() != pdPASS ) if( prvCheckOtherTasksAreStillRunning() != pdPASS )
{ {
/* An error has been detected in one of the tasks - flash faster. */ /* An error has been detected in one of the tasks - flash faster. */
xDelayPeriod = mainERROR_FLASH_PERIOD; xDelayPeriod = mainERROR_FLASH_PERIOD;
} }
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static long prvCheckOtherTasksAreStillRunning( void ) static long prvCheckOtherTasksAreStillRunning( void )
{ {
long lReturn = ( long ) pdPASS; long lReturn = ( long ) pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected * that they are all still running, and that none of them have detected
an error. */ * an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreComTestTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
lReturn = ( long ) pdFAIL; lReturn = ( long ) pdFAIL;
} }
return lReturn; return lReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -66,41 +66,41 @@
#include "dynamic.h" #include "dynamic.h"
/* Demo application task priorities. */ /* Demo application task priorities. */
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* How often should we check the other tasks? */ /* How often should we check the other tasks? */
#define mainCHECK_TASK_CYCLE_TIME ( 3000 ) #define mainCHECK_TASK_CYCLE_TIME ( 3000 )
/* The maximum offset into the pass and fail strings sent to the LCD. An /* The maximum offset into the pass and fail strings sent to the LCD. An
offset is used a simple method of using a different column each time a message * offset is used a simple method of using a different column each time a message
is written to the LCD. */ * is written to the LCD. */
#define mainMAX_WRITE_COLUMN ( 14 ) #define mainMAX_WRITE_COLUMN ( 14 )
/* Baud rate used by the comtest tasks. */ /* Baud rate used by the comtest tasks. */
#define mainCOM_TEST_BAUD_RATE ( 19200 ) #define mainCOM_TEST_BAUD_RATE ( 19200 )
/* The LED used by the comtest tasks. See the comtest.c file for more /* The LED used by the comtest tasks. See the comtest.c file for more
information. */ * information. */
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
/* The number of messages that can be queued for display on the LCD at any one /* The number of messages that can be queued for display on the LCD at any one
time. */ * time. */
#define mainLCD_QUEUE_LENGTH ( 2 ) #define mainLCD_QUEUE_LENGTH ( 2 )
/* The time to wait when sending to mainLCD_QUEUE_LENGTH. */ /* The time to wait when sending to mainLCD_QUEUE_LENGTH. */
#define mainNO_DELAY ( 0 ) #define mainNO_DELAY ( 0 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The type that is posted to the LCD queue. */ /* The type that is posted to the LCD queue. */
typedef struct LCD_MESSAGE typedef struct LCD_MESSAGE
{ {
unsigned char *pucString; /* Points to the string to be displayed. */ unsigned char * pucString; /* Points to the string to be displayed. */
unsigned char ucLine; /* The line of the LCD that should be used. */ unsigned char ucLine; /* The line of the LCD that should be used. */
} LCDMessage; } LCDMessage;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -110,12 +110,12 @@ typedef struct LCD_MESSAGE
* all the other tasks in the system. See the description at the top of the * all the other tasks in the system. See the description at the top of the
* file. * file.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* ST provided routine to configure the processor. * ST provided routine to configure the processor.
*/ */
static void prvSetupHardware(void); static void prvSetupHardware( void );
/* /*
* The only task that should access the LCD. Other tasks wanting to write * The only task that should access the LCD. Other tasks wanting to write
@ -124,7 +124,7 @@ static void prvSetupHardware(void);
* waiting for the arrival of such messages, displays the message, then blocks * waiting for the arrival of such messages, displays the message, then blocks
* again. * again.
*/ */
static void vPrintTask( void *pvParameters ); static void vPrintTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -136,177 +136,179 @@ static QueueHandle_t xLCDQueue;
/* Create all the demo application tasks, then start the scheduler. */ /* Create all the demo application tasks, then start the scheduler. */
int main( void ) int main( void )
{ {
/* Perform any hardware setup necessary. */ /* Perform any hardware setup necessary. */
prvSetupHardware(); prvSetupHardware();
vParTestInitialise(); vParTestInitialise();
/* Create the queue used to communicate with the LCD print task. */ /* Create the queue used to communicate with the LCD print task. */
xLCDQueue = xQueueCreate( mainLCD_QUEUE_LENGTH, sizeof( LCDMessage ) ); xLCDQueue = xQueueCreate( mainLCD_QUEUE_LENGTH, sizeof( LCDMessage ) );
/* Create the standard demo application tasks. See the WEB documentation /* Create the standard demo application tasks. See the WEB documentation
for more information on these tasks. */ * for more information on these tasks. */
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartLEDFlashTasks( mainLED_TASK_PRIORITY ); vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
/* Create the tasks defined within this file. */ /* Create the tasks defined within this file. */
xTaskCreate( vPrintTask, "LCD", configMINIMAL_STACK_SIZE, NULL, mainLCD_TASK_PRIORITY, NULL ); xTaskCreate( vPrintTask, "LCD", configMINIMAL_STACK_SIZE, NULL, mainLCD_TASK_PRIORITY, NULL );
xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
vTaskStartScheduler(); vTaskStartScheduler();
/* Execution will only reach here if there was insufficient heap to /* Execution will only reach here if there was insufficient heap to
start the scheduler. */ * start the scheduler. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
static unsigned long ulErrorDetected = pdFALSE; static unsigned long ulErrorDetected = pdFALSE;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
unsigned char *ucErrorMessage = ( unsigned char * )" FAIL"; unsigned char * ucErrorMessage = ( unsigned char * ) " FAIL";
unsigned char *ucSuccessMessage = ( unsigned char * )" PASS"; unsigned char * ucSuccessMessage = ( unsigned char * ) " PASS";
unsigned portBASE_TYPE uxColumn = mainMAX_WRITE_COLUMN; unsigned portBASE_TYPE uxColumn = mainMAX_WRITE_COLUMN;
LCDMessage xMessage; LCDMessage xMessage;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Wait until it is time for the next cycle. */ /* Wait until it is time for the next cycle. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_TASK_CYCLE_TIME ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_TASK_CYCLE_TIME );
/* Has an error been found in any of the standard demo tasks? */ /* Has an error been found in any of the standard demo tasks? */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
ulErrorDetected = pdTRUE; ulErrorDetected = pdTRUE;
} }
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorDetected = pdTRUE; ulErrorDetected = pdTRUE;
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
ulErrorDetected = pdTRUE; ulErrorDetected = pdTRUE;
} }
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreComTestTasksStillRunning() != pdTRUE )
{ {
ulErrorDetected = pdTRUE; ulErrorDetected = pdTRUE;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
ulErrorDetected = pdTRUE; ulErrorDetected = pdTRUE;
} }
/* Calculate the LCD line on which we would like the message to /* Calculate the LCD line on which we would like the message to
be displayed. The column variable is used for convenience as * be displayed. The column variable is used for convenience as
it is incremented each cycle anyway. */ * it is incremented each cycle anyway. */
xMessage.ucLine = ( unsigned char ) ( uxColumn & 0x01 ); xMessage.ucLine = ( unsigned char ) ( uxColumn & 0x01 );
/* The message displayed depends on whether an error was found or /* The message displayed depends on whether an error was found or
not. Any discovered error is latched. Here the column variable * not. Any discovered error is latched. Here the column variable
is used as an index into the text string as a simple way of moving * is used as an index into the text string as a simple way of moving
the text from column to column. */ * the text from column to column. */
if( ulErrorDetected == pdFALSE ) if( ulErrorDetected == pdFALSE )
{ {
xMessage.pucString = ucSuccessMessage + uxColumn; xMessage.pucString = ucSuccessMessage + uxColumn;
} }
else else
{ {
xMessage.pucString = ucErrorMessage + uxColumn; xMessage.pucString = ucErrorMessage + uxColumn;
} }
/* Send the message to the print task for display. */ /* Send the message to the print task for display. */
xQueueSend( xLCDQueue, ( void * ) &xMessage, mainNO_DELAY ); xQueueSend( xLCDQueue, ( void * ) &xMessage, mainNO_DELAY );
/* Make sure the message is printed in a different column the next /* Make sure the message is printed in a different column the next
time around. */ * time around. */
uxColumn--; uxColumn--;
if( uxColumn == 0 )
{ if( uxColumn == 0 )
uxColumn = mainMAX_WRITE_COLUMN; {
} uxColumn = mainMAX_WRITE_COLUMN;
} }
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters ) static void vPrintTask( void * pvParameters )
{ {
LCDMessage xMessage; LCDMessage xMessage;
for( ;; ) for( ; ; )
{ {
/* Wait until a message arrives. */ /* Wait until a message arrives. */
while( xQueueReceive( xLCDQueue, ( void * ) &xMessage, portMAX_DELAY ) != pdPASS ); while( xQueueReceive( xLCDQueue, ( void * ) &xMessage, portMAX_DELAY ) != pdPASS )
{
}
/* The message contains the text to display, and the line on which the /* The message contains the text to display, and the line on which the
text should be displayed. */ * text should be displayed. */
LCD_Clear(); LCD_Clear();
LCD_DisplayString( xMessage.ucLine, xMessage.pucString, BlackText ); LCD_DisplayString( xMessage.ucLine, xMessage.pucString, BlackText );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware(void) static void prvSetupHardware( void )
{ {
ErrorStatus OSC4MStartUpStatus01; ErrorStatus OSC4MStartUpStatus01;
/* ST provided routine. */ /* ST provided routine. */
/* MRCC system reset */ /* MRCC system reset */
MRCC_DeInit(); MRCC_DeInit();
/* Wait for OSC4M start-up */ /* Wait for OSC4M start-up */
OSC4MStartUpStatus01 = MRCC_WaitForOSC4MStartUp(); OSC4MStartUpStatus01 = MRCC_WaitForOSC4MStartUp();
if(OSC4MStartUpStatus01 == SUCCESS) if( OSC4MStartUpStatus01 == SUCCESS )
{ {
/* Set HCLK to 60MHz */ /* Set HCLK to 60MHz */
MRCC_HCLKConfig(MRCC_CKSYS_Div1); MRCC_HCLKConfig( MRCC_CKSYS_Div1 );
/* Set CKTIM to 60MHz */ /* Set CKTIM to 60MHz */
MRCC_CKTIMConfig(MRCC_HCLK_Div1); MRCC_CKTIMConfig( MRCC_HCLK_Div1 );
/* Set PCLK to 30MHz */ /* Set PCLK to 30MHz */
MRCC_PCLKConfig(MRCC_CKTIM_Div2); MRCC_PCLKConfig( MRCC_CKTIM_Div2 );
/* Enable Flash Burst mode */ /* Enable Flash Burst mode */
CFG_FLASHBurstConfig(CFG_FLASHBurst_Enable); CFG_FLASHBurstConfig( CFG_FLASHBurst_Enable );
/* Set CK_SYS to 60 MHz */ /* Set CK_SYS to 60 MHz */
MRCC_CKSYSConfig(MRCC_CKSYS_OSC4MPLL, MRCC_PLL_Mul_15); MRCC_CKSYSConfig( MRCC_CKSYS_OSC4MPLL, MRCC_PLL_Mul_15 );
} }
/* GPIO pins optimized for 3V3 operation */ /* GPIO pins optimized for 3V3 operation */
MRCC_IOVoltageRangeConfig(MRCC_IOVoltageRange_3V3); MRCC_IOVoltageRangeConfig( MRCC_IOVoltageRange_3V3 );
/* GPIO clock source enable */ /* GPIO clock source enable */
MRCC_PeripheralClockConfig(MRCC_Peripheral_GPIO, ENABLE); MRCC_PeripheralClockConfig( MRCC_Peripheral_GPIO, ENABLE );
/* EXTIT clock source enable */ /* EXTIT clock source enable */
MRCC_PeripheralClockConfig(MRCC_Peripheral_EXTIT, ENABLE); MRCC_PeripheralClockConfig( MRCC_Peripheral_EXTIT, ENABLE );
/* TB clock source enable */ /* TB clock source enable */
MRCC_PeripheralClockConfig(MRCC_Peripheral_TB, ENABLE); MRCC_PeripheralClockConfig( MRCC_Peripheral_TB, ENABLE );
/* Initialize the demonstration menu */ /* Initialize the demonstration menu */
LCD_Init(); LCD_Init();
LCD_DisplayString(Line1, ( unsigned char * ) "www.FreeRTOS.org", BlackText); LCD_DisplayString( Line1, ( unsigned char * ) "www.FreeRTOS.org", BlackText );
LCD_DisplayString(Line2, ( unsigned char * ) " STR750 Demo ", BlackText); LCD_DisplayString( Line2, ( unsigned char * ) " STR750 Demo ", BlackText );
EIC_IRQCmd(ENABLE); EIC_IRQCmd( ENABLE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -66,41 +66,41 @@
#include "dynamic.h" #include "dynamic.h"
/* Demo application task priorities. */ /* Demo application task priorities. */
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* How often should we check the other tasks? */ /* How often should we check the other tasks? */
#define mainCHECK_TASK_CYCLE_TIME ( 3000 ) #define mainCHECK_TASK_CYCLE_TIME ( 3000 )
/* The maximum offset into the pass and fail strings sent to the LCD. An /* The maximum offset into the pass and fail strings sent to the LCD. An
offset is used a simple method of using a different column each time a message * offset is used a simple method of using a different column each time a message
is written to the LCD. */ * is written to the LCD. */
#define mainMAX_WRITE_COLUMN ( 14 ) #define mainMAX_WRITE_COLUMN ( 14 )
/* Baud rate used by the comtest tasks. */ /* Baud rate used by the comtest tasks. */
#define mainCOM_TEST_BAUD_RATE ( 19200 ) #define mainCOM_TEST_BAUD_RATE ( 19200 )
/* The LED used by the comtest tasks. See the comtest.c file for more /* The LED used by the comtest tasks. See the comtest.c file for more
information. */ * information. */
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
/* The number of messages that can be queued for display on the LCD at any one /* The number of messages that can be queued for display on the LCD at any one
time. */ * time. */
#define mainLCD_QUEUE_LENGTH ( 2 ) #define mainLCD_QUEUE_LENGTH ( 2 )
/* The time to wait when sending to mainLCD_QUEUE_LENGTH. */ /* The time to wait when sending to mainLCD_QUEUE_LENGTH. */
#define mainNO_DELAY ( 0 ) #define mainNO_DELAY ( 0 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The type that is posted to the LCD queue. */ /* The type that is posted to the LCD queue. */
typedef struct LCD_MESSAGE typedef struct LCD_MESSAGE
{ {
unsigned char *pucString; /* Points to the string to be displayed. */ unsigned char * pucString; /* Points to the string to be displayed. */
unsigned char ucLine; /* The line of the LCD that should be used. */ unsigned char ucLine; /* The line of the LCD that should be used. */
} LCDMessage; } LCDMessage;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -110,12 +110,12 @@ typedef struct LCD_MESSAGE
* all the other tasks in the system. See the description at the top of the * all the other tasks in the system. See the description at the top of the
* file. * file.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* ST provided routine to configure the processor. * ST provided routine to configure the processor.
*/ */
static void prvSetupHardware(void); static void prvSetupHardware( void );
/* /*
* The only task that should access the LCD. Other tasks wanting to write * The only task that should access the LCD. Other tasks wanting to write
@ -124,7 +124,7 @@ static void prvSetupHardware(void);
* waiting for the arrival of such messages, displays the message, then blocks * waiting for the arrival of such messages, displays the message, then blocks
* again. * again.
*/ */
static void vPrintTask( void *pvParameters ); static void vPrintTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -136,174 +136,177 @@ static QueueHandle_t xLCDQueue;
/* Create all the demo application tasks, then start the scheduler. */ /* Create all the demo application tasks, then start the scheduler. */
void main( void ) void main( void )
{ {
/* Perform any hardware setup necessary. */ /* Perform any hardware setup necessary. */
prvSetupHardware(); prvSetupHardware();
vParTestInitialise(); vParTestInitialise();
/* Create the queue used to communicate with the LCD print task. */ /* Create the queue used to communicate with the LCD print task. */
xLCDQueue = xQueueCreate( mainLCD_QUEUE_LENGTH, sizeof( LCDMessage ) ); xLCDQueue = xQueueCreate( mainLCD_QUEUE_LENGTH, sizeof( LCDMessage ) );
/* Create the standard demo application tasks. See the WEB documentation /* Create the standard demo application tasks. See the WEB documentation
for more information on these tasks. */ * for more information on these tasks. */
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartLEDFlashTasks( mainLED_TASK_PRIORITY ); vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
/* Create the tasks defined within this file. */ /* Create the tasks defined within this file. */
xTaskCreate( vPrintTask, "LCD", configMINIMAL_STACK_SIZE, NULL, mainLCD_TASK_PRIORITY, NULL ); xTaskCreate( vPrintTask, "LCD", configMINIMAL_STACK_SIZE, NULL, mainLCD_TASK_PRIORITY, NULL );
xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
vTaskStartScheduler(); vTaskStartScheduler();
/* Execution will only reach here if there was insufficient heap to /* Execution will only reach here if there was insufficient heap to
start the scheduler. */ * start the scheduler. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
static unsigned long ulErrorDetected = pdFALSE; static unsigned long ulErrorDetected = pdFALSE;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
unsigned char *cErrorMessage = " FAIL"; unsigned char * cErrorMessage = " FAIL";
unsigned char *cSuccessMessage = " PASS"; unsigned char * cSuccessMessage = " PASS";
unsigned portBASE_TYPE uxColumn = mainMAX_WRITE_COLUMN; unsigned portBASE_TYPE uxColumn = mainMAX_WRITE_COLUMN;
LCDMessage xMessage; LCDMessage xMessage;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Wait until it is time for the next cycle. */ /* Wait until it is time for the next cycle. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_TASK_CYCLE_TIME ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_TASK_CYCLE_TIME );
/* Has an error been found in any of the standard demo tasks? */ /* Has an error been found in any of the standard demo tasks? */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
ulErrorDetected = pdTRUE; ulErrorDetected = pdTRUE;
} }
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorDetected = pdTRUE; ulErrorDetected = pdTRUE;
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
ulErrorDetected = pdTRUE; ulErrorDetected = pdTRUE;
} }
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreComTestTasksStillRunning() != pdTRUE )
{ {
ulErrorDetected = pdTRUE; ulErrorDetected = pdTRUE;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
ulErrorDetected = pdTRUE; ulErrorDetected = pdTRUE;
} }
/* Calculate the LCD line on which we would like the message to /* Calculate the LCD line on which we would like the message to
be displayed. The column variable is used for convenience as * be displayed. The column variable is used for convenience as
it is incremented each cycle anyway. */ * it is incremented each cycle anyway. */
xMessage.ucLine = ( unsigned char ) ( uxColumn & 0x01 ); xMessage.ucLine = ( unsigned char ) ( uxColumn & 0x01 );
/* The message displayed depends on whether an error was found or /* The message displayed depends on whether an error was found or
not. Any discovered error is latched. Here the column variable * not. Any discovered error is latched. Here the column variable
is used as an index into the text string as a simple way of moving * is used as an index into the text string as a simple way of moving
the text from column to column. */ * the text from column to column. */
if( ulErrorDetected == pdFALSE ) if( ulErrorDetected == pdFALSE )
{ {
xMessage.pucString = cSuccessMessage + uxColumn; xMessage.pucString = cSuccessMessage + uxColumn;
} }
else else
{ {
xMessage.pucString = cErrorMessage + uxColumn; xMessage.pucString = cErrorMessage + uxColumn;
} }
/* Send the message to the print task for display. */ /* Send the message to the print task for display. */
xQueueSend( xLCDQueue, ( void * ) &xMessage, mainNO_DELAY ); xQueueSend( xLCDQueue, ( void * ) &xMessage, mainNO_DELAY );
/* Make sure the message is printed in a different column the next /* Make sure the message is printed in a different column the next
time around. */ * time around. */
uxColumn--; uxColumn--;
if( uxColumn == 0 )
{ if( uxColumn == 0 )
uxColumn = mainMAX_WRITE_COLUMN; {
} uxColumn = mainMAX_WRITE_COLUMN;
} }
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters ) static void vPrintTask( void * pvParameters )
{ {
LCDMessage xMessage; LCDMessage xMessage;
for( ;; ) for( ; ; )
{ {
/* Wait until a message arrives. */ /* Wait until a message arrives. */
while( xQueueReceive( xLCDQueue, ( void * ) &xMessage, portMAX_DELAY ) != pdPASS ); while( xQueueReceive( xLCDQueue, ( void * ) &xMessage, portMAX_DELAY ) != pdPASS )
{
}
/* The message contains the text to display, and the line on which the /* The message contains the text to display, and the line on which the
text should be displayed. */ * text should be displayed. */
LCD_Clear(); LCD_Clear();
LCD_DisplayString( xMessage.ucLine, xMessage.pucString, BlackText ); LCD_DisplayString( xMessage.ucLine, xMessage.pucString, BlackText );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware(void) static void prvSetupHardware( void )
{ {
ErrorStatus OSC4MStartUpStatus01; ErrorStatus OSC4MStartUpStatus01;
/* ST provided routine. */ /* ST provided routine. */
/* MRCC system reset */ /* MRCC system reset */
MRCC_DeInit(); MRCC_DeInit();
/* Wait for OSC4M start-up */ /* Wait for OSC4M start-up */
OSC4MStartUpStatus01 = MRCC_WaitForOSC4MStartUp(); OSC4MStartUpStatus01 = MRCC_WaitForOSC4MStartUp();
if(OSC4MStartUpStatus01 == SUCCESS) if( OSC4MStartUpStatus01 == SUCCESS )
{ {
/* Set HCLK to 60MHz */ /* Set HCLK to 60MHz */
MRCC_HCLKConfig(MRCC_CKSYS_Div1); MRCC_HCLKConfig( MRCC_CKSYS_Div1 );
/* Set CKTIM to 60MHz */ /* Set CKTIM to 60MHz */
MRCC_CKTIMConfig(MRCC_HCLK_Div1); MRCC_CKTIMConfig( MRCC_HCLK_Div1 );
/* Set PCLK to 30MHz */ /* Set PCLK to 30MHz */
MRCC_PCLKConfig(MRCC_CKTIM_Div2); MRCC_PCLKConfig( MRCC_CKTIM_Div2 );
/* Enable Flash Burst mode */ /* Enable Flash Burst mode */
CFG_FLASHBurstConfig(CFG_FLASHBurst_Enable); CFG_FLASHBurstConfig( CFG_FLASHBurst_Enable );
/* Set CK_SYS to 60 MHz */ /* Set CK_SYS to 60 MHz */
MRCC_CKSYSConfig(MRCC_CKSYS_OSC4MPLL, MRCC_PLL_Mul_15); MRCC_CKSYSConfig( MRCC_CKSYS_OSC4MPLL, MRCC_PLL_Mul_15 );
} }
/* GPIO pins optimized for 3V3 operation */ /* GPIO pins optimized for 3V3 operation */
MRCC_IOVoltageRangeConfig(MRCC_IOVoltageRange_3V3); MRCC_IOVoltageRangeConfig( MRCC_IOVoltageRange_3V3 );
/* GPIO clock source enable */ /* GPIO clock source enable */
MRCC_PeripheralClockConfig(MRCC_Peripheral_GPIO, ENABLE); MRCC_PeripheralClockConfig( MRCC_Peripheral_GPIO, ENABLE );
/* EXTIT clock source enable */ /* EXTIT clock source enable */
MRCC_PeripheralClockConfig(MRCC_Peripheral_EXTIT, ENABLE); MRCC_PeripheralClockConfig( MRCC_Peripheral_EXTIT, ENABLE );
/* TB clock source enable */ /* TB clock source enable */
MRCC_PeripheralClockConfig(MRCC_Peripheral_TB, ENABLE); MRCC_PeripheralClockConfig( MRCC_Peripheral_TB, ENABLE );
/* Initialize the demonstration menu */ /* Initialize the demonstration menu */
LCD_Init(); LCD_Init();
LCD_DisplayString(Line1, "www.FreeRTOS.org", BlackText); LCD_DisplayString( Line1, "www.FreeRTOS.org", BlackText );
LCD_DisplayString(Line2, " STR750 Demo ", BlackText); LCD_DisplayString( Line2, " STR750 Demo ", BlackText );
EIC_IRQCmd(ENABLE); EIC_IRQCmd( ENABLE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -63,21 +63,21 @@
#include <pio/pio.h> #include <pio/pio.h>
/* Priorities for the demo application tasks. */ /* Priorities for the demo application tasks. */
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 0 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 0 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 0 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 0 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainGENERIC_QUEUE_PRIORITY ( tskIDLE_PRIORITY ) #define mainGENERIC_QUEUE_PRIORITY ( tskIDLE_PRIORITY )
/* The period of the check task both in and out of the presense of an error. */ /* The period of the check task both in and out of the presense of an error. */
#define mainNO_ERROR_PERIOD ( 5000 / portTICK_PERIOD_MS ) #define mainNO_ERROR_PERIOD ( 5000 / portTICK_PERIOD_MS )
#define mainERROR_PERIOD ( 500 / portTICK_PERIOD_MS ); #define mainERROR_PERIOD ( 500 / portTICK_PERIOD_MS );
/* Constants used by the ComTest task. */ /* Constants used by the ComTest task. */
#define mainCOM_TEST_BAUD_RATE ( 38400 ) #define mainCOM_TEST_BAUD_RATE ( 38400 )
#define mainCOM_TEST_LED ( LED_DS1 ) #define mainCOM_TEST_LED ( LED_DS1 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -85,148 +85,150 @@
static void prvSetupHardware( void ); static void prvSetupHardware( void );
/* The check task as described at the top of this file. */ /* The check task as described at the top of this file. */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main() int main()
{ {
/* Perform any hardware setup necessary to run the demo. */ /* Perform any hardware setup necessary to run the demo. */
prvSetupHardware(); prvSetupHardware();
/* First create the 'standard demo' tasks. These exist just to to /* First create the 'standard demo' tasks. These exist just to to
demonstrate API functions being used and test the kernel port. More * demonstrate API functions being used and test the kernel port. More
information is provided on the FreeRTOS.org WEB site. */ * information is provided on the FreeRTOS.org WEB site. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartCountingSemaphoreTasks(); vStartCountingSemaphoreTasks();
vStartGenericQueueTasks( tskIDLE_PRIORITY ); vStartGenericQueueTasks( tskIDLE_PRIORITY );
vStartQueuePeekTasks(); vStartQueuePeekTasks();
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
/* Create the check task - this is the task that checks all the other tasks /* Create the check task - this is the task that checks all the other tasks
are executing as expected and without reporting any errors. */ * are executing as expected and without reporting any errors. */
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL ); xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
/* The death demo tasks must be started last as the sanity checks performed /* The death demo tasks must be started last as the sanity checks performed
require knowledge of the number of other tasks in the system. */ * require knowledge of the number of other tasks in the system. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the scheduler. From this point on the execution will be under /* Start the scheduler. From this point on the execution will be under
the control of the kernel. */ * the control of the kernel. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient heap available for the /* Will only get here if there was insufficient heap available for the
idle task to be created. */ * idle task to be created. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTask( void * pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
TickType_t xNextWakeTime, xPeriod = mainNO_ERROR_PERIOD; TickType_t xNextWakeTime, xPeriod = mainNO_ERROR_PERIOD;
static volatile unsigned long ulErrorCode = 0UL; static volatile unsigned long ulErrorCode = 0UL;
/* Just to remove the compiler warning. */ /* Just to remove the compiler warning. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise xNextWakeTime prior to its first use. From this point on /* Initialise xNextWakeTime prior to its first use. From this point on
the value of the variable is handled automatically by the kernel. */ * the value of the variable is handled automatically by the kernel. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; )
{
/* 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. */
if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
ulErrorCode |= 0x01UL;
}
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) for( ; ; )
{ {
ulErrorCode |= 0x02UL; /* Delay until it is time for this task to execute again. */
} vTaskDelayUntil( &xNextWakeTime, xPeriod );
if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) /* Check all the other tasks in the system - latch any reported errors
{ * into the ulErrorCode variable. */
ulErrorCode |= 0x04UL; if( xAreBlockingQueuesStillRunning() != pdTRUE )
} {
ulErrorCode |= 0x01UL;
}
if( xIsCreateTaskStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorCode |= 0x08UL; ulErrorCode |= 0x02UL;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
{ {
ulErrorCode |= 0x10UL; ulErrorCode |= 0x04UL;
} }
if( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xIsCreateTaskStillRunning() != pdTRUE )
{ {
ulErrorCode |= 0x20UL; ulErrorCode |= 0x08UL;
} }
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
ulErrorCode |= 0x40UL; ulErrorCode |= 0x10UL;
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
ulErrorCode |= 0x80UL; ulErrorCode |= 0x20UL;
} }
if( xAreQueuePeekTasksStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
ulErrorCode |= 0x100UL; ulErrorCode |= 0x40UL;
} }
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
ulErrorCode |= 0x200UL; ulErrorCode |= 0x80UL;
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{ {
ulErrorCode |= 0x400UL; ulErrorCode |= 0x100UL;
} }
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorCode |= 0x800UL; ulErrorCode |= 0x200UL;
} }
/* Reduce the block period and in so doing increase the frequency at if( xAreSemaphoreTasksStillRunning() != pdTRUE )
which this task executes if any errors have been latched. The increased {
frequency causes the LED toggle rate to increase and so gives some ulErrorCode |= 0x400UL;
visual feedback that an error has occurred. */ }
if( ulErrorCode != 0x00 )
{ if( xAreComTestTasksStillRunning() != pdTRUE )
xPeriod = mainERROR_PERIOD; {
} ulErrorCode |= 0x800UL;
}
/* Finally toggle the LED. */
vParTestToggleLED( LED_POWER ); /* 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. */
if( ulErrorCode != 0x00 )
{
xPeriod = mainERROR_PERIOD;
}
/* Finally toggle the LED. */
vParTestToggleLED( LED_POWER );
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
const Pin xPins[] = { PIN_USART0_RXD, PIN_USART0_TXD }; const Pin xPins[] = { PIN_USART0_RXD, PIN_USART0_TXD };
/* Setup the LED outputs. */ /* Setup the LED outputs. */
vParTestInitialise(); vParTestInitialise();
/* Setup the pins for the UART. */ /* Setup the pins for the UART. */
PIO_Configure( xPins, PIO_LISTSIZE( xPins ) ); PIO_Configure( xPins, PIO_LISTSIZE( xPins ) );
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -25,7 +25,8 @@
*/ */
/*This file has been prepared for Doxygen automatic documentation generation.*/ /*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
/* \file *********************************************************************
* *
* \brief FreeRTOS Real Time Kernel example. * \brief FreeRTOS Real Time Kernel example.
* *
@ -79,56 +80,48 @@
#include "death.h" #include "death.h"
#include "flop.h" #include "flop.h"
/*! \name Priority definitions for most of the tasks in the demo application. /* Priority definitions for most of the tasks in the demo application.
* Some tasks just use the idle priority. * Some tasks just use the idle priority.
*/ */
//! @{ #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
//! @}
//! Baud rate used by the serial port tasks. /* Baud rate used by the serial port tasks. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 57600 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 57600 )
//! LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
//! and mainCOM_TEST_LED + 1 is toggled on each character Rx. * and mainCOM_TEST_LED + 1 is toggled on each character Rx. */
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
//! LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
//! that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
//! the LED is toggled. If an error is found at any time the LED toggles faster. * the LED is toggled. If an error is found at any time the LED toggles faster.
#define mainCHECK_TASK_LED ( 6 )
//! LED that is set upon error.
#define mainERROR_LED ( 7 )
//! 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 )
/*! \name Constants used by the vMemCheckTask() task.
*/ */
//! @{ #define mainCHECK_TASK_LED ( 6 )
#define mainCOUNT_INITIAL_VALUE ( ( unsigned long ) 0 )
#define mainNO_TASK ( 0 )
//! @}
/*! \name The size of the memory blocks allocated by the vMemCheckTask() task. /* LED that is set upon error. */
*/ #define mainERROR_LED ( 7 )
//! @{
#define mainMEM_CHECK_SIZE_1 ( ( size_t ) 51 )
#define mainMEM_CHECK_SIZE_2 ( ( size_t ) 52 )
#define mainMEM_CHECK_SIZE_3 ( ( size_t ) 15 )
//! @}
/* 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 )
/* Constants used by the vMemCheckTask() task. */
#define mainCOUNT_INITIAL_VALUE ( ( unsigned long ) 0 )
#define mainNO_TASK ( 0 )
/* 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 * prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file. * of the file.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks that all the demo application tasks are still executing without error * Checks that all the demo application tasks are still executing without error
@ -148,7 +141,7 @@ static portBASE_TYPE prvCheckOtherTasksAreStillRunning( void );
/* /*
* A task that exercises the memory allocator. * A task that exercises the memory allocator.
*/ */
static void vMemCheckTask( void *pvParameters ); static void vMemCheckTask( void * pvParameters );
/* /*
* Called by the check task following the detection of an error to set the * Called by the check task following the detection of an error to set the
@ -160,305 +153,305 @@ static void prvIndicateError( void );
int main( void ) int main( void )
{ {
/* Start the crystal oscillator 0 and switch the main clock to it. */ /* Start the crystal oscillator 0 and switch the main clock to it. */
pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP); pm_switch_to_osc0( &AVR32_PM, FOSC0, OSC0_STARTUP );
portDBG_TRACE("Starting the FreeRTOS AVR32 UC3 Demo..."); portDBG_TRACE( "Starting the FreeRTOS AVR32 UC3 Demo..." );
/* Setup the LED's for output. */ /* Setup the LED's for output. */
vParTestInitialise(); vParTestInitialise();
/* Start the standard demo tasks. See the WEB documentation for more /* Start the standard demo tasks. See the WEB documentation for more
information. */ * information. */
vStartLEDFlashTasks( mainLED_TASK_PRIORITY ); vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartMathTasks( tskIDLE_PRIORITY ); vStartMathTasks( tskIDLE_PRIORITY );
/* Start the demo tasks defined within this file, specifically the check /* Start the demo tasks defined within this file, specifically the check
task as described at the top of this file. */ * task as described at the top of this file. */
xTaskCreate( xTaskCreate(
vErrorChecks vErrorChecks
, "ErrCheck" , "ErrCheck"
, configMINIMAL_STACK_SIZE , configMINIMAL_STACK_SIZE
, NULL , NULL
, mainCHECK_TASK_PRIORITY , mainCHECK_TASK_PRIORITY
, NULL ); , NULL );
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle /* Will only get here if there was insufficient memory to create the idle
task. */ * task. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*! /*
* \brief The task function for the "Check" task. * @brief The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
static volatile unsigned long ulDummyVariable = 3UL; static volatile unsigned long ulDummyVariable = 3UL;
unsigned long ulMemCheckTaskRunningCount; unsigned long ulMemCheckTaskRunningCount;
TaskHandle_t xCreatedTask; TaskHandle_t xCreatedTask;
portBASE_TYPE bSuicidalTask = 0; portBASE_TYPE bSuicidalTask = 0;
/* The parameters are not used. Prevent compiler warnings. */ /* The parameters are not used. Prevent compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. * operating without error.
*
* In addition to the standard tests the memory allocator is tested through
* the dynamic creation and deletion of a task each cycle. Each time the
* task is created memory must be allocated for its stack. When the task is
* deleted this memory is returned to the heap. If the task cannot be created
* then it is likely that the memory allocation failed. */
In addition to the standard tests the memory allocator is tested through for( ; ; )
the dynamic creation and deletion of a task each cycle. Each time the {
task is created memory must be allocated for its stack. When the task is /* Do this only once. */
deleted this memory is returned to the heap. If the task cannot be created if( bSuicidalTask == 0 )
then it is likely that the memory allocation failed. */ {
bSuicidalTask++;
for( ;; ) /* 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
/* Do this only once. */ * to be called before vTaskStartScheduler(). We're in the case here where
if( bSuicidalTask == 0 ) * vTaskStartScheduler() has already been called (thus the hidden IDLE task
{ * has already been spawned). Since vCreateSuicidalTask() supposes that the
bSuicidalTask++; * 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 );
}
/* This task has to be created last as it keeps account of the number of /* Reset xCreatedTask. This is modified by the task about to be
tasks it expects to see running. However its implementation expects * created so we can tell if it is executing correctly or not. */
to be called before vTaskStartScheduler(). We're in the case here where xCreatedTask = mainNO_TASK;
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 /* Dynamically create a task - passing ulMemCheckTaskRunningCount as a
created so we can tell if it is executing correctly or not. */ * parameter. */
xCreatedTask = mainNO_TASK; ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;
/* Dynamically create a task - passing ulMemCheckTaskRunningCount as a if( xTaskCreate( vMemCheckTask,
parameter. */ "MEM_CHECK",
ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE; configMINIMAL_STACK_SIZE,
( void * ) &ulMemCheckTaskRunningCount,
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. */
prvIndicateError();
}
if( xTaskCreate( vMemCheckTask, /* Delay until it is time to execute again. */
"MEM_CHECK", vTaskDelay( mainCHECK_PERIOD );
configMINIMAL_STACK_SIZE,
( void * ) &ulMemCheckTaskRunningCount,
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. */
prvIndicateError();
}
/* Delay until it is time to execute again. */ /* Delete the dynamically created task. */
vTaskDelay( mainCHECK_PERIOD ); if( xCreatedTask != mainNO_TASK )
{
vTaskDelete( xCreatedTask );
}
/* Delete the dynamically created task. */ /* Perform a bit of 32bit maths to ensure the registers used by the
if( xCreatedTask != mainNO_TASK ) * integer tasks get some exercise. The result here is not important -
{ * see the demo application documentation for more info. */
vTaskDelete( xCreatedTask ); ulDummyVariable *= 3;
}
/* Perform a bit of 32bit maths to ensure the registers used by the /* Check all other tasks are still operating without error.
integer tasks get some exercise. The result here is not important - * Check that vMemCheckTask did increment the counter. */
see the demo application documentation for more info. */ if( ( prvCheckOtherTasksAreStillRunning() != pdFALSE ) ||
ulDummyVariable *= 3; ( ulMemCheckTaskRunningCount == mainCOUNT_INITIAL_VALUE ) )
{
/* Check all other tasks are still operating without error. /* An error has occurred in one of the tasks.
Check that vMemCheckTask did increment the counter. */ * Don't go any further and flash the LED faster to give visual
if( ( prvCheckOtherTasksAreStillRunning() != pdFALSE ) * feedback of the error. */
|| ( ulMemCheckTaskRunningCount == mainCOUNT_INITIAL_VALUE ) ) prvIndicateError();
{ }
/* An error has occurred in one of the tasks. else
Don't go any further and flash the LED faster to give visual {
feedback of the error. */ /* Toggle the LED if everything is okay. */
prvIndicateError(); vParTestToggleLED( mainCHECK_TASK_LED );
} }
else }
{
/* Toggle the LED if everything is okay. */
vParTestToggleLED( mainCHECK_TASK_LED );
}
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*! /*
* \brief Checks that all the demo application tasks are still executing without error. * @brief Checks that all the demo application tasks are still executing without error.
*/ */
static portBASE_TYPE prvCheckOtherTasksAreStillRunning( void ) static portBASE_TYPE prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreComTestTasksStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xIsCreateTaskStillRunning() != pdTRUE ) if( xIsCreateTaskStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
return ( xErrorHasOccurred ); return( xErrorHasOccurred );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*! /*
* \brief Dynamically created and deleted during each cycle of the vErrorChecks() * @brief Dynamically created and deleted during each cycle of the vErrorChecks()
* task. This is done to check the operation of the memory allocator. * task. This is done to check the operation of the memory allocator.
* See the top of vErrorChecks for more details. * See the top of vErrorChecks for more details.
* *
* \param *pvParameters Parameters for the task (can be of any kind) * @param pvParameters Parameters for the task (can be of any kind)
*/ */
static void vMemCheckTask( void *pvParameters ) static void vMemCheckTask( void * pvParameters )
{ {
unsigned long *pulMemCheckTaskRunningCounter; unsigned long * pulMemCheckTaskRunningCounter;
void *pvMem1, *pvMem2, *pvMem3; void * pvMem1, * pvMem2, * pvMem3;
static long lErrorOccurred = pdFALSE; static long lErrorOccurred = pdFALSE;
/* This task is dynamically created then deleted during each cycle of the /* This task is dynamically created then deleted during each cycle of the
vErrorChecks task to check the operation of the memory allocator. Each time * vErrorChecks task to check the operation of the memory allocator. Each time
the task is created memory is allocated for the stack and TCB. Each time * the task is created memory is allocated for the stack and TCB. Each time
the task is deleted this memory is returned to the heap. This task itself * the task is deleted this memory is returned to the heap. This task itself
exercises the allocator by allocating and freeing blocks. * exercises the allocator by allocating and freeing blocks.
*
* The task executes at the idle priority so does not require a delay.
*
* pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the
* vErrorChecks() task that this task is still executing without error. */
The task executes at the idle priority so does not require a delay. pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters;
pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the for( ; ; )
vErrorChecks() task that this task is still executing without error. */ {
if( lErrorOccurred == pdFALSE )
{
/* We have never seen an error so increment the counter. */
( *pulMemCheckTaskRunningCounter )++;
}
else
{
/* There has been an error so reset the counter so the check task
* can tell that an error occurred. */
*pulMemCheckTaskRunningCounter = mainCOUNT_INITIAL_VALUE;
}
pulMemCheckTaskRunningCounter = ( unsigned long * ) pvParameters; /* 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. */
for( ;; ) vTaskSuspendAll();
{ {
if( lErrorOccurred == pdFALSE ) pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );
{
/* We have never seen an error so increment the counter. */
( *pulMemCheckTaskRunningCounter )++;
}
else
{
/* There has been an error so reset the counter so the check task
can tell that an error occurred. */
*pulMemCheckTaskRunningCounter = mainCOUNT_INITIAL_VALUE;
}
/* Allocate some memory - just to give the allocator some extra if( pvMem1 == NULL )
exercise. This has to be in a critical section to ensure the {
task does not get deleted while it has memory allocated. */ lErrorOccurred = pdTRUE;
}
else
{
memset( pvMem1, 0xaa, mainMEM_CHECK_SIZE_1 );
vPortFree( pvMem1 );
}
}
xTaskResumeAll();
vTaskSuspendAll(); /* Again - with a different size block. */
{ vTaskSuspendAll();
pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 ); {
pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 );
if( pvMem1 == NULL ) if( pvMem2 == NULL )
{ {
lErrorOccurred = pdTRUE; lErrorOccurred = pdTRUE;
} }
else else
{ {
memset( pvMem1, 0xaa, mainMEM_CHECK_SIZE_1 ); memset( pvMem2, 0xaa, mainMEM_CHECK_SIZE_2 );
vPortFree( pvMem1 ); vPortFree( pvMem2 );
} }
} }
xTaskResumeAll(); xTaskResumeAll();
/* Again - with a different size block. */ /* Again - with a different size block. */
vTaskSuspendAll(); vTaskSuspendAll();
{ {
pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 ); pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );
if( pvMem2 == NULL ) if( pvMem3 == NULL )
{ {
lErrorOccurred = pdTRUE; lErrorOccurred = pdTRUE;
} }
else else
{ {
memset( pvMem2, 0xaa, mainMEM_CHECK_SIZE_2 ); memset( pvMem3, 0xaa, mainMEM_CHECK_SIZE_3 );
vPortFree( pvMem2 ); vPortFree( pvMem3 );
} }
} }
xTaskResumeAll(); xTaskResumeAll();
}
/* Again - with a different size block. */
vTaskSuspendAll();
{
pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );
if( pvMem3 == NULL )
{
lErrorOccurred = pdTRUE;
}
else
{
memset( pvMem3, 0xaa, mainMEM_CHECK_SIZE_3 );
vPortFree( pvMem3 );
}
}
xTaskResumeAll();
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvIndicateError( void ) static void prvIndicateError( void )
{ {
/* The check task has found an error in one of the other tasks. /* The check task has found an error in one of the other tasks.
Set the LEDs to a state that indicates this. */ * Set the LEDs to a state that indicates this. */
vParTestSetLED(mainERROR_LED,pdTRUE); vParTestSetLED( mainERROR_LED, pdTRUE );
for(;;)
{
#if( BOARD==EVK1100 )
vParTestToggleLED( mainCHECK_TASK_LED );
vTaskDelay( mainERROR_FLASH_RATE );
#endif
#if ( BOARD==EVK1101 )
vParTestSetLED( 0, pdTRUE );
vParTestSetLED( 1, pdTRUE );
vParTestSetLED( 2, pdTRUE );
vParTestSetLED( 3, pdTRUE );
#endif
}
}
for( ; ; )
{
#if ( BOARD == EVK1100 )
vParTestToggleLED( mainCHECK_TASK_LED );
vTaskDelay( mainERROR_FLASH_RATE );
#endif
#if ( BOARD == EVK1101 )
vParTestSetLED( 0, pdTRUE );
vParTestSetLED( 1, pdTRUE );
vParTestSetLED( 2, pdTRUE );
vParTestSetLED( 3, pdTRUE );
#endif
}
}

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -44,45 +44,45 @@
*/ */
/* /*
Changes from V1.2.0 * Changes from V1.2.0
*
+ Changed the baud rate for the serial test from 19200 to 57600. + Changed the baud rate for the serial test from 19200 to 57600.
+
Changes from V1.2.3 + Changes from V1.2.3
+
+ The integer and comtest tasks are now used when the cooperative scheduler + The integer and comtest tasks are now used when the cooperative scheduler
is being used. Previously they were only used with the preemptive + is being used. Previously they were only used with the preemptive
scheduler. + scheduler.
+
Changes from V1.2.5 + Changes from V1.2.5
+
+ Set the baud rate to 38400. This has a smaller error percentage with an + Set the baud rate to 38400. This has a smaller error percentage with an
8MHz clock (according to the manual). + 8MHz clock (according to the manual).
+
Changes from V2.0.0 + Changes from V2.0.0
+
+ Delay periods are now specified using variables and constants of + Delay periods are now specified using variables and constants of
TickType_t rather than unsigned long. + TickType_t rather than unsigned long.
+
Changes from V2.2.0 + Changes from V2.2.0
+
+ File can now be built using either the IAR or WinAVR compiler. + File can now be built using either the IAR or WinAVR compiler.
+
Changes from V2.6.1 + Changes from V2.6.1
+
+ The IAR and WinAVR AVR ports are now maintained separately. + The IAR and WinAVR AVR ports are now maintained separately.
+
Changes from V4.0.5 + Changes from V4.0.5
+
+ Modified to demonstrate the use of co-routines. + Modified to demonstrate the use of co-routines.
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef GCC_MEGA_AVR #ifdef GCC_MEGA_AVR
/* EEPROM routines used only with the WinAVR compiler. */ /* EEPROM routines used only with the WinAVR compiler. */
#include <avr/eeprom.h> #include <avr/eeprom.h>
#endif #endif
/* Scheduler include files. */ /* Scheduler include files. */
@ -101,39 +101,39 @@ Changes from V4.0.5
#include "regtest.h" #include "regtest.h"
/* Priority definitions for most of the tasks in the demo application. Some /* Priority definitions for most of the tasks in the demo application. Some
tasks just use the idle priority. */ * tasks just use the idle priority. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_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 ) 38400 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 38400 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 4 ) #define mainCOM_TEST_LED ( 4 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 7 ) #define mainCHECK_TASK_LED ( 7 )
/* The period between executions of the check task. */ /* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
/* An address in the EEPROM used to count resets. This is used to check that /* An address in the EEPROM used to count resets. This is used to check that
the demo application is not unexpectedly resetting. */ * the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 ) #define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 )
/* The number of coroutines to create. */ /* The number of coroutines to create. */
#define mainNUM_FLASH_COROUTINES ( 3 ) #define mainNUM_FLASH_COROUTINES ( 3 )
/* /*
* The task function for the "Check" task. * The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks the unique counts of other tasks to ensure they are still operational. * Checks the unique counts of other tasks to ensure they are still operational.
@ -150,124 +150,125 @@ static void prvIncrementResetCount( void );
/* /*
* Idle hook is used to scheduler co-routines. * Idle hook is used to scheduler co-routines.
*/ */
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
short main( void ) short main( void )
{ {
prvIncrementResetCount(); prvIncrementResetCount();
/* Setup the LED's for output. */ /* Setup the LED's for output. */
vParTestInitialise(); vParTestInitialise();
/* Create the standard demo tasks. */ /* Create the standard demo tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartRegTestTasks(); vStartRegTestTasks();
/* Create the tasks defined within this file. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Create the co-routines that flash the LED's. */ /* Create the tasks defined within this file. */
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* 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. */
vTaskStartScheduler();
return 0; /* Create the co-routines that flash the LED's. */
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. */
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. */ /* The parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */ * operating without error. */
for( ;; ) for( ; ; )
{ {
vTaskDelay( mainCHECK_PERIOD ); vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the /* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important - * integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */ * see the demo application documentation for more info. */
ulDummyVariable *= 3; ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning(); prvCheckOtherTasksAreStillRunning();
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckOtherTasksAreStillRunning( void ) static void prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreComTestTasksStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xAreRegTestTasksStillRunning() != pdTRUE ) if( xAreRegTestTasksStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xErrorHasOccurred == pdFALSE ) if( xErrorHasOccurred == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvIncrementResetCount( void ) static void prvIncrementResetCount( void )
{ {
unsigned char ucCount; unsigned char ucCount;
const unsigned char ucReadBit = ( unsigned char ) 0x01; const unsigned char ucReadBit = ( unsigned char ) 0x01;
const unsigned char ucWrite1 = ( unsigned char ) 0x04; const unsigned char ucWrite1 = ( unsigned char ) 0x04;
const unsigned char ucWrite2 = ( unsigned char ) 0x02; const unsigned char ucWrite2 = ( unsigned char ) 0x02;
/* Increment the EEPROM value at 0x00. /* Increment the EEPROM value at 0x00.
*
Setup the EEPROM address. */ * Setup the EEPROM address. */
EEARH = 0x00; EEARH = 0x00;
EEARL = 0x00; EEARL = 0x00;
/* Set the read enable bit. */
EECR |= ucReadBit;
/* Wait for the read. */ /* Set the read enable bit. */
while( EECR & ucReadBit ); EECR |= ucReadBit;
/* The byte is ready. */ /* Wait for the read. */
ucCount = EEDR; while( EECR & ucReadBit )
{
/* Increment the reset count, then write the byte back. */ }
ucCount++;
EEDR = ucCount; /* The byte is ready. */
EECR = ucWrite1; ucCount = EEDR;
EECR = ( ucWrite1 | ucWrite2 );
/* Increment the reset count, then write the byte back. */
ucCount++;
EEDR = ucCount;
EECR = ucWrite1;
EECR = ( ucWrite1 | ucWrite2 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
vCoRoutineSchedule(); vCoRoutineSchedule();
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -44,42 +44,42 @@
*/ */
/* /*
Changes from V1.2.0 * Changes from V1.2.0
*
+ Changed the baud rate for the serial test from 19200 to 57600. + Changed the baud rate for the serial test from 19200 to 57600.
+
Changes from V1.2.3 + Changes from V1.2.3
+
+ The integer and comtest tasks are now used when the cooperative scheduler + The integer and comtest tasks are now used when the cooperative scheduler
is being used. Previously they were only used with the preemptive + is being used. Previously they were only used with the preemptive
scheduler. + scheduler.
+
Changes from V1.2.5 + Changes from V1.2.5
+
+ Set the baud rate to 38400. This has a smaller error percentage with an + Set the baud rate to 38400. This has a smaller error percentage with an
8MHz clock (according to the manual). + 8MHz clock (according to the manual).
+
Changes from V2.0.0 + Changes from V2.0.0
+
+ Delay periods are now specified using variables and constants of + Delay periods are now specified using variables and constants of
TickType_t rather than unsigned long. + TickType_t rather than unsigned long.
+
Changes from V2.6.1 + Changes from V2.6.1
+
+ The IAR and WinAVR AVR ports are now maintained separately. + The IAR and WinAVR AVR ports are now maintained separately.
+
Changes from V4.0.5 + Changes from V4.0.5
+
+ Modified to demonstrate the use of co-routines. + Modified to demonstrate the use of co-routines.
+
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef GCC_MEGA_AVR #ifdef GCC_MEGA_AVR
/* EEPROM routines used only with the WinAVR compiler. */ /* EEPROM routines used only with the WinAVR compiler. */
#include <avr/eeprom.h> #include <avr/eeprom.h>
#endif #endif
/* Scheduler include files. */ /* Scheduler include files. */
@ -98,39 +98,39 @@ Changes from V4.0.5
#include "regtest.h" #include "regtest.h"
/* Priority definitions for most of the tasks in the demo application. Some /* Priority definitions for most of the tasks in the demo application. Some
tasks just use the idle priority. */ * tasks just use the idle priority. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_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 ) 38400 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 38400 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 4 ) #define mainCOM_TEST_LED ( 4 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 7 ) #define mainCHECK_TASK_LED ( 7 )
/* The period between executions of the check task. */ /* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
/* An address in the EEPROM used to count resets. This is used to check that /* An address in the EEPROM used to count resets. This is used to check that
the demo application is not unexpectedly resetting. */ * the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 ) #define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 )
/* The number of coroutines to create. */ /* The number of coroutines to create. */
#define mainNUM_FLASH_COROUTINES ( 3 ) #define mainNUM_FLASH_COROUTINES ( 3 )
/* /*
* The task function for the "Check" task. * The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks the unique counts of other tasks to ensure they are still operational. * Checks the unique counts of other tasks to ensure they are still operational.
@ -153,100 +153,99 @@ void vApplicationIdleHook( void );
short main( void ) short main( void )
{ {
prvIncrementResetCount(); prvIncrementResetCount();
/* Setup the LED's for output. */ /* Setup the LED's for output. */
vParTestInitialise(); vParTestInitialise();
/* Create the standard demo tasks. */ /* Create the standard demo tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartRegTestTasks(); vStartRegTestTasks();
/* Create the tasks defined within this file. */ /* Create the tasks defined within this file. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Create the co-routines that flash the LED's. */ /* Create the co-routines that flash the LED's. */
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION /* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define * as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */ * configUSE_PREEMPTION as 0. */
vTaskStartScheduler(); vTaskStartScheduler();
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
static volatile unsigned long ulDummyVariable = 3UL; static volatile unsigned long ulDummyVariable = 3UL;
/* The parameters are not used. */ /* The parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */ * operating without error. */
for( ;; ) for( ; ; )
{ {
vTaskDelay( mainCHECK_PERIOD ); vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the /* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important - * integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */ * see the demo application documentation for more info. */
ulDummyVariable *= 3; ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning(); prvCheckOtherTasksAreStillRunning();
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckOtherTasksAreStillRunning( void ) static void prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreComTestTasksStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xAreRegTestTasksStillRunning() != pdTRUE ) if( xAreRegTestTasksStillRunning() != pdTRUE )
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xErrorHasOccurred == pdFALSE ) if( xErrorHasOccurred == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvIncrementResetCount( void ) static void prvIncrementResetCount( void )
{ {
unsigned char ucCount; unsigned char ucCount;
eeprom_read_block( &ucCount, mainRESET_COUNT_ADDRESS, sizeof( ucCount ) ); eeprom_read_block( &ucCount, mainRESET_COUNT_ADDRESS, sizeof( ucCount ) );
ucCount++; ucCount++;
eeprom_write_byte( mainRESET_COUNT_ADDRESS, ucCount ); eeprom_write_byte( mainRESET_COUNT_ADDRESS, ucCount );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
vCoRoutineSchedule(); vCoRoutineSchedule();
} }

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -37,7 +37,7 @@
#include "regtest.h" #include "regtest.h"
/* Priority definitions for most of the tasks in the demo application. Some /* Priority definitions for most of the tasks in the demo application. Some
tasks just use the idle priority. */ * tasks just use the idle priority. */
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
@ -46,20 +46,20 @@ tasks just use the idle priority. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 6 ) #define mainCOM_TEST_LED ( 6 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 5 ) #define mainCHECK_TASK_LED ( 5 )
/* The period between executions of the check task. */ /* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS )
/* An address in the EEPROM used to count resets. This is used to check that /* An address in the EEPROM used to count resets. This is used to check that
the demo application is not unexpectedly resetting. */ * the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( 0x1400 ) #define mainRESET_COUNT_ADDRESS ( 0x1400 )
/* The number of coroutines to create. */ /* The number of coroutines to create. */
@ -68,7 +68,7 @@ the demo application is not unexpectedly resetting. */
/* /*
* The task function for the "Check" task. * The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks the unique counts of other tasks to ensure they are still operational. * Checks the unique counts of other tasks to ensure they are still operational.
@ -91,16 +91,16 @@ void main_minimal( void )
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartRegTestTasks(); vStartRegTestTasks();
/* Create the tasks defined within this file. */ /* Create the tasks defined within this file. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Create the co-routines that flash the LED's. */ /* Create the co-routines that flash the LED's. */
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION /* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define * as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */ * configUSE_PREEMPTION as 0. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
@ -109,28 +109,28 @@ void init_minimal( void )
/* Configure UART pins: PB0 Rx, PB1 Tx */ /* Configure UART pins: PB0 Rx, PB1 Tx */
PORTB.DIR &= ~PIN1_bm; PORTB.DIR &= ~PIN1_bm;
PORTB.DIR |= PIN0_bm; PORTB.DIR |= PIN0_bm;
vParTestInitialise(); vParTestInitialise();
} }
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
static volatile unsigned long ulDummyVariable = 3UL; static volatile unsigned long ulDummyVariable = 3UL;
/* The parameters are not used. */ /* The parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */ * operating without error. */
for( ;; ) for( ; ; )
{ {
vTaskDelay( mainCHECK_PERIOD ); vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the /* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important - * integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */ * see the demo application documentation for more info. */
ulDummyVariable *= 3; ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning(); prvCheckOtherTasksAreStillRunning();
} }
} }
@ -138,7 +138,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void ) static void prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -159,11 +159,11 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xErrorHasOccurred == pdFALSE ) if( xErrorHasOccurred == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
@ -171,7 +171,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void ) static void prvIncrementResetCount( void )
{ {
static unsigned char __eeprom ucResetCount @ mainRESET_COUNT_ADDRESS; static unsigned char __eeprom ucResetCount @ mainRESET_COUNT_ADDRESS;
ucResetCount++; ucResetCount++;
} }

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -38,7 +38,7 @@
#include "regtest.h" #include "regtest.h"
/* Priority definitions for most of the tasks in the demo application. Some /* Priority definitions for most of the tasks in the demo application. Some
tasks just use the idle priority. */ * tasks just use the idle priority. */
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
@ -47,20 +47,20 @@ tasks just use the idle priority. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 6 ) #define mainCOM_TEST_LED ( 6 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 5 ) #define mainCHECK_TASK_LED ( 5 )
/* The period between executions of the check task. */ /* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS )
/* An address in the EEPROM used to count resets. This is used to check that /* An address in the EEPROM used to count resets. This is used to check that
the demo application is not unexpectedly resetting. */ * the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( 0x1400 ) #define mainRESET_COUNT_ADDRESS ( 0x1400 )
/* The number of coroutines to create. */ /* The number of coroutines to create. */
@ -69,7 +69,7 @@ the demo application is not unexpectedly resetting. */
/* /*
* The task function for the "Check" task. * The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks the unique counts of other tasks to ensure they are still operational. * Checks the unique counts of other tasks to ensure they are still operational.
@ -92,16 +92,16 @@ void main_minimal( void )
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartRegTestTasks(); vStartRegTestTasks();
/* Create the tasks defined within this file. */ /* Create the tasks defined within this file. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Create the co-routines that flash the LED's. */ /* Create the co-routines that flash the LED's. */
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION /* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define * as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */ * configUSE_PREEMPTION as 0. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
@ -110,28 +110,28 @@ void init_minimal( void )
/* Configure UART pins: PB0 Rx, PB1 Tx */ /* Configure UART pins: PB0 Rx, PB1 Tx */
PORTB.DIR &= ~PIN1_bm; PORTB.DIR &= ~PIN1_bm;
PORTB.DIR |= PIN0_bm; PORTB.DIR |= PIN0_bm;
vParTestInitialise(); vParTestInitialise();
} }
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
static volatile unsigned long ulDummyVariable = 3UL; static volatile unsigned long ulDummyVariable = 3UL;
/* The parameters are not used. */ /* The parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */ * operating without error. */
for( ;; ) for( ; ; )
{ {
vTaskDelay( mainCHECK_PERIOD ); vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the /* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important - * integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */ * see the demo application documentation for more info. */
ulDummyVariable *= 3; ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning(); prvCheckOtherTasksAreStillRunning();
} }
} }
@ -139,7 +139,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void ) static void prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -160,11 +160,11 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xErrorHasOccurred == pdFALSE ) if( xErrorHasOccurred == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
@ -172,7 +172,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void ) static void prvIncrementResetCount( void )
{ {
unsigned char ucResetCount; unsigned char ucResetCount;
eeprom_read_block( &ucResetCount, ( void * ) mainRESET_COUNT_ADDRESS, sizeof( ucResetCount ) ); eeprom_read_block( &ucResetCount, ( void * ) mainRESET_COUNT_ADDRESS, sizeof( ucResetCount ) );
ucResetCount++; ucResetCount++;

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -37,7 +37,7 @@
#include "regtest.h" #include "regtest.h"
/* Priority definitions for most of the tasks in the demo application. Some /* Priority definitions for most of the tasks in the demo application. Some
tasks just use the idle priority. */ * tasks just use the idle priority. */
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
@ -46,20 +46,20 @@ tasks just use the idle priority. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 7 ) #define mainCOM_TEST_LED ( 7 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 6 ) #define mainCHECK_TASK_LED ( 6 )
/* The period between executions of the check task. */ /* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS )
/* An address in the EEPROM used to count resets. This is used to check that /* An address in the EEPROM used to count resets. This is used to check that
the demo application is not unexpectedly resetting. */ * the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( 0x1400 ) #define mainRESET_COUNT_ADDRESS ( 0x1400 )
/* The number of coroutines to create. */ /* The number of coroutines to create. */
@ -68,7 +68,7 @@ the demo application is not unexpectedly resetting. */
/* /*
* The task function for the "Check" task. * The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks the unique counts of other tasks to ensure they are still operational. * Checks the unique counts of other tasks to ensure they are still operational.
@ -91,16 +91,16 @@ void main_minimal( void )
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartRegTestTasks(); vStartRegTestTasks();
/* Create the tasks defined within this file. */ /* Create the tasks defined within this file. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Create the co-routines that flash the LED's. */ /* Create the co-routines that flash the LED's. */
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION /* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define * as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */ * configUSE_PREEMPTION as 0. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
@ -109,28 +109,28 @@ void init_minimal( void )
/* Configure UART pins: PC1 Rx, PC0 Tx */ /* Configure UART pins: PC1 Rx, PC0 Tx */
PORTC.DIR &= ~PIN0_bm; PORTC.DIR &= ~PIN0_bm;
PORTC.DIR |= PIN1_bm; PORTC.DIR |= PIN1_bm;
vParTestInitialise(); vParTestInitialise();
} }
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
static volatile unsigned long ulDummyVariable = 3UL; static volatile unsigned long ulDummyVariable = 3UL;
/* The parameters are not used. */ /* The parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */ * operating without error. */
for( ;; ) for( ; ; )
{ {
vTaskDelay( mainCHECK_PERIOD ); vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the /* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important - * integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */ * see the demo application documentation for more info. */
ulDummyVariable *= 3; ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning(); prvCheckOtherTasksAreStillRunning();
} }
} }
@ -138,7 +138,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void ) static void prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -159,11 +159,11 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xErrorHasOccurred == pdFALSE ) if( xErrorHasOccurred == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
@ -171,7 +171,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void ) static void prvIncrementResetCount( void )
{ {
static unsigned char __eeprom ucResetCount @ mainRESET_COUNT_ADDRESS; static unsigned char __eeprom ucResetCount @ mainRESET_COUNT_ADDRESS;
ucResetCount++; ucResetCount++;
} }

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -37,7 +37,7 @@
#include "regtest.h" #include "regtest.h"
/* Priority definitions for most of the tasks in the demo application. Some /* Priority definitions for most of the tasks in the demo application. Some
tasks just use the idle priority. */ * tasks just use the idle priority. */
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
@ -46,20 +46,20 @@ tasks just use the idle priority. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 9600 )
/* LED used by the serial port tasks. This is toggled on each character Tx, /* LED used by the serial port tasks. This is toggled on each character Tx,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */ * and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 7 ) #define mainCOM_TEST_LED ( 7 )
/* LED that is toggled by the check task. The check task periodically checks /* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found * that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles * the LED is toggled. If an error is found at any time the LED is never toggles
again. */ * again. */
#define mainCHECK_TASK_LED ( 6 ) #define mainCHECK_TASK_LED ( 6 )
/* The period between executions of the check task. */ /* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS ) #define mainCHECK_PERIOD ( ( TickType_t ) 1000 / portTICK_PERIOD_MS )
/* An address in the EEPROM used to count resets. This is used to check that /* An address in the EEPROM used to count resets. This is used to check that
the demo application is not unexpectedly resetting. */ * the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( 0x1400 ) #define mainRESET_COUNT_ADDRESS ( 0x1400 )
/* The number of coroutines to create. */ /* The number of coroutines to create. */
@ -68,7 +68,7 @@ the demo application is not unexpectedly resetting. */
/* /*
* The task function for the "Check" task. * The task function for the "Check" task.
*/ */
static void vErrorChecks( void *pvParameters ); static void vErrorChecks( void * pvParameters );
/* /*
* Checks the unique counts of other tasks to ensure they are still operational. * Checks the unique counts of other tasks to ensure they are still operational.
@ -91,16 +91,16 @@ void main_minimal( void )
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartRegTestTasks(); vStartRegTestTasks();
/* Create the tasks defined within this file. */ /* Create the tasks defined within this file. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Create the co-routines that flash the LED's. */ /* Create the co-routines that flash the LED's. */
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* In this port, to use preemptive scheduler define configUSE_PREEMPTION /* In this port, to use preemptive scheduler define configUSE_PREEMPTION
as 1 in portmacro.h. To use the cooperative scheduler define * as 1 in portmacro.h. To use the cooperative scheduler define
configUSE_PREEMPTION as 0. */ * configUSE_PREEMPTION as 0. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
@ -109,28 +109,28 @@ void init_minimal( void )
/* Configure UART pins: PC1 Rx, PC0 Tx */ /* Configure UART pins: PC1 Rx, PC0 Tx */
PORTC.DIR &= ~PIN0_bm; PORTC.DIR &= ~PIN0_bm;
PORTC.DIR |= PIN1_bm; PORTC.DIR |= PIN1_bm;
vParTestInitialise(); vParTestInitialise();
} }
static void vErrorChecks( void *pvParameters ) static void vErrorChecks( void * pvParameters )
{ {
static volatile unsigned long ulDummyVariable = 3UL; static volatile unsigned long ulDummyVariable = 3UL;
/* The parameters are not used. */ /* The parameters are not used. */
( void ) pvParameters; ( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */ * operating without error. */
for( ;; ) for( ; ; )
{ {
vTaskDelay( mainCHECK_PERIOD ); vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the /* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important - * integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */ * see the demo application documentation for more info. */
ulDummyVariable *= 3; ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning(); prvCheckOtherTasksAreStillRunning();
} }
} }
@ -138,7 +138,7 @@ static volatile unsigned long ulDummyVariable = 3UL;
static void prvCheckOtherTasksAreStillRunning( void ) static void prvCheckOtherTasksAreStillRunning( void )
{ {
static portBASE_TYPE xErrorHasOccurred = pdFALSE; static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
@ -159,11 +159,11 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
{ {
xErrorHasOccurred = pdTRUE; xErrorHasOccurred = pdTRUE;
} }
if( xErrorHasOccurred == pdFALSE ) if( xErrorHasOccurred == pdFALSE )
{ {
/* Toggle the LED if everything is okay so we know if an error occurs even if not /* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */ * using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED ); vParTestToggleLED( mainCHECK_TASK_LED );
} }
} }
@ -171,7 +171,7 @@ static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static void prvIncrementResetCount( void ) static void prvIncrementResetCount( void )
{ {
unsigned char ucResetCount; unsigned char ucResetCount;
eeprom_read_block( &ucResetCount, ( void * ) mainRESET_COUNT_ADDRESS, sizeof( ucResetCount ) ); eeprom_read_block( &ucResetCount, ( void * ) mainRESET_COUNT_ADDRESS, sizeof( ucResetCount ) );
ucResetCount++; ucResetCount++;

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -82,8 +82,8 @@
#include "chip.h" #include "chip.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -97,182 +97,186 @@ static void prvSetupHardware( void );
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
*/ */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
extern void main_blinky( void ); extern void main_blinky( void );
#else #else
extern void main_full( void ); extern void main_full( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port /* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port
layer. */ * layer. */
void vApplicationIRQHandler( void ); void vApplicationIRQHandler( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
{ {
/* Configure the hardware ready to run the demo. */ /* Configure the hardware ready to run the demo. */
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
#else #else
{ {
main_full(); main_full();
} }
#endif #endif
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Disable watchdog */ /* Disable watchdog */
wdt_disable( ); wdt_disable();
/* Set protect mode in the AIC for easier debugging. */ /* Set protect mode in the AIC for easier debugging. */
AIC->AIC_DCR |= AIC_DCR_PROT; AIC->AIC_DCR |= AIC_DCR_PROT;
/* Configure ports used by LEDs. */ /* Configure ports used by LEDs. */
vParTestInitialise(); vParTestInitialise();
#if defined (ddram) #if defined( ddram )
MMU_Initialize( ( uint32_t * ) 0x30C000 ); MMU_Initialize( ( uint32_t * ) 0x30C000 );
CP15_EnableMMU(); CP15_EnableMMU();
CP15_EnableDcache(); CP15_EnableDcache();
CP15_EnableIcache(); CP15_EnableIcache();
#endif #endif
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
( void ) xFreeHeapSpace; ( void ) xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( const char * pcFile, unsigned long ulLine ) void vAssertCalled( const char * pcFile,
unsigned long ulLine )
{ {
volatile unsigned long ul = 0; volatile unsigned long ul = 0;
( void ) pcFile; ( void ) pcFile;
( void ) ulLine; ( void ) ulLine;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Set ul to a non-zero value using the debugger to step out of this /* Set ul to a non-zero value using the debugger to step out of this
function. */ * function. */
while( ul == 0 ) while( ul == 0 )
{ {
portNOP(); portNOP();
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo(); vQueueOverwritePeriodicISRDemo();
/* Call the periodic event group from ISR demo. */ /* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing(); vPeriodicEventGroupsProcessing();
} }
#endif #endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The function called by the RTOS port layer after it has managed interrupt /* The function called by the RTOS port layer after it has managed interrupt
entry. */ * entry. */
void vApplicationIRQHandler( void ) void vApplicationIRQHandler( void )
{ {
typedef void (*ISRFunction_t)( void ); typedef void (* ISRFunction_t)( void );
ISRFunction_t pxISRFunction; ISRFunction_t pxISRFunction;
volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS; volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
/* Obtain the address of the interrupt handler from the AIR. */ /* Obtain the address of the interrupt handler from the AIR. */
pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR; pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR;
/* Write back to the SAMA5's interrupt controller's IVR register in case the /* Write back to the SAMA5's interrupt controller's IVR register in case the
CPU is in protect mode. If the interrupt controller is not in protect mode * CPU is in protect mode. If the interrupt controller is not in protect mode
then this write is not necessary. */ * then this write is not necessary. */
*pulAIC_IVR = ( uint32_t ) pxISRFunction; *pulAIC_IVR = ( uint32_t ) pxISRFunction;
/* Ensure the write takes before re-enabling interrupts. */ /* Ensure the write takes before re-enabling interrupts. */
__DSB(); __DSB();
__ISB(); __ISB();
__enable_irq(); __enable_irq();
/* Call the installed ISR. */ /* Call the installed ISR. */
pxISRFunction(); pxISRFunction();
} }
/* Keep the linker quiet. */ /* Keep the linker quiet. */
size_t __write(int, const unsigned char *, size_t); size_t __write( int,
size_t __write(int f, const unsigned char *p, size_t s) const unsigned char *,
size_t );
size_t __write( int f,
const unsigned char * p,
size_t s )
{ {
(void) f; ( void ) f;
(void) p; ( void ) p;
(void) s; ( void ) s;
return 0; return 0;
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -57,8 +57,8 @@
#include "chip.h" #include "chip.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -72,42 +72,43 @@ static void prvSetupHardware( void );
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
*/ */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
extern void main_blinky( void ); extern void main_blinky( void );
#else #else
extern void main_full( void ); extern void main_full( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port /* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port
layer. */ * layer. */
void vApplicationIRQHandler( void ); void vApplicationIRQHandler( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
{ {
/* Configure the hardware ready to run the demo. */ /* Configure the hardware ready to run the demo. */
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
#else #else
{ {
main_full(); main_full();
} }
#endif #endif
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -116,127 +117,127 @@ static void prvSetupHardware( void )
/* Disable watchdog */ /* Disable watchdog */
WDT_Disable( WDT ); WDT_Disable( WDT );
/* Set protect mode in the AIC for easier debugging. */ /* Set protect mode in the AIC for easier debugging. */
AIC->AIC_DCR |= AIC_DCR_PROT; AIC->AIC_DCR |= AIC_DCR_PROT;
/* Configure ports used by LEDs. */ /* Configure ports used by LEDs. */
vParTestInitialise(); vParTestInitialise();
#if defined (ddram) #if defined( ddram )
MMU_Initialize( ( uint32_t * ) 0x30C000 ); MMU_Initialize( ( uint32_t * ) 0x30C000 );
CP15_EnableMMU(); CP15_EnableMMU();
CP15_EnableDcache(); CP15_EnableDcache();
CP15_EnableIcache(); CP15_EnableIcache();
#endif #endif
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
( void ) xFreeHeapSpace; ( void ) xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( const char * pcFile, unsigned long ulLine ) void vAssertCalled( const char * pcFile,
unsigned long ulLine )
{ {
volatile unsigned long ul = 0; volatile unsigned long ul = 0;
( void ) pcFile; ( void ) pcFile;
( void ) ulLine; ( void ) ulLine;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Set ul to a non-zero value using the debugger to step out of this /* Set ul to a non-zero value using the debugger to step out of this
function. */ * function. */
while( ul == 0 ) while( ul == 0 )
{ {
portNOP(); portNOP();
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo(); vQueueOverwritePeriodicISRDemo();
/* Call the periodic event group from ISR demo. */ /* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing(); vPeriodicEventGroupsProcessing();
} }
#endif #endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The function called by the RTOS port layer after it has managed interrupt /* The function called by the RTOS port layer after it has managed interrupt
entry. */ * entry. */
void vApplicationIRQHandler( void ) void vApplicationIRQHandler( void )
{ {
typedef void (*ISRFunction_t)( void ); typedef void (* ISRFunction_t)( void );
ISRFunction_t pxISRFunction; ISRFunction_t pxISRFunction;
volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS; volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
/* Obtain the address of the interrupt handler from the AIR. */ /* Obtain the address of the interrupt handler from the AIR. */
pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR; pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR;
/* Write back to the SAMA5's interrupt controller's IVR register in case the /* Write back to the SAMA5's interrupt controller's IVR register in case the
CPU is in protect mode. If the interrupt controller is not in protect mode * CPU is in protect mode. If the interrupt controller is not in protect mode
then this write is not necessary. */ * then this write is not necessary. */
*pulAIC_IVR = ( uint32_t ) pxISRFunction; *pulAIC_IVR = ( uint32_t ) pxISRFunction;
/* Ensure the write takes before re-enabling interrupts. */ /* Ensure the write takes before re-enabling interrupts. */
__DSB(); __DSB();
__ISB(); __ISB();
__enable_irq(); __enable_irq();
/* Call the installed ISR. */ /* Call the installed ISR. */
pxISRFunction(); pxISRFunction();
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -57,8 +57,8 @@
#include "chip.h" #include "chip.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -71,43 +71,44 @@ static void prvSetupHardware( void );
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
*/ */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
extern void main_blinky( void ); extern void main_blinky( void );
#else #else
extern void main_full( void ); extern void main_full( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port /* Prototype for the IRQ handler called by the generic Cortex-A5 RTOS port
layer. */ * layer. */
void vApplicationIRQHandler( void ); void vApplicationIRQHandler( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
{ {
/* Configure the hardware ready to run the demo. */ /* Configure the hardware ready to run the demo. */
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
#else #else
{ {
main_full(); main_full();
} }
#endif #endif
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -116,129 +117,130 @@ static void prvSetupHardware( void )
/* Disable watchdog */ /* Disable watchdog */
WDT_Disable( WDT ); WDT_Disable( WDT );
/* Set protect mode in the AIC for easier debugging. THIS IS COMMENTED OUT /* Set protect mode in the AIC for easier debugging. THIS IS COMMENTED OUT
AS IT RESULTS IN SPURIOUS INTERRUPTS. * AS IT RESULTS IN SPURIOUS INTERRUPTS.
AIC->AIC_DCR |= AIC_DCR_PROT; */ * AIC->AIC_DCR |= AIC_DCR_PROT; */
/* Configure ports used by LEDs. */ /* Configure ports used by LEDs. */
vParTestInitialise(); vParTestInitialise();
#if defined (ddram) #if defined( ddram )
{ {
MMU_Initialize( ( uint32_t * ) 0x20C000 ); MMU_Initialize( ( uint32_t * ) 0x20C000 );
CP15_EnableMMU(); CP15_EnableMMU();
CP15_EnableDcache(); CP15_EnableDcache();
CP15_EnableIcache(); CP15_EnableIcache();
} }
#endif #endif
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
( void ) xFreeHeapSpace; ( void ) xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( const char * pcFile, unsigned long ulLine ) void vAssertCalled( const char * pcFile,
unsigned long ulLine )
{ {
volatile unsigned long ul = 0; volatile unsigned long ul = 0;
( void ) pcFile; ( void ) pcFile;
( void ) ulLine; ( void ) ulLine;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Set ul to a non-zero value using the debugger to step out of this /* Set ul to a non-zero value using the debugger to step out of this
function. */ * function. */
while( ul == 0 ) while( ul == 0 )
{ {
portNOP(); portNOP();
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo(); vQueueOverwritePeriodicISRDemo();
/* Call the periodic event group from ISR demo. */ /* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing(); vPeriodicEventGroupsProcessing();
} }
#endif #endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The function called by the RTOS port layer after it has managed interrupt /* The function called by the RTOS port layer after it has managed interrupt
entry. */ * entry. */
void vApplicationIRQHandler( void ) void vApplicationIRQHandler( void )
{ {
typedef void (*ISRFunction_t)( void ); typedef void (* ISRFunction_t)( void );
ISRFunction_t pxISRFunction; ISRFunction_t pxISRFunction;
volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS; volatile uint32_t * pulAIC_IVR = ( uint32_t * ) configINTERRUPT_VECTOR_ADDRESS;
/* Obtain the address of the interrupt handler from the AIR. */ /* Obtain the address of the interrupt handler from the AIR. */
pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR; pxISRFunction = ( ISRFunction_t ) *pulAIC_IVR;
/* Write back to the SAMA5's interrupt controller's IVR register in case the /* Write back to the SAMA5's interrupt controller's IVR register in case the
CPU is in protect mode. If the interrupt controller is not in protect mode * CPU is in protect mode. If the interrupt controller is not in protect mode
then this write is not necessary. */ * then this write is not necessary. */
*pulAIC_IVR = ( uint32_t ) pxISRFunction; *pulAIC_IVR = ( uint32_t ) pxISRFunction;
/* Ensure the write takes before re-enabling interrupts. */ /* Ensure the write takes before re-enabling interrupts. */
__DSB(); __DSB();
__ISB(); __ISB();
__enable_irq(); __enable_irq();
/* Call the installed ISR. */ /* Call the installed ISR. */
pxISRFunction(); pxISRFunction();
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -75,7 +75,7 @@
* When mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0 the comprehensive test * When mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0 the comprehensive test
* and demo application will be run. * and demo application will be run.
*/ */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -89,240 +89,250 @@ static void prvSetupHardware( void );
* mainSELECTED_APPLICATION definition. * mainSELECTED_APPLICATION definition.
*/ */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
extern void main_blinky( void ); extern void main_blinky( void );
#else #else
extern void main_full( void ); extern void main_full( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configAPPLICATION_ALLOCATED_HEAP is set to 1 in FreeRTOSConfig.h so the /* configAPPLICATION_ALLOCATED_HEAP is set to 1 in FreeRTOSConfig.h so the
application can define the array used as the FreeRTOS heap. This is done so the * application can define the array used as the FreeRTOS heap. This is done so the
heap can be forced into fast internal RAM - useful because the stacks used by * heap can be forced into fast internal RAM - useful because the stacks used by
the tasks come from this space. */ * the tasks come from this space. */
uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__ ( ( section( ".oc_ram" ) ) ); uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__( ( section( ".oc_ram" ) ) );
/* FreeRTOS uses its own interrupt handler code. This code cannot use the array /* FreeRTOS uses its own interrupt handler code. This code cannot use the array
of handlers defined by the Altera drivers because the array is declared static, * of handlers defined by the Altera drivers because the array is declared static,
and so not accessible outside of the dirver's source file. Instead declare an * and so not accessible outside of the dirver's source file. Instead declare an
array for use by the FreeRTOS handler. See: * array for use by the FreeRTOS handler. See:
http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html. */ * http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html. */
static INT_DISPATCH_t xISRHandlers[ ALT_INT_PROVISION_INT_COUNT ]; static INT_DISPATCH_t xISRHandlers[ ALT_INT_PROVISION_INT_COUNT ];
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
{ {
/* Configure the hardware ready to run the demo. */ /* Configure the hardware ready to run the demo. */
prvSetupHardware(); prvSetupHardware();
/* The mainSELECTED_APPLICATION setting is described at the top /* The mainSELECTED_APPLICATION setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
#else #else
{ {
main_full(); main_full();
} }
#endif #endif
/* Don't expect to reach here. */ /* Don't expect to reach here. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
extern uint8_t __cs3_interrupt_vector; extern uint8_t __cs3_interrupt_vector;
uint32_t ulSCTLR, ulVectorTable = ( uint32_t ) &__cs3_interrupt_vector; uint32_t ulSCTLR, ulVectorTable = ( uint32_t ) &__cs3_interrupt_vector;
const uint32_t ulVBit = 13U; const uint32_t ulVBit = 13U;
alt_int_global_init(); alt_int_global_init();
alt_int_cpu_binary_point_set( 0 ); alt_int_cpu_binary_point_set( 0 );
/* Clear SCTLR.V for low vectors and map the vector table to the beginning /* Clear SCTLR.V for low vectors and map the vector table to the beginning
of the code. */ * of the code. */
__asm( "MRC p15, 0, %0, c1, c0, 0" : "=r" ( ulSCTLR ) ); __asm( "MRC p15, 0, %0, c1, c0, 0" : "=r" ( ulSCTLR ) );
ulSCTLR &= ~( 1 << ulVBit ); ulSCTLR &= ~( 1 << ulVBit );
__asm( "MCR p15, 0, %0, c1, c0, 0" : : "r" ( ulSCTLR ) ); __asm( "MCR p15, 0, %0, c1, c0, 0" : : "r" ( ulSCTLR ) );
__asm( "MCR p15, 0, %0, c12, c0, 0" : : "r" ( ulVectorTable ) ); __asm( "MCR p15, 0, %0, c12, c0, 0" : : "r" ( ulVectorTable ) );
cache_init(); cache_init();
mmu_init(); mmu_init();
/* GPIO for LEDs. ParTest is a historic name which used to stand for /* GPIO for LEDs. ParTest is a historic name which used to stand for
parallel port test. */ * parallel port test. */
vParTestInitialise(); vParTestInitialise();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
( void ) xFreeHeapSpace; ( void ) xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( const char * pcFile, unsigned long ulLine ) void vAssertCalled( const char * pcFile,
unsigned long ulLine )
{ {
volatile unsigned long ul = 0; volatile unsigned long ul = 0;
( void ) pcFile; ( void ) pcFile;
( void ) ulLine; ( void ) ulLine;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Set ul to a non-zero value using the debugger to step out of this /* Set ul to a non-zero value using the debugger to step out of this
function. */ * function. */
while( ul == 0 ) while( ul == 0 )
{ {
portNOP(); portNOP();
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 )
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo(); vQueueOverwritePeriodicISRDemo();
/* Call the periodic event group from ISR demo. */ /* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing(); vPeriodicEventGroupsProcessing();
/* Call the periodic test that uses mutexes form an interrupt. */ /* Call the periodic test that uses mutexes form an interrupt. */
vInterruptSemaphorePeriodicTest(); vInterruptSemaphorePeriodicTest();
} }
#endif #endif /* if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vConfigureTickInterrupt( void ) void vConfigureTickInterrupt( void )
{ {
alt_freq_t ulTempFrequency; alt_freq_t ulTempFrequency;
const alt_freq_t ulMicroSecondsPerSecond = 1000000UL; const alt_freq_t ulMicroSecondsPerSecond = 1000000UL;
void FreeRTOS_Tick_Handler( void );
/* Interrupts are disabled when this function is called. */ void FreeRTOS_Tick_Handler( void );
/* Initialise the general purpose timer modules. */ /* Interrupts are disabled when this function is called. */
alt_gpt_all_tmr_init();
/* ALT_CLK_MPU_PERIPH = mpu_periph_clk */ /* Initialise the general purpose timer modules. */
alt_clk_freq_get( ALT_CLK_MPU_PERIPH, &ulTempFrequency ); alt_gpt_all_tmr_init();
/* Use the local private timer. */ /* ALT_CLK_MPU_PERIPH = mpu_periph_clk */
alt_gpt_counter_set( ALT_GPT_CPU_PRIVATE_TMR, ulTempFrequency / configTICK_RATE_HZ ); alt_clk_freq_get( ALT_CLK_MPU_PERIPH, &ulTempFrequency );
/* Sanity check. */ /* Use the local private timer. */
configASSERT( alt_gpt_time_microsecs_get( ALT_GPT_CPU_PRIVATE_TMR ) == ( ulMicroSecondsPerSecond / configTICK_RATE_HZ ) ); alt_gpt_counter_set( ALT_GPT_CPU_PRIVATE_TMR, ulTempFrequency / configTICK_RATE_HZ );
/* Set to periodic mode. */ /* Sanity check. */
alt_gpt_mode_set( ALT_GPT_CPU_PRIVATE_TMR, ALT_GPT_RESTART_MODE_PERIODIC ); configASSERT( alt_gpt_time_microsecs_get( ALT_GPT_CPU_PRIVATE_TMR ) == ( ulMicroSecondsPerSecond / configTICK_RATE_HZ ) );
/* The timer can be started here as interrupts are disabled. */ /* Set to periodic mode. */
alt_gpt_tmr_start( ALT_GPT_CPU_PRIVATE_TMR ); alt_gpt_mode_set( ALT_GPT_CPU_PRIVATE_TMR, ALT_GPT_RESTART_MODE_PERIODIC );
/* Register the standard FreeRTOS Cortex-A tick handler as the timer's /* The timer can be started here as interrupts are disabled. */
interrupt handler. The handler clears the interrupt using the alt_gpt_tmr_start( ALT_GPT_CPU_PRIVATE_TMR );
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. */ /* Register the standard FreeRTOS Cortex-A tick handler as the timer's
alt_int_dist_priority_set( ALT_INT_INTERRUPT_PPI_TIMER_PRIVATE, portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); * 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 );
/* Ensure the interrupt is forwarded to the CPU. */ /* This tick interrupt must run at the lowest priority. */
alt_int_dist_priority_set( ALT_INT_INTERRUPT_PPI_TIMER_PRIVATE, portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
/* Ensure the interrupt is forwarded to the CPU. */
alt_int_dist_enable( ALT_INT_INTERRUPT_PPI_TIMER_PRIVATE ); alt_int_dist_enable( ALT_INT_INTERRUPT_PPI_TIMER_PRIVATE );
/* Finally, enable the interrupt. */ /* Finally, enable the interrupt. */
alt_gpt_int_clear_pending( ALT_GPT_CPU_PRIVATE_TMR ); alt_gpt_int_clear_pending( ALT_GPT_CPU_PRIVATE_TMR );
alt_gpt_int_enable( ALT_GPT_CPU_PRIVATE_TMR ); alt_gpt_int_enable( ALT_GPT_CPU_PRIVATE_TMR );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vRegisterIRQHandler( uint32_t ulID, alt_int_callback_t pxHandlerFunction, void *pvContext ) void vRegisterIRQHandler( uint32_t ulID,
alt_int_callback_t pxHandlerFunction,
void * pvContext )
{ {
if( ulID < ALT_INT_PROVISION_INT_COUNT ) if( ulID < ALT_INT_PROVISION_INT_COUNT )
{ {
xISRHandlers[ ulID ].pxISR = pxHandlerFunction; xISRHandlers[ ulID ].pxISR = pxHandlerFunction;
xISRHandlers[ ulID ].pvContext = pvContext; xISRHandlers[ ulID ].pvContext = pvContext;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIRQHandler( uint32_t ulICCIAR ) void vApplicationIRQHandler( uint32_t ulICCIAR )
{ {
uint32_t ulInterruptID; uint32_t ulInterruptID;
void *pvContext; void * pvContext;
alt_int_callback_t pxISR; alt_int_callback_t pxISR;
/* Re-enable interrupts. */ /* Re-enable interrupts. */
__asm ( "cpsie i" ); __asm( "cpsie i" );
/* The ID of the interrupt is obtained by bitwise anding the ICCIAR value /* The ID of the interrupt is obtained by bitwise anding the ICCIAR value
with 0x3FF. */ * with 0x3FF. */
ulInterruptID = ulICCIAR & 0x3FFUL; ulInterruptID = ulICCIAR & 0x3FFUL;
if( ulInterruptID < ALT_INT_PROVISION_INT_COUNT ) if( ulInterruptID < ALT_INT_PROVISION_INT_COUNT )
{ {
/* Call the function installed in the array of installed handler /* Call the function installed in the array of installed handler
functions. */ * functions. */
pxISR = xISRHandlers[ ulInterruptID ].pxISR; pxISR = xISRHandlers[ ulInterruptID ].pxISR;
pvContext = xISRHandlers[ ulInterruptID ].pvContext; pvContext = xISRHandlers[ ulInterruptID ].pvContext;
pxISR( ulICCIAR, pvContext ); pxISR( ulICCIAR, pvContext );
} }
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -26,8 +26,8 @@
/****************************************************************************** /******************************************************************************
* NOTE 1: This project provides two demo applications. A simple blinky * NOTE 1: This project provides two demo applications. A simple blinky
* style project, and a more comprehensive test and demo application. The * style project, and a more comprehensive test and demo application. The
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
* in main.c. This file implements the simply blinky style version. * in main.c. This file implements the simply blinky style version.
* *
@ -70,28 +70,28 @@
#include "partest.h" #include "partest.h"
/* Priorities at which the tasks are created. */ /* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* The LED toggled by the Rx task. */ /* The LED toggled by the Rx task. */
#define mainTASK_LED ( 0 ) #define mainTASK_LED ( 0 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -102,86 +102,87 @@ static QueueHandle_t xQueue = NULL;
void main_blinky( void ) void main_blinky( void )
{ {
/* Create the queue. */ /* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) ); xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
NULL, /* The parameter passed to the task - not used in this case. */ NULL, /* The parameter passed to the task - not used in this case. */
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
NULL ); /* The task handle is not required, so NULL is passed. */ NULL ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle * there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from * and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for * User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The * more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be * mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */ * a privileged mode (not user mode). */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. */ /* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL; const unsigned long ulExpectedValue = 100UL;
/* Remove compiler warning about unused parameter. */ /* Remove compiler warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == ulExpectedValue ) if( ulReceivedValue == ulExpectedValue )
{ {
vParTestToggleLED( mainTASK_LED ); vParTestToggleLED( mainTASK_LED );
ulReceivedValue = 0U; ulReceivedValue = 0U;
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -92,42 +92,42 @@
#include "IntSemTest.h" #include "IntSemTest.h"
/* Priorities for the demo application tasks. */ /* Priorities for the demo application tasks. */
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainUART_COMMAND_CONSOLE_STACK_SIZE ( configMINIMAL_STACK_SIZE * 3UL ) #define mainUART_COMMAND_CONSOLE_STACK_SIZE ( configMINIMAL_STACK_SIZE * 3UL )
#define mainCOM_TEST_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) #define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define mainQUEUE_OVERWRITE_PRIORITY ( tskIDLE_PRIORITY ) #define mainQUEUE_OVERWRITE_PRIORITY ( tskIDLE_PRIORITY )
/* The priority used by the UART command console task. This is very basic and /* The priority used by the UART command console task. This is very basic and
uses the Altera polling UART driver - so *must* run at the idle priority. */ * uses the Altera polling UART driver - so *must* run at the idle priority. */
#define mainUART_COMMAND_CONSOLE_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainUART_COMMAND_CONSOLE_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* The LED used by the check task. */ /* The LED used by the check task. */
#define mainCHECK_LED ( 0 ) #define mainCHECK_LED ( 0 )
/* A block time of zero simply means "don't block". */ /* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The period of the check task, in ms, provided no errors have been reported by /* The period of the check task, in ms, provided no errors have been reported by
any of the standard demo tasks. ms are converted to the equivalent in ticks * any of the standard demo tasks. ms are converted to the equivalent in ticks
using the pdMS_TO_TICKS() macro constant. */ * using the pdMS_TO_TICKS() macro constant. */
#define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 3000UL ) #define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 3000UL )
/* The period of the check task, in ms, if an error has been reported in one of /* The period of the check task, in ms, if an error has been reported in one of
the standard demo tasks. ms are converted to the equivalent in ticks using the * the standard demo tasks. ms are converted to the equivalent in ticks using the
pdMS_TO_TICKS() macro. */ * pdMS_TO_TICKS() macro. */
#define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 200UL ) #define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 200UL )
/* Parameters that are passed into the register check tasks solely for the /* Parameters that are passed into the register check tasks solely for the
purpose of ensuring parameters are passed into tasks correctly. */ * purpose of ensuring parameters are passed into tasks correctly. */
#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 ) #define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 )
#define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 ) #define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 )
/* The base period used by the timer test tasks. */ /* The base period used by the timer test tasks. */
#define mainTIMER_TEST_PERIOD ( 50 ) #define mainTIMER_TEST_PERIOD ( 50 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -135,7 +135,7 @@ purpose of ensuring parameters are passed into tasks correctly. */
/* /*
* The check task, as described at the top of this file. * The check task, as described at the top of this file.
*/ */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
/* /*
* Register check tasks, and the tasks used to write over and check the contents * Register check tasks, and the tasks used to write over and check the contents
@ -144,9 +144,9 @@ static void prvCheckTask( void *pvParameters );
* entry points are kept in the C file for the convenience of checking the task * entry points are kept in the C file for the convenience of checking the task
* parameter. * parameter.
*/ */
static void prvRegTestTaskEntry1( void *pvParameters ); static void prvRegTestTaskEntry1( void * pvParameters );
extern void vRegTest1Implementation( void ); extern void vRegTest1Implementation( void );
static void prvRegTestTaskEntry2( void *pvParameters ); static void prvRegTestTaskEntry2( void * pvParameters );
extern void vRegTest2Implementation( void ); extern void vRegTest2Implementation( void );
/* /*
@ -158,285 +158,284 @@ extern void vRegisterSampleCLICommands( void );
/* /*
* The task that manages the FreeRTOS+CLI input and output. * The task that manages the FreeRTOS+CLI input and output.
*/ */
extern void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriority ); extern void vUARTCommandConsoleStart( uint16_t usStackSize,
UBaseType_t uxPriority );
/* /*
* A high priority task that does nothing other than execute at a pseudo random * A high priority task that does nothing other than execute at a pseudo random
* time to ensure the other test tasks don't just execute in a repeating * time to ensure the other test tasks don't just execute in a repeating
* pattern. * pattern.
*/ */
static void prvPseudoRandomiser( void *pvParameters ); static void prvPseudoRandomiser( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check task. If the variables keep incrementing, * register check tasks to the check task. If the variables keep incrementing,
then the register check tasks have not discovered any errors. If a variable * then the register check tasks have not discovered any errors. If a variable
stops incrementing, then an error has been found. */ * stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
/* Start all the other standard demo/test tasks. They have no particular /* Start all the other standard demo/test tasks. They have no particular
functionality, but do demonstrate how to use the FreeRTOS API and test the * functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */ * kernel port. */
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartCountingSemaphoreTasks(); vStartCountingSemaphoreTasks();
vStartGenericQueueTasks( tskIDLE_PRIORITY ); vStartGenericQueueTasks( tskIDLE_PRIORITY );
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartMathTasks( mainFLOP_TASK_PRIORITY ); vStartMathTasks( mainFLOP_TASK_PRIORITY );
vStartTimerDemoTask( mainTIMER_TEST_PERIOD ); vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY ); vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );
vStartEventGroupTasks(); vStartEventGroupTasks();
vStartInterruptSemaphoreTasks(); vStartInterruptSemaphoreTasks();
/* Start the tasks that implements the command console on the UART, as /* Start the tasks that implements the command console on the UART, as
described above. */ * described above. */
vUARTCommandConsoleStart( mainUART_COMMAND_CONSOLE_STACK_SIZE, mainUART_COMMAND_CONSOLE_TASK_PRIORITY ); vUARTCommandConsoleStart( mainUART_COMMAND_CONSOLE_STACK_SIZE, mainUART_COMMAND_CONSOLE_TASK_PRIORITY );
/* Register the standard CLI commands. */ /* Register the standard CLI commands. */
vRegisterSampleCLICommands(); vRegisterSampleCLICommands();
/* Create the register check tasks, as described at the top of this file */ /* Create the register check tasks, as described at the top of this file */
xTaskCreate( prvRegTestTaskEntry1, "Reg1", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_1_PARAMETER, tskIDLE_PRIORITY, NULL ); xTaskCreate( prvRegTestTaskEntry1, "Reg1", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_1_PARAMETER, tskIDLE_PRIORITY, NULL );
xTaskCreate( prvRegTestTaskEntry2, "Reg2", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL ); xTaskCreate( prvRegTestTaskEntry2, "Reg2", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL );
/* Create the task that just adds a little random behaviour. */ /* Create the task that just adds a little random behaviour. */
xTaskCreate( prvPseudoRandomiser, "Rnd", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL ); xTaskCreate( prvPseudoRandomiser, "Rnd", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
/* Create the task that performs the 'check' functionality, as described at /* Create the task that performs the 'check' functionality, as described at
the top of this file. */ * the top of this file. */
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* The set of tasks created by the following function call have to be /* The set of tasks created by the following function call have to be
created last as they keep account of the number of tasks they expect to see * created last as they keep account of the number of tasks they expect to see
running. */ * running. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was either insufficient FreeRTOS heap memory available for the idle * there was either insufficient FreeRTOS heap memory available for the idle
and/or timer tasks to be created, or vTaskStartScheduler() was called from * and/or timer tasks to be created, or vTaskStartScheduler() was called from
User mode. See the memory management section on the FreeRTOS web site for * User mode. See the memory management section on the FreeRTOS web site for
more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The * more details on the FreeRTOS heap http://www.freertos.org/a00111.html. The
mode from which main() is called is set in the C start up code and must be * mode from which main() is called is set in the C start up code and must be
a privileged mode (not user mode). */ * a privileged mode (not user mode). */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTask( void *pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD; TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Just to stop compiler warnings. */ /* Just to stop compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still /* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration. * operating without error. The onboard LED is toggled on each iteration.
If an error is detected then the delay period is decreased from * If an error is detected then the delay period is decreased from
mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the * mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the
effect of increasing the rate at which the onboard LED toggles, and in so * effect of increasing the rate at which the onboard LED toggles, and in so
doing gives visual feedback of the system status. */ * doing gives visual feedback of the system status. */
for( ;; ) for( ; ; )
{ {
/* Delay until it is time to execute again. */ /* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod ); vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod );
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
ulErrorFound = 1 << 1; ulErrorFound = 1 << 1;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = 1 << 2; ulErrorFound = 1 << 2;
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
ulErrorFound = 1 << 3; ulErrorFound = 1 << 3;
} }
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = 1 << 4; ulErrorFound = 1 << 4;
} }
if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = 1 << 5; ulErrorFound = 1 << 5;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = 1 << 6; ulErrorFound = 1 << 6;
} }
if( xIsCreateTaskStillRunning() != pdTRUE ) if( xIsCreateTaskStillRunning() != pdTRUE )
{ {
ulErrorFound = 1 << 7; ulErrorFound = 1 << 7;
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = 1 << 8; ulErrorFound = 1 << 8;
} }
if( xAreTimerDemoTasksStillRunning( ( TickType_t ) mainNO_ERROR_CHECK_TASK_PERIOD ) != pdPASS ) if( xAreTimerDemoTasksStillRunning( ( TickType_t ) mainNO_ERROR_CHECK_TASK_PERIOD ) != pdPASS )
{ {
ulErrorFound = 1 << 9; ulErrorFound = 1 << 9;
} }
if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = 1 << 10; ulErrorFound = 1 << 10;
} }
if( xIsQueueOverwriteTaskStillRunning() != pdPASS ) if( xIsQueueOverwriteTaskStillRunning() != pdPASS )
{ {
ulErrorFound = 1 << 11; ulErrorFound = 1 << 11;
} }
if( xAreEventGroupTasksStillRunning() != pdPASS ) if( xAreEventGroupTasksStillRunning() != pdPASS )
{ {
ulErrorFound = 1 << 12; ulErrorFound = 1 << 12;
} }
if( xAreInterruptSemaphoreTasksStillRunning() != pdPASS ) if( xAreInterruptSemaphoreTasksStillRunning() != pdPASS )
{ {
ulErrorFound = 1 << 13; ulErrorFound = 1 << 13;
} }
/* Check that the register test 1 task is still running. */ /* Check that the register test 1 task is still running. */
if( ulLastRegTest1Value == ulRegTest1LoopCounter ) if( ulLastRegTest1Value == ulRegTest1LoopCounter )
{ {
ulErrorFound = 1 << 14; ulErrorFound = 1 << 14;
} }
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ ulLastRegTest1Value = ulRegTest1LoopCounter;
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
{
ulErrorFound = 1 << 15;
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If /* Check that the register test 2 task is still running. */
the LED toggles every mainNO_ERROR_CHECK_TASK_PERIOD milliseconds then if( ulLastRegTest2Value == ulRegTest2LoopCounter )
everything is ok. A faster toggle indicates an error. */ {
vParTestToggleLED( mainCHECK_LED ); ulErrorFound = 1 << 15;
}
if( ulErrorFound != pdFALSE ) ulLastRegTest2Value = ulRegTest2LoopCounter;
{
/* An error has been detected in one of the tasks - flash the LED /* Toggle the check LED to give an indication of the system status. If
at a higher frequency to give visible feedback that something has * the LED toggles every mainNO_ERROR_CHECK_TASK_PERIOD milliseconds then
gone wrong (it might just be that the loop back connector required * everything is ok. A faster toggle indicates an error. */
by the comtest tasks has not been fitted). */ vParTestToggleLED( mainCHECK_LED );
xDelayPeriod = mainERROR_CHECK_TASK_PERIOD;
} 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). */
xDelayPeriod = mainERROR_CHECK_TASK_PERIOD;
}
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvRegTestTaskEntry1( void *pvParameters ) static void prvRegTestTaskEntry1( void * pvParameters )
{ {
/* Although the regtest task is written in assembler, its entry point is /* Although the regtest task is written in assembler, its entry point is
written in C for convenience of checking the task parameter is being passed * written in C for convenience of checking the task parameter is being passed
in correctly. */ * in correctly. */
if( pvParameters == mainREG_TEST_TASK_1_PARAMETER ) if( pvParameters == mainREG_TEST_TASK_1_PARAMETER )
{ {
/* The reg test task also tests the floating point registers. Tasks /* The reg test task also tests the floating point registers. Tasks
that use the floating point unit must call vPortTaskUsesFPU() before * that use the floating point unit must call vPortTaskUsesFPU() before
any floating point instructions are executed. */ * any floating point instructions are executed. */
vPortTaskUsesFPU(); vPortTaskUsesFPU();
/* Start the part of the test that is written in assembler. */ /* Start the part of the test that is written in assembler. */
vRegTest1Implementation(); vRegTest1Implementation();
} }
/* The following line will only execute if the task parameter is found to /* The following line will only execute if the task parameter is found to
be incorrect. The check task will detect that the regtest loop counter is * be incorrect. The check task will detect that the regtest loop counter is
not being incremented and flag an error. */ * not being incremented and flag an error. */
vTaskDelete( NULL ); vTaskDelete( NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvRegTestTaskEntry2( void *pvParameters ) static void prvRegTestTaskEntry2( void * pvParameters )
{ {
/* Although the regtest task is written in assembler, its entry point is /* Although the regtest task is written in assembler, its entry point is
written in C for convenience of checking the task parameter is being passed * written in C for convenience of checking the task parameter is being passed
in correctly. */ * in correctly. */
if( pvParameters == mainREG_TEST_TASK_2_PARAMETER ) if( pvParameters == mainREG_TEST_TASK_2_PARAMETER )
{ {
/* The reg test task also tests the floating point registers. Tasks /* The reg test task also tests the floating point registers. Tasks
that use the floating point unit must call vPortTaskUsesFPU() before * that use the floating point unit must call vPortTaskUsesFPU() before
any floating point instructions are executed. */ * any floating point instructions are executed. */
vPortTaskUsesFPU(); vPortTaskUsesFPU();
/* Start the part of the test that is written in assembler. */ /* Start the part of the test that is written in assembler. */
vRegTest2Implementation(); vRegTest2Implementation();
} }
/* The following line will only execute if the task parameter is found to /* The following line will only execute if the task parameter is found to
be incorrect. The check task will detect that the regtest loop counter is * be incorrect. The check task will detect that the regtest loop counter is
not being incremented and flag an error. */ * not being incremented and flag an error. */
vTaskDelete( NULL ); vTaskDelete( NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvPseudoRandomiser( void *pvParameters ) static void prvPseudoRandomiser( void * pvParameters )
{ {
const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL, ulMinDelay = ( 35 / portTICK_PERIOD_MS ); const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL, ulMinDelay = ( 35 / portTICK_PERIOD_MS );
volatile uint32_t ulNextRand = ( uint32_t ) &pvParameters, ulValue; volatile uint32_t ulNextRand = ( uint32_t ) &pvParameters, ulValue;
/* This task does nothing other than ensure there is a little bit of /* This task does nothing other than ensure there is a little bit of
disruption in the scheduling pattern of the other tasks. Normally this is * disruption in the scheduling pattern of the other tasks. Normally this is
done by generating interrupts at pseudo random times. */ * done by generating interrupts at pseudo random times. */
for( ;; ) for( ; ; )
{ {
ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement; ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
ulValue = ( ulNextRand >> 16UL ) & 0xffUL; ulValue = ( ulNextRand >> 16UL ) & 0xffUL;
if( ulValue < ulMinDelay ) if( ulValue < ulMinDelay )
{ {
ulValue = ulMinDelay; ulValue = ulMinDelay;
} }
vTaskDelay( ulValue ); vTaskDelay( ulValue );
while( ulValue > 0 ) while( ulValue > 0 )
{ {
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
ulValue--; ulValue--;
} }
} }
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -83,29 +83,29 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The time between cycles of the 'check' functionality (defined within the /* The time between cycles of the 'check' functionality (defined within the
tick hook). */ * tick hook). */
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* The LCD task uses the sprintf function so requires a little more stack too. */ /* The LCD task uses the sprintf function so requires a little more stack too. */
#define mainLCD_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) #define mainLCD_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 )
/* Task priorities. */ /* Task priorities. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* The maximum number of message that can be waiting for display at any one /* The maximum number of message that can be waiting for display at any one
time. */ * time. */
#define mainLCD_QUEUE_SIZE ( 3 ) #define mainLCD_QUEUE_SIZE ( 3 )
/* Constants used by the comtest tasks. There isn't a spare LED so an invalid /* Constants used by the comtest tasks. There isn't a spare LED so an invalid
LED is specified. */ * LED is specified. */
#define mainBAUD_RATE ( 115200 ) #define mainBAUD_RATE ( 115200 )
#define mainCOM_TEST_LED ( 10 ) #define mainCOM_TEST_LED ( 10 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -118,13 +118,14 @@ static void prvSetupHardware( void );
* The LCD gatekeeper task. Tasks wishing to write to the LCD do not access * The LCD gatekeeper task. Tasks wishing to write to the LCD do not access
* the LCD directly, but instead send the message to the LCD gatekeeper task. * the LCD directly, but instead send the message to the LCD gatekeeper task.
*/ */
static void prvLCDTask( void *pvParameters ); static void prvLCDTask( void * pvParameters );
/* /*
* Hook functions that can get called by the kernel. The 'check' functionality * Hook functions that can get called by the kernel. The 'check' functionality
* is implemented within the tick hook. * is implemented within the tick hook.
*/ */
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
/* /*
* The tick hook function as described in the comments at the top of this file. * The tick hook function as described in the comments at the top of this file.
@ -144,149 +145,154 @@ static QueueHandle_t xLCDQueue;
int main( void ) int main( void )
{ {
/* Prepare the hardware. */ /* Prepare the hardware. */
prvSetupHardware(); prvSetupHardware();
/* Create the queue used by the LCD task. Messages for display on the LCD /* Create the queue used by the LCD task. Messages for display on the LCD
are received via this queue. */ * are received via this queue. */
xLCDQueue = xQueueCreate( mainLCD_QUEUE_SIZE, sizeof( xLCDMessage ) ); xLCDQueue = xQueueCreate( mainLCD_QUEUE_SIZE, sizeof( xLCDMessage ) );
/* Start the standard demo tasks. These do nothing other than test the /* Start the standard demo tasks. These do nothing other than test the
port and provide some APU usage examples. */ * port and provide some APU usage examples. */
vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY ); vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY ); vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartQueuePeekTasks(); vStartQueuePeekTasks();
vStartLEDFlashTasks( mainLED_TASK_PRIORITY ); vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainBAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainBAUD_RATE, mainCOM_TEST_LED );
/* Start the tasks defined within this file/specific to this demo. */ /* Start the tasks defined within this file/specific to this demo. */
xTaskCreate( prvLCDTask, "LCD", mainLCD_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( prvLCDTask, "LCD", mainLCD_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle /* Will only get here if there was insufficient memory to create the idle
task. */ * task. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void prvSetupHardware( void ) void prvSetupHardware( void )
{ {
/* Initialise the port used for the LED outputs. */ /* Initialise the port used for the LED outputs. */
vParTestInitialise(); vParTestInitialise();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
static xLCDMessage xMessage = { "PASS" }; static xLCDMessage xMessage = { "PASS" };
static unsigned long ulTicksSinceLastDisplay = 0; static unsigned long ulTicksSinceLastDisplay = 0;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Called from every tick interrupt. Have enough ticks passed to make it /* Called from every tick interrupt. Have enough ticks passed to make it
time to perform our health status check again? */ * time to perform our health status check again? */
ulTicksSinceLastDisplay++; ulTicksSinceLastDisplay++;
if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
{
ulTicksSinceLastDisplay = 0;
/* Has an error been found in any task? */ if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
if( xAreGenericQueueTasksStillRunning() != pdTRUE ) {
{ ulTicksSinceLastDisplay = 0;
xMessage.pcMessage = "ERROR IN GEN Q";
}
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN MATH";
}
else if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN BLOCK Q";
}
else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN BLOCK TIME";
}
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN SEMAPHORE";
}
else if( xArePollingQueuesStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN POLL Q";
}
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN PEEK Q";
}
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN REC MUTEX";
}
else if( xAreComTestTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN COMTEST";
}
/* Send the message to the LCD gatekeeper for display. */ /* Has an error been found in any task? */
xHigherPriorityTaskWoken = pdFALSE; if( xAreGenericQueueTasksStillRunning() != pdTRUE )
xQueueSendFromISR( xLCDQueue, &xMessage, &xHigherPriorityTaskWoken ); {
} xMessage.pcMessage = "ERROR IN GEN Q";
}
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN MATH";
}
else if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN BLOCK Q";
}
else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN BLOCK TIME";
}
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN SEMAPHORE";
}
else if( xArePollingQueuesStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN POLL Q";
}
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN PEEK Q";
}
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN REC MUTEX";
}
else if( xAreComTestTasksStillRunning() != pdTRUE )
{
xMessage.pcMessage = "ERROR IN COMTEST";
}
/* Send the message to the LCD gatekeeper for display. */
xHigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR( xLCDQueue, &xMessage, &xHigherPriorityTaskWoken );
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pxTask; ( void ) pxTask;
( void ) pcTaskName; ( void ) pcTaskName;
/* If the parameters have been corrupted then inspect pxCurrentTCB to /* If the parameters have been corrupted then inspect pxCurrentTCB to
identify which task has overflowed its stack. */ * identify which task has overflowed its stack. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvLCDTask( void *pvParameters ) static void prvLCDTask( void * pvParameters )
{ {
xLCDMessage xMessage; xLCDMessage xMessage;
unsigned long ulY = 0; unsigned long ulY = 0;
const unsigned long ulX = 5; const unsigned long ulX = 5;
const unsigned long ulMaxY = 250, ulYIncrement = 22, ulWidth = 250, ulHeight = 20;; const unsigned long ulMaxY = 250, ulYIncrement = 22, ulWidth = 250, ulHeight = 20;
/* Initialize LCD. */ /* Initialize LCD. */
LCDD_Initialize(); LCDD_Initialize();
LCDD_Start(); LCDD_Start();
LCDD_Fill( ( void * ) BOARD_LCD_BASE, COLOR_WHITE ); LCDD_Fill( ( void * ) BOARD_LCD_BASE, COLOR_WHITE );
LCDD_DrawString( ( void * ) BOARD_LCD_BASE, 1, ulY + 3, " www.FreeRTOS.org", COLOR_BLACK ); LCDD_DrawString( ( void * ) BOARD_LCD_BASE, 1, ulY + 3, " www.FreeRTOS.org", COLOR_BLACK );
for( ;; ) for( ; ; )
{ {
/* Wait for a message from the check function (which is executed in /* Wait for a message from the check function (which is executed in
the tick hook). */ * the tick hook). */
xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ); xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY );
/* Clear the space where the old message was. */ /* Clear the space where the old message was. */
LCDD_DrawRectangle( ( void * ) BOARD_LCD_BASE, 0, ulY, ulWidth, ulHeight, COLOR_WHITE ); LCDD_DrawRectangle( ( void * ) BOARD_LCD_BASE, 0, ulY, ulWidth, ulHeight, COLOR_WHITE );
/* Increment to the next drawing position. */ /* Increment to the next drawing position. */
ulY += ulYIncrement; ulY += ulYIncrement;
/* Have the Y position moved past the end of the LCD? */ /* Have the Y position moved past the end of the LCD? */
if( ulY >= ulMaxY ) if( ulY >= ulMaxY )
{ {
ulY = 0; ulY = 0;
} }
/* Draw a new rectangle, in which the message will be written. */ /* Draw a new rectangle, in which the message will be written. */
LCDD_DrawRectangle( ( void * ) BOARD_LCD_BASE, 0, ulY, ulWidth, ulHeight, COLOR_GREEN ); LCDD_DrawRectangle( ( void * ) BOARD_LCD_BASE, 0, ulY, ulWidth, ulHeight, COLOR_GREEN );
/* Write the message. */ /* Write the message. */
LCDD_DrawString( ( void * ) BOARD_LCD_BASE, ulX, ulY + 3, xMessage.pcMessage, COLOR_BLACK ); LCDD_DrawString( ( void * ) BOARD_LCD_BASE, ulX, ulY + 3, xMessage.pcMessage, COLOR_BLACK );
} }
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -67,167 +67,172 @@ static void prvSetupHardware( void );
* main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1. * main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1.
* main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0. * main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0.
*/ */
#if( configCREATE_LOW_POWER_DEMO != 0 ) #if ( configCREATE_LOW_POWER_DEMO != 0 )
extern void main_low_power( void ); extern void main_low_power( void );
#else #else
extern void main_full( void ); extern void main_full( void );
#endif /* #if configCREATE_LOW_POWER_DEMO == 1 */ #endif /* #if configCREATE_LOW_POWER_DEMO == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
{ {
/* /*
* See the following link for instructions: * See the following link for instructions:
* https://www.FreeRTOS.org/EFM32-Giant-Gecko-Pearl-Gecko-tickless-RTOS-demo.html * https://www.FreeRTOS.org/EFM32-Giant-Gecko-Pearl-Gecko-tickless-RTOS-demo.html
*/ */
/* Configure the hardware ready to run the demo. */ /* Configure the hardware ready to run the demo. */
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_LOW_POWER_DEMO setting is described at the top /* The mainCREATE_LOW_POWER_DEMO setting is described at the top
of this file. */ * of this file. */
#if( configCREATE_LOW_POWER_DEMO != 0 ) #if ( configCREATE_LOW_POWER_DEMO != 0 )
{ {
main_low_power(); main_low_power();
} }
#else #else
{ {
main_full(); main_full();
} }
#endif #endif
/* Should not get here. */ /* Should not get here. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Library initialisation routines. */ /* Library initialisation routines. */
CHIP_Init(); CHIP_Init();
BSP_TraceProfilerSetup(); BSP_TraceProfilerSetup();
SLEEP_Init( NULL, NULL ); SLEEP_Init( NULL, NULL );
BSP_LedsInit(); BSP_LedsInit();
SLEEP_SleepBlockBegin( configENERGY_MODE ); SLEEP_SleepBlockBegin( configENERGY_MODE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
( void ) xFreeHeapSpace; ( void ) xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* The full demo includes tests that run from the tick hook. */ /* The full demo includes tests that run from the tick hook. */
#if( configCREATE_LOW_POWER_DEMO == 0 ) #if ( configCREATE_LOW_POWER_DEMO == 0 )
{ {
extern void vFullDemoTickHook( void ); extern void vFullDemoTickHook( void );
/* Some of the tests and demo tasks executed by the full demo include /* Some of the tests and demo tasks executed by the full demo include
interaction from an interrupt - for which the tick interrupt is used * interaction from an interrupt - for which the tick interrupt is used
via the tick hook function. */ * via the tick hook function. */
vFullDemoTickHook(); vFullDemoTickHook();
} }
#endif #endif
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */ * used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{ {
/* If the buffers to be provided to the Idle task are declared inside this /* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB; static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */ * state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB; *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */ /* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack; *ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory() * application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */ * to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
uint32_t * pulTimerTaskStackSize )
{ {
/* If the buffers to be provided to the Timer task are declared inside this /* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB; static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer /* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */ * task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB; *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */ /* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack; *ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -67,177 +67,183 @@ static void prvSetupHardware( void );
* main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1. * main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1.
* main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0. * main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0.
*/ */
#if( configCREATE_LOW_POWER_DEMO != 0 ) #if ( configCREATE_LOW_POWER_DEMO != 0 )
extern void main_low_power( void ); extern void main_low_power( void );
#else #else
extern void main_full( void ); extern void main_full( void );
#endif /* #if configCREATE_LOW_POWER_DEMO == 1 */ #endif /* #if configCREATE_LOW_POWER_DEMO == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
{ {
/* /*
* See the following link for instructions: * See the following link for instructions:
* https://www.FreeRTOS.org/EFM32-Giant-Gecko-Pearl-Gecko-tickless-RTOS-demo.html * https://www.FreeRTOS.org/EFM32-Giant-Gecko-Pearl-Gecko-tickless-RTOS-demo.html
*/ */
/* Configure the hardware ready to run the demo. */ /* Configure the hardware ready to run the demo. */
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_LOW_POWER_DEMO setting is described at the top /* The mainCREATE_LOW_POWER_DEMO setting is described at the top
of this file. */ * of this file. */
#if( configCREATE_LOW_POWER_DEMO != 0 ) #if ( configCREATE_LOW_POWER_DEMO != 0 )
{ {
main_low_power(); main_low_power();
} }
#else #else
{ {
main_full(); main_full();
} }
#endif #endif
/* Should not get here. */ /* Should not get here. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
EMU_DCDCInit_TypeDef xDCDInit = EMU_DCDCINIT_STK_DEFAULT; EMU_DCDCInit_TypeDef xDCDInit = EMU_DCDCINIT_STK_DEFAULT;
CMU_HFXOInit_TypeDef xHFXOInit = CMU_HFXOINIT_STK_DEFAULT; CMU_HFXOInit_TypeDef xHFXOInit = CMU_HFXOINIT_STK_DEFAULT;
/* Chip errata */ /* Chip errata */
CHIP_Init(); CHIP_Init();
/* Init DCDC regulator and HFXO with kit specific parameters */ /* Init DCDC regulator and HFXO with kit specific parameters */
EMU_DCDCInit( &xDCDInit ); EMU_DCDCInit( &xDCDInit );
CMU_HFXOInit( &xHFXOInit ); CMU_HFXOInit( &xHFXOInit );
/* Switch HFCLK to HFXO and disable HFRCO */ /* Switch HFCLK to HFXO and disable HFRCO */
CMU_ClockSelectSet( cmuClock_HF, cmuSelect_HFXO ); CMU_ClockSelectSet( cmuClock_HF, cmuSelect_HFXO );
CMU_OscillatorEnable( cmuOsc_HFRCO, false, false ); CMU_OscillatorEnable( cmuOsc_HFRCO, false, false );
/* Initialize LED driver. */ /* Initialize LED driver. */
BSP_LedsInit(); BSP_LedsInit();
BSP_LedSet( 0 ); BSP_LedSet( 0 );
BSP_LedClear( 1 ); BSP_LedClear( 1 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
( void ) xFreeHeapSpace; ( void ) xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* The full demo includes tests that run from the tick hook. */ /* The full demo includes tests that run from the tick hook. */
#if( configCREATE_LOW_POWER_DEMO == 0 ) #if ( configCREATE_LOW_POWER_DEMO == 0 )
{ {
extern void vFullDemoTickHook( void ); extern void vFullDemoTickHook( void );
/* Some of the tests and demo tasks executed by the full demo include /* Some of the tests and demo tasks executed by the full demo include
interaction from an interrupt - for which the tick interrupt is used * interaction from an interrupt - for which the tick interrupt is used
via the tick hook function. */ * via the tick hook function. */
vFullDemoTickHook(); vFullDemoTickHook();
} }
#endif #endif
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */ * used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{ {
/* If the buffers to be provided to the Idle task are declared inside this /* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB; static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */ * state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB; *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */ /* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack; *ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory() * application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */ * to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
uint32_t * pulTimerTaskStackSize )
{ {
/* If the buffers to be provided to the Timer task are declared inside this /* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB; static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer /* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */ * task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB; *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */ /* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack; *ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -24,31 +24,31 @@
* *
*/ */
/* /*
* This demo application creates six co-routines and two tasks (three including * This demo application creates six co-routines and two tasks (three including
* the idle task). The co-routines execute as part of the idle task hook. * the idle task). The co-routines execute as part of the idle task hook.
* *
* Five of the created co-routines are the standard 'co-routine flash' * Five of the created co-routines are the standard 'co-routine flash'
* co-routines contained within the Demo/Common/Minimal/crflash.c file and * co-routines contained within the Demo/Common/Minimal/crflash.c file and
* documented on the FreeRTOS.org WEB site. * documented on the FreeRTOS.org WEB site.
* *
* The 'LCD Task' rotates a string on the LCD, delaying between each character * The 'LCD Task' rotates a string on the LCD, delaying between each character
* as necessitated by the slow interface, and delaying between each string just * as necessitated by the slow interface, and delaying between each string just
* long enough to enable the text to be read. * long enough to enable the text to be read.
* *
* The sixth co-routine and final task control the transmission and reception * The sixth co-routine and final task control the transmission and reception
* of a string to UART 0. The co-routine periodically sends the first * of a string to UART 0. The co-routine periodically sends the first
* character of the string to the UART, with the UART's TxEnd interrupt being * character of the string to the UART, with the UART's TxEnd interrupt being
* used to transmit the remaining characters. The UART's RxEnd interrupt * used to transmit the remaining characters. The UART's RxEnd interrupt
* receives the characters and places them on a queue to be processed by the * receives the characters and places them on a queue to be processed by the
* 'COMs Rx' task. An error is latched should an unexpected character be * 'COMs Rx' task. An error is latched should an unexpected character be
* received, or any character be received out of sequence. * received, or any character be received out of sequence.
* *
* A loopback connector is required to ensure that each character transmitted * A loopback connector is required to ensure that each character transmitted
* on the UART is also received on the same UART. For test purposes the UART * on the UART is also received on the same UART. For test purposes the UART
* FIFO's are not utalised in order to maximise the interrupt overhead. Also * FIFO's are not utalised in order to maximise the interrupt overhead. Also
* a pseudo random interval is used between the start of each transmission in * a pseudo random interval is used between the start of each transmission in
* order that the resultant interrupts are more randomly distributed and * order that the resultant interrupts are more randomly distributed and
* therefore more likely to highlight any problems. * therefore more likely to highlight any problems.
* *
* The flash co-routines control LED's zero to four. LED five is toggled each * The flash co-routines control LED's zero to four. LED five is toggled each
@ -56,12 +56,12 @@
* the string is CORRECTLY received on the UART. LED seven is latched on should * the string is CORRECTLY received on the UART. LED seven is latched on should
* an error be detected in any task or co-routine. * an error be detected in any task or co-routine.
* *
* In addition the idle task makes repetitive calls to * In addition the idle task makes repetitive calls to
* prvSetAndCheckRegisters(). This simply loads the general purpose registers * prvSetAndCheckRegisters(). This simply loads the general purpose registers
* with a known value, then checks each register to ensure the held value is * with a known value, then checks each register to ensure the held value is
* still correct. As a low priority task this checking routine is likely to * still correct. As a low priority task this checking routine is likely to
* get repeatedly swapped in and out. A register being found to contain an * get repeatedly swapped in and out. A register being found to contain an
* incorrect value is therefore indicative of an error in the task switching * incorrect value is therefore indicative of an error in the task switching
* mechansim. * mechansim.
* *
*/ */
@ -80,68 +80,68 @@
#include "DriverLib.h" #include "DriverLib.h"
/* The time to delay between writing each character to the LCD. */ /* The time to delay between writing each character to the LCD. */
#define mainCHAR_WRITE_DELAY ( 2 / portTICK_PERIOD_MS ) #define mainCHAR_WRITE_DELAY ( 2 / portTICK_PERIOD_MS )
/* The time to delay between writing each string to the LCD. */ /* The time to delay between writing each string to the LCD. */
#define mainSTRING_WRITE_DELAY ( 400 / portTICK_PERIOD_MS ) #define mainSTRING_WRITE_DELAY ( 400 / portTICK_PERIOD_MS )
/* The number of flash co-routines to create. */ /* The number of flash co-routines to create. */
#define mainNUM_FLASH_CO_ROUTINES ( 5 ) #define mainNUM_FLASH_CO_ROUTINES ( 5 )
/* The length of the queue used to pass received characters to the Comms Rx /* The length of the queue used to pass received characters to the Comms Rx
task. */ * task. */
#define mainRX_QUEUE_LEN ( 5 ) #define mainRX_QUEUE_LEN ( 5 )
/* The priority of the co-routine used to initiate the transmission of the /* The priority of the co-routine used to initiate the transmission of the
string on UART 0. */ * string on UART 0. */
#define mainTX_CO_ROUTINE_PRIORITY ( 1 ) #define mainTX_CO_ROUTINE_PRIORITY ( 1 )
/* Only one co-routine is created so its index is not important. */ /* Only one co-routine is created so its index is not important. */
#define mainTX_CO_ROUTINE_INDEX ( 0 ) #define mainTX_CO_ROUTINE_INDEX ( 0 )
/* The time between transmissions of the string on UART 0. This is pseudo /* The time between transmissions of the string on UART 0. This is pseudo
random in order to generate a bit or randomness to when the interrupts occur.*/ * random in order to generate a bit or randomness to when the interrupts occur.*/
#define mainMIN_TX_DELAY ( 40 / portTICK_PERIOD_MS ) #define mainMIN_TX_DELAY ( 40 / portTICK_PERIOD_MS )
#define mainMAX_TX_DELAY ( ( TickType_t ) 0x7f ) #define mainMAX_TX_DELAY ( ( TickType_t ) 0x7f )
#define mainOFFSET_TIME ( ( TickType_t ) 3 ) #define mainOFFSET_TIME ( ( TickType_t ) 3 )
/* The time the Comms Rx task should wait to receive a character. This should /* The time the Comms Rx task should wait to receive a character. This should
be slightly longer than the time between transmissions. If we do not receive * be slightly longer than the time between transmissions. If we do not receive
a character after this time then there must be an error in the transmission or * a character after this time then there must be an error in the transmission or
the timing of the transmission. */ * the timing of the transmission. */
#define mainCOMMS_RX_DELAY ( mainMAX_TX_DELAY + 20 ) #define mainCOMMS_RX_DELAY ( mainMAX_TX_DELAY + 20 )
/* The task priorities. */ /* The task priorities. */
#define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainCOMMS_RX_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainCOMMS_RX_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The LED's toggled by the various tasks. */ /* The LED's toggled by the various tasks. */
#define mainCOMMS_FAIL_LED ( 7 ) #define mainCOMMS_FAIL_LED ( 7 )
#define mainCOMMS_RX_LED ( 6 ) #define mainCOMMS_RX_LED ( 6 )
#define mainCOMMS_TX_LED ( 5 ) #define mainCOMMS_TX_LED ( 5 )
/* The baud rate used by the UART comms tasks/co-routine. */ /* The baud rate used by the UART comms tasks/co-routine. */
#define mainBAUD_RATE ( 57600 ) #define mainBAUD_RATE ( 57600 )
/* FIFO setting for the UART. The FIFO is not used to create a better test. */ /* FIFO setting for the UART. The FIFO is not used to create a better test. */
#define mainFIFO_SET ( 0x10 ) #define mainFIFO_SET ( 0x10 )
/* The string that is transmitted on the UART contains sequentially the /* The string that is transmitted on the UART contains sequentially the
characters from mainFIRST_TX_CHAR to mainLAST_TX_CHAR. */ * characters from mainFIRST_TX_CHAR to mainLAST_TX_CHAR. */
#define mainFIRST_TX_CHAR '0' #define mainFIRST_TX_CHAR '0'
#define mainLAST_TX_CHAR 'z' #define mainLAST_TX_CHAR 'z'
/* Just used to walk through the program memory in order that some random data /* Just used to walk through the program memory in order that some random data
can be generated. */ * can be generated. */
#define mainTOTAL_PROGRAM_MEMORY ( ( unsigned long * ) ( 8 * 1024 ) ) #define mainTOTAL_PROGRAM_MEMORY ( ( unsigned long * ) ( 8 * 1024 ) )
#define mainFIRST_PROGRAM_BYTES ( ( unsigned long * ) 4 ) #define mainFIRST_PROGRAM_BYTES ( ( unsigned long * ) 4 )
/* The error routine that is called if the driver library encounters an error. */ /* The error routine that is called if the driver library encounters an error. */
#ifdef DEBUG #ifdef DEBUG
void void __error__( char * pcFilename,
__error__(char *pcFilename, unsigned long ulLine) unsigned long ulLine )
{ {
} }
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -160,12 +160,13 @@ static void vCommsRxTask( void * pvParameters );
* The co-routine that periodically initiates the transmission of the string on * The co-routine that periodically initiates the transmission of the string on
* the UART. * the UART.
*/ */
static void vSerialTxCoRoutine( CoRoutineHandle_t xHandle, unsigned portBASE_TYPE uxIndex ); static void vSerialTxCoRoutine( CoRoutineHandle_t xHandle,
unsigned portBASE_TYPE uxIndex );
/* /*
* Writes a string the the LCD. * Writes a string the the LCD.
*/ */
static void prvWriteString( const char *pcString ); static void prvWriteString( const char * pcString );
/* /*
* Initialisation routine for the UART. * Initialisation routine for the UART.
@ -175,7 +176,8 @@ static void vSerialInit( void );
/* /*
* Thread safe write to the PDC. * Thread safe write to the PDC.
*/ */
static void prvPDCWrite( char cAddress, char cData ); static void prvPDCWrite( char cAddress,
char cData );
/* /*
* Function to simply set a known value into the general purpose registers * Function to simply set a known value into the general purpose registers
@ -185,7 +187,7 @@ static void prvPDCWrite( char cAddress, char cData );
void prvSetAndCheckRegisters( void ); void prvSetAndCheckRegisters( void );
/* /*
* Latch the LED that indicates that an error has occurred. * Latch the LED that indicates that an error has occurred.
*/ */
void vSetErrorLED( void ); void vSetErrorLED( void );
@ -197,399 +199,413 @@ static void prvSetupHardware( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Error flag set to pdFAIL if an error is encountered in the tasks/co-routines /* Error flag set to pdFAIL if an error is encountered in the tasks/co-routines
defined within this file. */ * defined within this file. */
unsigned portBASE_TYPE uxErrorStatus = pdPASS; unsigned portBASE_TYPE uxErrorStatus = pdPASS;
/* The next character to transmit. */ /* The next character to transmit. */
static char cNextChar; static char cNextChar;
/* The queue used to transmit characters from the interrupt to the Comms Rx /* The queue used to transmit characters from the interrupt to the Comms Rx
task. */ * task. */
static QueueHandle_t xCommsQueue; static QueueHandle_t xCommsQueue;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void Main( void ) void Main( void )
{ {
/* Create the queue used to communicate between the UART ISR and the Comms /* Create the queue used to communicate between the UART ISR and the Comms
Rx task. */ * Rx task. */
xCommsQueue = xQueueCreate( mainRX_QUEUE_LEN, sizeof( char ) ); xCommsQueue = xQueueCreate( mainRX_QUEUE_LEN, sizeof( char ) );
/* Setup the ports used by the demo and the clock. */ /* Setup the ports used by the demo and the clock. */
prvSetupHardware(); prvSetupHardware();
/* Create the co-routines that flash the LED's. */ /* Create the co-routines that flash the LED's. */
vStartFlashCoRoutines( mainNUM_FLASH_CO_ROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_CO_ROUTINES );
/* Create the co-routine that initiates the transmission of characters /* Create the co-routine that initiates the transmission of characters
on the UART. */ * on the UART. */
xCoRoutineCreate( vSerialTxCoRoutine, mainTX_CO_ROUTINE_PRIORITY, mainTX_CO_ROUTINE_INDEX ); xCoRoutineCreate( vSerialTxCoRoutine, mainTX_CO_ROUTINE_PRIORITY, mainTX_CO_ROUTINE_INDEX );
/* Create the LCD and Comms Rx tasks. */ /* Create the LCD and Comms Rx tasks. */
xTaskCreate( vLCDTask, "LCD", configMINIMAL_STACK_SIZE, NULL, mainLCD_TASK_PRIORITY, NULL ); xTaskCreate( vLCDTask, "LCD", configMINIMAL_STACK_SIZE, NULL, mainLCD_TASK_PRIORITY, NULL );
xTaskCreate( vCommsRxTask, "CMS", configMINIMAL_STACK_SIZE, NULL, mainCOMMS_RX_TASK_PRIORITY, NULL ); xTaskCreate( vCommsRxTask, "CMS", configMINIMAL_STACK_SIZE, NULL, mainCOMMS_RX_TASK_PRIORITY, NULL );
/* Start the scheduler running the tasks and co-routines just created. */ /* Start the scheduler running the tasks and co-routines just created. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Should not get here unless we did not have enough memory to start the /* Should not get here unless we did not have enough memory to start the
scheduler. */ * scheduler. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Setup the PLL. */ /* Setup the PLL. */
SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ ); SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ );
/* Initialise the hardware used to talk to the LCD, LED's and UART. */ /* Initialise the hardware used to talk to the LCD, LED's and UART. */
PDCInit(); PDCInit();
vParTestInitialise(); vParTestInitialise();
vSerialInit(); vSerialInit();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* The co-routines are executed in the idle task using the idle task /* The co-routines are executed in the idle task using the idle task
hook. */ * hook. */
for( ;; ) for( ; ; )
{ {
/* Schedule the co-routines. */ /* Schedule the co-routines. */
vCoRoutineSchedule(); vCoRoutineSchedule();
/* Run the register check function between each co-routine. */ /* Run the register check function between each co-routine. */
prvSetAndCheckRegisters(); prvSetAndCheckRegisters();
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvWriteString( const char *pcString ) static void prvWriteString( const char * pcString )
{ {
/* Write pcString to the LED, pausing between each character. */ /* Write pcString to the LED, pausing between each character. */
prvPDCWrite(PDC_LCD_CSR, LCD_CLEAR); prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR );
while( *pcString )
{ while( *pcString )
vTaskDelay( mainCHAR_WRITE_DELAY ); {
prvPDCWrite( PDC_LCD_RAM, *pcString ); vTaskDelay( mainCHAR_WRITE_DELAY );
pcString++; prvPDCWrite( PDC_LCD_RAM, *pcString );
} pcString++;
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vLCDTask( void * pvParameters ) void vLCDTask( void * pvParameters )
{ {
unsigned portBASE_TYPE uxIndex; unsigned portBASE_TYPE uxIndex;
const unsigned char ucCFGData[] = { const unsigned char ucCFGData[] =
0x30, /* Set data bus to 8-bits. */ {
0x30, 0x30, /* Set data bus to 8-bits. */
0x30, 0x30,
0x3C, /* Number of lines/font. */ 0x30,
0x08, /* Display off. */ 0x3C, /* Number of lines/font. */
0x01, /* Display clear. */ 0x08, /* Display off. */
0x06, /* Entry mode [cursor dir][shift]. */ 0x01, /* Display clear. */
0x0C /* Display on [display on][curson on][blinking on]. */ 0x06, /* Entry mode [cursor dir][shift]. */
}; 0x0C /* Display on [display on][curson on][blinking on]. */
};
/* The strings that are written to the LCD. */ /* The strings that are written to the LCD. */
const char *pcStringsToDisplay[] = { const char * pcStringsToDisplay[] =
"Stellaris", {
"Demo", "Stellaris",
"One", "Demo",
"www.FreeRTOS.org", "One",
"" "www.FreeRTOS.org",
}; ""
};
/* Configure the LCD. */ /* Configure the LCD. */
uxIndex = 0; uxIndex = 0;
while( uxIndex < sizeof( ucCFGData ) )
{
prvPDCWrite( PDC_LCD_CSR, ucCFGData[ uxIndex ] );
uxIndex++;
vTaskDelay( mainCHAR_WRITE_DELAY );
}
/* Turn the LCD Backlight on. */ while( uxIndex < sizeof( ucCFGData ) )
prvPDCWrite( PDC_CSR, 0x01 ); {
prvPDCWrite( PDC_LCD_CSR, ucCFGData[ uxIndex ] );
uxIndex++;
vTaskDelay( mainCHAR_WRITE_DELAY );
}
/* Clear display. */ /* Turn the LCD Backlight on. */
vTaskDelay( mainCHAR_WRITE_DELAY ); prvPDCWrite( PDC_CSR, 0x01 );
prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR );
uxIndex = 0; /* Clear display. */
for( ;; ) vTaskDelay( mainCHAR_WRITE_DELAY );
{ prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR );
/* 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;
/* Longer pause on the last string to be sent. */
vTaskDelay( mainSTRING_WRITE_DELAY * 2 );
}
/* Wait until it is time to move onto the next string. */ uxIndex = 0;
vTaskDelay( mainSTRING_WRITE_DELAY );
} 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;
/* Longer pause on the last string to be sent. */
vTaskDelay( mainSTRING_WRITE_DELAY * 2 );
}
/* Wait until it is time to move onto the next string. */
vTaskDelay( mainSTRING_WRITE_DELAY );
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCommsRxTask( void * pvParameters ) static void vCommsRxTask( void * pvParameters )
{ {
static char cRxedChar, cExpectedChar; static char cRxedChar, cExpectedChar;
/* Set the char we expect to receive to the start of the string. */ /* Set the char we expect to receive to the start of the string. */
cExpectedChar = mainFIRST_TX_CHAR; cExpectedChar = mainFIRST_TX_CHAR;
for( ;; ) for( ; ; )
{ {
/* Wait for a character to be received. */ /* Wait for a character to be received. */
xQueueReceive( xCommsQueue, ( void * ) &cRxedChar, mainCOMMS_RX_DELAY ); xQueueReceive( xCommsQueue, ( void * ) &cRxedChar, mainCOMMS_RX_DELAY );
/* Was the character received (if any) the expected character. */ /* Was the character received (if any) the expected character. */
if( cRxedChar != cExpectedChar ) if( cRxedChar != cExpectedChar )
{ {
/* Got an unexpected character. This can sometimes occur when /* Got an unexpected character. This can sometimes occur when
reseting the system using the debugger leaving characters already * reseting the system using the debugger leaving characters already
in the UART registers. */ * in the UART registers. */
uxErrorStatus = pdFAIL; uxErrorStatus = pdFAIL;
/* Resync by waiting for the end of the current string. */ /* Resync by waiting for the end of the current string. */
while( cRxedChar != mainLAST_TX_CHAR ) while( cRxedChar != mainLAST_TX_CHAR )
{ {
while( !xQueueReceive( xCommsQueue, ( void * ) &cRxedChar, portMAX_DELAY ) ); while( !xQueueReceive( xCommsQueue, ( void * ) &cRxedChar, portMAX_DELAY ) )
} {
}
}
/* The next expected character is the start of the string again. */ /* The next expected character is the start of the string again. */
cExpectedChar = mainFIRST_TX_CHAR; cExpectedChar = mainFIRST_TX_CHAR;
} }
else else
{ {
if( cExpectedChar == mainLAST_TX_CHAR ) if( cExpectedChar == mainLAST_TX_CHAR )
{ {
/* We have reached the end of the string - we now expect to /* We have reached the end of the string - we now expect to
receive the first character in the string again. The LED is * receive the first character in the string again. The LED is
toggled to indicate that the entire string was received without * toggled to indicate that the entire string was received without
error. */ * error. */
vParTestToggleLED( mainCOMMS_RX_LED ); vParTestToggleLED( mainCOMMS_RX_LED );
cExpectedChar = mainFIRST_TX_CHAR; cExpectedChar = mainFIRST_TX_CHAR;
} }
else else
{ {
/* We got the expected character, we now expect to receive the /* We got the expected character, we now expect to receive the
next character in the string. */ * next character in the string. */
cExpectedChar++; cExpectedChar++;
} }
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vSerialTxCoRoutine( CoRoutineHandle_t xHandle, unsigned portBASE_TYPE uxIndex ) static void vSerialTxCoRoutine( CoRoutineHandle_t xHandle,
unsigned portBASE_TYPE uxIndex )
{ {
TickType_t xDelayPeriod; TickType_t xDelayPeriod;
static unsigned long *pulRandomBytes = mainFIRST_PROGRAM_BYTES; static unsigned long * pulRandomBytes = mainFIRST_PROGRAM_BYTES;
/* Co-routine MUST start with a call to crSTART. */ /* Co-routine MUST start with a call to crSTART. */
crSTART( xHandle ); crSTART( xHandle );
for(;;) for( ; ; )
{ {
/* Was the previously transmitted string received correctly? */ /* Was the previously transmitted string received correctly? */
if( uxErrorStatus != pdPASS ) if( uxErrorStatus != pdPASS )
{ {
/* An error was encountered so set the error LED. */ /* An error was encountered so set the error LED. */
vSetErrorLED(); vSetErrorLED();
} }
/* The next character to Tx is the first in the string. */ /* The next character to Tx is the first in the string. */
cNextChar = mainFIRST_TX_CHAR; cNextChar = mainFIRST_TX_CHAR;
UARTIntDisable( UART0_BASE, UART_INT_TX ); UARTIntDisable( UART0_BASE, UART_INT_TX );
{ {
/* Send the first character. */ /* Send the first character. */
if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) ) if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
{ {
HWREG( UART0_BASE + UART_O_DR ) = cNextChar; HWREG( UART0_BASE + UART_O_DR ) = cNextChar;
} }
/* Move the variable to the char to Tx on so the ISR transmits /* Move the variable to the char to Tx on so the ISR transmits
the next character in the string once this one has completed. */ * the next character in the string once this one has completed. */
cNextChar++; cNextChar++;
} }
UARTIntEnable(UART0_BASE, UART_INT_TX); UARTIntEnable( UART0_BASE, UART_INT_TX );
/* Toggle the LED to show a new string is being transmitted. */ /* Toggle the LED to show a new string is being transmitted. */
vParTestToggleLED( mainCOMMS_TX_LED ); vParTestToggleLED( mainCOMMS_TX_LED );
/* Delay before we start the string off again. A pseudo-random delay /* Delay before we start the string off again. A pseudo-random delay
is used as this will provide a better test. */ * is used as this will provide a better test. */
xDelayPeriod = xTaskGetTickCount() + ( *pulRandomBytes ); xDelayPeriod = xTaskGetTickCount() + ( *pulRandomBytes );
pulRandomBytes++; pulRandomBytes++;
if( pulRandomBytes > mainTOTAL_PROGRAM_MEMORY )
{
pulRandomBytes = mainFIRST_PROGRAM_BYTES;
}
/* Make sure we don't wait too long... */ if( pulRandomBytes > mainTOTAL_PROGRAM_MEMORY )
xDelayPeriod &= mainMAX_TX_DELAY; {
pulRandomBytes = mainFIRST_PROGRAM_BYTES;
}
/* ...but we do want to wait. */ /* Make sure we don't wait too long... */
if( xDelayPeriod < mainMIN_TX_DELAY ) xDelayPeriod &= mainMAX_TX_DELAY;
{
xDelayPeriod = mainMIN_TX_DELAY;
}
/* Block for the random(ish) time. */ /* ...but we do want to wait. */
crDELAY( xHandle, xDelayPeriod ); if( xDelayPeriod < mainMIN_TX_DELAY )
{
xDelayPeriod = mainMIN_TX_DELAY;
}
/* Block for the random(ish) time. */
crDELAY( xHandle, xDelayPeriod );
} }
/* Co-routine MUST end with a call to crEND. */ /* Co-routine MUST end with a call to crEND. */
crEND(); crEND();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vSerialInit( void ) static void vSerialInit( void )
{ {
/* Enable the UART. GPIOA has already been initialised. */ /* Enable the UART. GPIOA has already been initialised. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
/* Set GPIO A0 and A1 as peripheral function. They are used to output the /* Set GPIO A0 and A1 as peripheral function. They are used to output the
UART signals. */ * UART signals. */
GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW ); GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW );
/* Configure the UART for 8-N-1 operation. */ /* Configure the UART for 8-N-1 operation. */
UARTConfigSet( UART0_BASE, mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE ); UARTConfigSet( UART0_BASE, mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE );
/* We dont want to use the fifo. This is for test purposes to generate /* We dont want to use the fifo. This is for test purposes to generate
as many interrupts as possible. */ * as many interrupts as possible. */
HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET; HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET;
/* Enable both Rx and Tx interrupts. */ /* Enable both Rx and Tx interrupts. */
HWREG( UART0_BASE + UART_O_IM ) |= ( UART_INT_TX | UART_INT_RX ); HWREG( UART0_BASE + UART_O_IM ) |= ( UART_INT_TX | UART_INT_RX );
IntEnable( INT_UART0 ); IntEnable( INT_UART0 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vUART_ISR(void) void vUART_ISR( void )
{ {
unsigned long ulStatus; unsigned long ulStatus;
char cRxedChar; char cRxedChar;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* What caused the interrupt. */ /* What caused the interrupt. */
ulStatus = UARTIntStatus( UART0_BASE, pdTRUE ); ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
/* Clear the interrupt. */ /* Clear the interrupt. */
UARTIntClear( UART0_BASE, ulStatus ); UARTIntClear( UART0_BASE, ulStatus );
/* Was an Rx interrupt pending? */ /* Was an Rx interrupt pending? */
if( ulStatus & UART_INT_RX ) if( ulStatus & UART_INT_RX )
{ {
if( ( HWREG(UART0_BASE + UART_O_FR ) & UART_FR_RXFF ) ) if( ( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_RXFF ) )
{ {
/* Get the char from the buffer and post it onto the queue of /* Get the char from the buffer and post it onto the queue of
Rxed chars. Posting the character should wake the task that is * Rxed chars. Posting the character should wake the task that is
blocked on the queue waiting for characters. */ * blocked on the queue waiting for characters. */
cRxedChar = ( char ) HWREG( UART0_BASE + UART_O_DR ); cRxedChar = ( char ) HWREG( UART0_BASE + UART_O_DR );
xQueueSendFromISR( xCommsQueue, &cRxedChar, &xHigherPriorityTaskWoken ); xQueueSendFromISR( xCommsQueue, &cRxedChar, &xHigherPriorityTaskWoken );
} }
} }
/* Was a Tx interrupt pending? */ /* Was a Tx interrupt pending? */
if( ulStatus & UART_INT_TX ) if( ulStatus & UART_INT_TX )
{ {
/* Send the next character in the string. We are not using the FIFO. */ /* Send the next character in the string. We are not using the FIFO. */
if( cNextChar <= mainLAST_TX_CHAR ) if( cNextChar <= mainLAST_TX_CHAR )
{ {
if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) ) if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
{ {
HWREG( UART0_BASE + UART_O_DR ) = cNextChar; HWREG( UART0_BASE + UART_O_DR ) = cNextChar;
} }
cNextChar++;
} cNextChar++;
} }
}
/* If a task was woken by the character being received then we force
a context switch to occur in case the task is of higher priority than /* If a task was woken by the character being received then we force
the currently executing task (i.e. the task that this interrupt * a context switch to occur in case the task is of higher priority than
interrupted.) */ * the currently executing task (i.e. the task that this interrupt
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); * interrupted.) */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvPDCWrite( char cAddress, char cData ) static void prvPDCWrite( char cAddress,
char cData )
{ {
vTaskSuspendAll(); vTaskSuspendAll();
{ {
PDCWrite( cAddress, cData ); PDCWrite( cAddress, cData );
} }
xTaskResumeAll(); xTaskResumeAll();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vSetErrorLED( void ) void vSetErrorLED( void )
{ {
vParTestSetLED( mainCOMMS_FAIL_LED, pdTRUE ); vParTestSetLED( mainCOMMS_FAIL_LED, pdTRUE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void prvSetAndCheckRegisters( void ) void prvSetAndCheckRegisters( void )
{ {
/* Fill the general purpose registers with known values. */ /* Fill the general purpose registers with known values. */
__asm volatile( " mov r11, #10\n" __asm volatile ( " mov r11, #10\n"
" add r0, r11, #1\n" " add r0, r11, #1\n"
" add r1, r11, #2\n" " add r1, r11, #2\n"
" add r2, r11, #3\n" " add r2, r11, #3\n"
" add r3, r11, #4\n" " add r3, r11, #4\n"
" add r4, r11, #5\n" " add r4, r11, #5\n"
" add r5, r11, #6\n" " add r5, r11, #6\n"
" add r6, r11, #7\n" " add r6, r11, #7\n"
" add r7, r11, #8\n" " add r7, r11, #8\n"
" add r8, r11, #9\n" " add r8, r11, #9\n"
" add r9, r11, #10\n" " add r9, r11, #10\n"
" add r10, r11, #11\n" " add r10, r11, #11\n"
" add r12, r11, #12" ); " add r12, r11, #12" );
/* Check the values are as expected. */ /* Check the values are as expected. */
__asm volatile( " cmp r11, #10\n" __asm volatile ( " cmp r11, #10\n"
" bne set_error_led\n" " bne set_error_led\n"
" cmp r0, #11\n" " cmp r0, #11\n"
" bne set_error_led\n" " bne set_error_led\n"
" cmp r1, #12\n" " cmp r1, #12\n"
" bne set_error_led\n" " bne set_error_led\n"
" cmp r2, #13\n" " cmp r2, #13\n"
" bne set_error_led\n" " bne set_error_led\n"
" cmp r3, #14\n" " cmp r3, #14\n"
" bne set_error_led\n" " bne set_error_led\n"
" cmp r4, #15\n" " cmp r4, #15\n"
" bne set_error_led\n" " bne set_error_led\n"
" cmp r5, #16\n" " cmp r5, #16\n"
" bne set_error_led\n" " bne set_error_led\n"
" cmp r6, #17\n" " cmp r6, #17\n"
" bne set_error_led\n" " bne set_error_led\n"
" cmp r7, #18\n" " cmp r7, #18\n"
" bne set_error_led\n" " bne set_error_led\n"
" cmp r8, #19\n" " cmp r8, #19\n"
" bne set_error_led\n" " bne set_error_led\n"
" cmp r9, #20\n" " cmp r9, #20\n"
" bne set_error_led\n" " bne set_error_led\n"
" cmp r10, #21\n" " cmp r10, #21\n"
" bne set_error_led\n" " bne set_error_led\n"
" cmp r12, #22\n" " cmp r12, #22\n"
" bne set_error_led\n" " bne set_error_led\n"
" bx lr" ); " bx lr" );
__asm volatile( "set_error_led:\n" __asm volatile ( "set_error_led:\n"
" push {r14}\n" " push {r14}\n"
" ldr r1, =vSetErrorLED\n" " ldr r1, =vSetErrorLED\n"
" blx r1\n" " blx r1\n"
" pop {r14}\n" " pop {r14}\n"
" bx lr" ); " bx lr" );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -24,15 +24,15 @@
* *
*/ */
/* /*
* This demo application creates eight co-routines and four tasks (five * This demo application creates eight co-routines and four tasks (five
* including the idle task). The co-routines execute as part of the idle task * including the idle task). The co-routines execute as part of the idle task
* hook. The application is limited in size to allow its compilation using * hook. The application is limited in size to allow its compilation using
* the KickStart version of the IAR compiler. * the KickStart version of the IAR compiler.
* *
* Six of the created co-routines are the standard 'co-routine flash' * Six of the created co-routines are the standard 'co-routine flash'
* co-routines contained within the Demo/Common/Minimal/crflash.c file and * co-routines contained within the Demo/Common/Minimal/crflash.c file and
* documented on the FreeRTOS.org WEB site. * documented on the FreeRTOS.org WEB site.
* *
* The 'LCD Task' waits on a message queue for messages informing it what and * The 'LCD Task' waits on a message queue for messages informing it what and
* where to display text. This is the only task that accesses the LCD * where to display text. This is the only task that accesses the LCD
@ -45,34 +45,34 @@
* The 'ADC Co-routine' periodically reads the ADC input that is connected to * The 'ADC Co-routine' periodically reads the ADC input that is connected to
* the light sensor, forms a short message from the value, and then sends this * the light sensor, forms a short message from the value, and then sends this
* message to the LCD Task using the same message queue. The ADC readings are * message to the LCD Task using the same message queue. The ADC readings are
* displayed on the bottom row of the LCD. * displayed on the bottom row of the LCD.
* *
* The eighth co-routine and final task control the transmission and reception * The eighth co-routine and final task control the transmission and reception
* of a string to UART 0. The co-routine periodically sends the first * of a string to UART 0. The co-routine periodically sends the first
* character of the string to the UART, with the UART's TxEnd interrupt being * character of the string to the UART, with the UART's TxEnd interrupt being
* used to transmit the remaining characters. The UART's RxEnd interrupt * used to transmit the remaining characters. The UART's RxEnd interrupt
* receives the characters and places them on a queue to be processed by the * receives the characters and places them on a queue to be processed by the
* 'COMs Rx' task. An error is latched should an unexpected character be * 'COMs Rx' task. An error is latched should an unexpected character be
* received, or any character be received out of sequence. * received, or any character be received out of sequence.
* *
* A loopback connector is required to ensure that each character transmitted * A loopback connector is required to ensure that each character transmitted
* on the UART is also received on the same UART. For test purposes the UART * on the UART is also received on the same UART. For test purposes the UART
* FIFO's are not utalised in order to maximise the interrupt overhead. Also * FIFO's are not utalised in order to maximise the interrupt overhead. Also
* a pseudo random interval is used between the start of each transmission in * a pseudo random interval is used between the start of each transmission in
* order that the resultant interrupts are more randomly distributed and * order that the resultant interrupts are more randomly distributed and
* therefore more likely to highlight any problems. * therefore more likely to highlight any problems.
* *
* The flash co-routines control LED's zero to four. LED five is toggled each * The flash co-routines control LED's zero to four. LED five is toggled each
* time the string is transmitted on the UART. LED six is toggled each time * time the string is transmitted on the UART. LED six is toggled each time
* the string is CORRECTLY received on the UART. LED seven is latched on * the string is CORRECTLY received on the UART. LED seven is latched on
* should an error be detected in any task or co-routine. * should an error be detected in any task or co-routine.
* *
* In addition the idle task makes repetitive calls to * In addition the idle task makes repetitive calls to
* vSetAndCheckRegisters(). This simply loads the general purpose registers * vSetAndCheckRegisters(). This simply loads the general purpose registers
* with a known value, then checks each register to ensure the held value is * with a known value, then checks each register to ensure the held value is
* still correct. As a low priority task this checking routine is likely to * still correct. As a low priority task this checking routine is likely to
* get repeatedly swapped in and out. A register being found to contain an * get repeatedly swapped in and out. A register being found to contain an
* incorrect value is therefore indicative of an error in the task switching * incorrect value is therefore indicative of an error in the task switching
* mechanism. * mechanism.
* *
*/ */
@ -95,43 +95,43 @@
#include "DriverLib.h" #include "DriverLib.h"
/* The time to delay between writing each character to the LCD. */ /* The time to delay between writing each character to the LCD. */
#define mainCHAR_WRITE_DELAY ( 2 / portTICK_PERIOD_MS ) #define mainCHAR_WRITE_DELAY ( 2 / portTICK_PERIOD_MS )
/* The time to delay between writing each string to the LCD. */ /* The time to delay between writing each string to the LCD. */
#define mainSTRING_WRITE_DELAY ( 400 / portTICK_PERIOD_MS ) #define mainSTRING_WRITE_DELAY ( 400 / portTICK_PERIOD_MS )
#define mainADC_DELAY ( 200 / portTICK_PERIOD_MS ) #define mainADC_DELAY ( 200 / portTICK_PERIOD_MS )
/* The number of flash co-routines to create. */ /* The number of flash co-routines to create. */
#define mainNUM_FLASH_CO_ROUTINES ( 5 ) #define mainNUM_FLASH_CO_ROUTINES ( 5 )
/* The length of the queue used to send messages to the LCD task. */ /* The length of the queue used to send messages to the LCD task. */
#define mainLCD_QUEUE_LEN ( 3 ) #define mainLCD_QUEUE_LEN ( 3 )
/* The priority of the co-routine used to initiate the transmission of the /* The priority of the co-routine used to initiate the transmission of the
string on UART 0. */ * string on UART 0. */
#define mainTX_CO_ROUTINE_PRIORITY ( 1 ) #define mainTX_CO_ROUTINE_PRIORITY ( 1 )
#define mainADC_CO_ROUTINE_PRIORITY ( 2 ) #define mainADC_CO_ROUTINE_PRIORITY ( 2 )
/* Only one of each co-routine is created so its index is not important. */ /* Only one of each co-routine is created so its index is not important. */
#define mainTX_CO_ROUTINE_INDEX ( 0 ) #define mainTX_CO_ROUTINE_INDEX ( 0 )
#define mainADC_CO_ROUTINE_INDEX ( 0 ) #define mainADC_CO_ROUTINE_INDEX ( 0 )
/* The task priorities. */ /* The task priorities. */
#define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainMSG_TASK_PRIORITY ( mainLCD_TASK_PRIORITY - 1 ) #define mainMSG_TASK_PRIORITY ( mainLCD_TASK_PRIORITY - 1 )
#define mainCOMMS_RX_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainCOMMS_RX_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The LCD had two rows. */ /* The LCD had two rows. */
#define mainTOP_ROW 0 #define mainTOP_ROW 0
#define mainBOTTOM_ROW 1 #define mainBOTTOM_ROW 1
/* Dimension for the buffer into which the ADC value string is written. */ /* Dimension for the buffer into which the ADC value string is written. */
#define mainMAX_ADC_STRING_LEN 20 #define mainMAX_ADC_STRING_LEN 20
/* The LED that is lit should an error be detected in any of the tasks or /* The LED that is lit should an error be detected in any of the tasks or
co-routines. */ * co-routines. */
#define mainFAIL_LED ( 7 ) #define mainFAIL_LED ( 7 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -149,7 +149,8 @@ static void prvLCDMessageTask( void * pvParameters );
* The co-routine that reads the ADC and sends messages for display on the * The co-routine that reads the ADC and sends messages for display on the
* bottom row of the LCD. * bottom row of the LCD.
*/ */
static void prvADCCoRoutine( CoRoutineHandle_t xHandle, unsigned portBASE_TYPE uxIndex ); static void prvADCCoRoutine( CoRoutineHandle_t xHandle,
unsigned portBASE_TYPE uxIndex );
/* /*
* Function to simply set a known value into the general purpose registers * Function to simply set a known value into the general purpose registers
@ -159,14 +160,15 @@ static void prvADCCoRoutine( CoRoutineHandle_t xHandle, unsigned portBASE_TYPE u
extern void vSetAndCheckRegisters( void ); extern void vSetAndCheckRegisters( void );
/* /*
* Latch the LED that indicates that an error has occurred. * Latch the LED that indicates that an error has occurred.
*/ */
void vSetErrorLED( void ); void vSetErrorLED( void );
/* /*
* Thread safe write to the PDC. * Thread safe write to the PDC.
*/ */
static void prvPDCWrite( char cAddress, char cData ); static void prvPDCWrite( char cAddress,
char cData );
/* /*
* Sets up the hardware used by the demo. * Sets up the hardware used by the demo.
@ -179,12 +181,12 @@ static void prvSetupHardware( void );
/* The structure that is passed on the LCD message queue. */ /* The structure that is passed on the LCD message queue. */
typedef struct typedef struct
{ {
char **ppcMessageToDisplay; /*<< Points to a char* pointing to the message to display. */ char ** ppcMessageToDisplay; /*<< Points to a char* pointing to the message to display. */
portBASE_TYPE xRow; /*<< The row on which the message should be displayed. */ portBASE_TYPE xRow; /*<< The row on which the message should be displayed. */
} xLCDMessage; } xLCDMessage;
/* Error flag set to pdFAIL if an error is encountered in the tasks/co-routines /* Error flag set to pdFAIL if an error is encountered in the tasks/co-routines
defined within this file. */ * defined within this file. */
unsigned portBASE_TYPE uxErrorStatus = pdPASS; unsigned portBASE_TYPE uxErrorStatus = pdPASS;
/* The queue used to transmit messages to the LCD task. */ /* The queue used to transmit messages to the LCD task. */
@ -197,242 +199,250 @@ static QueueHandle_t xLCDQueue;
*/ */
void main( void ) void main( void )
{ {
/* Create the queue used by tasks wanting to write to the LCD. */ /* Create the queue used by tasks wanting to write to the LCD. */
xLCDQueue = xQueueCreate( mainLCD_QUEUE_LEN, sizeof( xLCDMessage ) ); xLCDQueue = xQueueCreate( mainLCD_QUEUE_LEN, sizeof( xLCDMessage ) );
/* Setup the ports used by the demo and the clock. */ /* Setup the ports used by the demo and the clock. */
prvSetupHardware(); prvSetupHardware();
/* Create the co-routines that flash the LED's. */ /* Create the co-routines that flash the LED's. */
vStartFlashCoRoutines( mainNUM_FLASH_CO_ROUTINES ); vStartFlashCoRoutines( mainNUM_FLASH_CO_ROUTINES );
/* Create the co-routine that initiates the transmission of characters /* Create the co-routine that initiates the transmission of characters
on the UART and the task that receives them, as described at the top of * on the UART and the task that receives them, as described at the top of
this file. */ * this file. */
xCoRoutineCreate( vSerialTxCoRoutine, mainTX_CO_ROUTINE_PRIORITY, mainTX_CO_ROUTINE_INDEX ); xCoRoutineCreate( vSerialTxCoRoutine, mainTX_CO_ROUTINE_PRIORITY, mainTX_CO_ROUTINE_INDEX );
xTaskCreate( vCommsRxTask, "CMS", configMINIMAL_STACK_SIZE, NULL, mainCOMMS_RX_TASK_PRIORITY, NULL ); xTaskCreate( vCommsRxTask, "CMS", configMINIMAL_STACK_SIZE, NULL, mainCOMMS_RX_TASK_PRIORITY, NULL );
/* Create the task that waits for messages to display on the LCD, plus the /* Create the task that waits for messages to display on the LCD, plus the
task and co-routine that send messages for display (as described at the top * task and co-routine that send messages for display (as described at the top
of this file. */ * of this file. */
xTaskCreate( prvLCDTask, "LCD", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainLCD_TASK_PRIORITY, NULL ); xTaskCreate( prvLCDTask, "LCD", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainLCD_TASK_PRIORITY, NULL );
xTaskCreate( prvLCDMessageTask, "MSG", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainMSG_TASK_PRIORITY, NULL ); xTaskCreate( prvLCDMessageTask, "MSG", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainMSG_TASK_PRIORITY, NULL );
xCoRoutineCreate( prvADCCoRoutine, mainADC_CO_ROUTINE_PRIORITY, mainADC_CO_ROUTINE_INDEX ); xCoRoutineCreate( prvADCCoRoutine, mainADC_CO_ROUTINE_PRIORITY, mainADC_CO_ROUTINE_INDEX );
/* Start the scheduler running the tasks and co-routines just created. */ /* Start the scheduler running the tasks and co-routines just created. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Should not get here unless we did not have enough memory to start the /* Should not get here unless we did not have enough memory to start the
scheduler. */ * scheduler. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvLCDMessageTask( void * pvParameters ) static void prvLCDMessageTask( void * pvParameters )
{ {
/* The strings that are written to the LCD. */ /* The strings that are written to the LCD. */
char *pcStringsToDisplay[] = { char * pcStringsToDisplay[] =
"IAR ", {
"Stellaris ", "IAR ",
"Demo ", "Stellaris ",
"www.FreeRTOS.org", "Demo ",
"" "www.FreeRTOS.org",
}; ""
};
QueueHandle_t *pxLCDQueue; QueueHandle_t * pxLCDQueue;
xLCDMessage xMessageToSend; xLCDMessage xMessageToSend;
portBASE_TYPE xIndex = 0; portBASE_TYPE xIndex = 0;
/* To test the parameter passing mechanism, the queue on which messages are /* To test the parameter passing mechanism, the queue on which messages are
posted is passed in as a parameter even though it is available as a file * posted is passed in as a parameter even though it is available as a file
scope variable anyway. */ * scope variable anyway. */
pxLCDQueue = ( QueueHandle_t * ) pvParameters; pxLCDQueue = ( QueueHandle_t * ) pvParameters;
for( ;; ) for( ; ; )
{ {
/* Wait until it is time to move onto the next string. */ /* Wait until it is time to move onto the next string. */
vTaskDelay( mainSTRING_WRITE_DELAY ); vTaskDelay( mainSTRING_WRITE_DELAY );
/* Create the message object to send to the LCD task. */
xMessageToSend.ppcMessageToDisplay = &pcStringsToDisplay[ xIndex ];
xMessageToSend.xRow = mainTOP_ROW;
/* Post the message to be displayed. */
if( !xQueueSend( *pxLCDQueue, ( void * ) &xMessageToSend, 0 ) )
{
uxErrorStatus = pdFAIL;
}
/* Move onto the next message, wrapping when necessary. */
xIndex++;
if( *( pcStringsToDisplay[ xIndex ] ) == 0x00 )
{
xIndex = 0;
/* Delay longer before going back to the start of the messages. */ /* Create the message object to send to the LCD task. */
vTaskDelay( mainSTRING_WRITE_DELAY * 2 ); xMessageToSend.ppcMessageToDisplay = &pcStringsToDisplay[ xIndex ];
} xMessageToSend.xRow = mainTOP_ROW;
}
/* Post the message to be displayed. */
if( !xQueueSend( *pxLCDQueue, ( void * ) &xMessageToSend, 0 ) )
{
uxErrorStatus = pdFAIL;
}
/* Move onto the next message, wrapping when necessary. */
xIndex++;
if( *( pcStringsToDisplay[ xIndex ] ) == 0x00 )
{
xIndex = 0;
/* Delay longer before going back to the start of the messages. */
vTaskDelay( mainSTRING_WRITE_DELAY * 2 );
}
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void prvLCDTask( void * pvParameters ) void prvLCDTask( void * pvParameters )
{ {
unsigned portBASE_TYPE uxIndex; unsigned portBASE_TYPE uxIndex;
QueueHandle_t *pxLCDQueue; QueueHandle_t * pxLCDQueue;
xLCDMessage xReceivedMessage; xLCDMessage xReceivedMessage;
char *pcString; char * pcString;
const unsigned char ucCFGData[] = { const unsigned char ucCFGData[] =
0x30, /* Set data bus to 8-bits. */ {
0x30, 0x30, /* Set data bus to 8-bits. */
0x30, 0x30,
0x3C, /* Number of lines/font. */ 0x30,
0x08, /* Display off. */ 0x3C, /* Number of lines/font. */
0x01, /* Display clear. */ 0x08, /* Display off. */
0x06, /* Entry mode [cursor dir][shift]. */ 0x01, /* Display clear. */
0x0C /* Display on [display on][curson on][blinking on]. */ 0x06, /* Entry mode [cursor dir][shift]. */
}; 0x0C /* Display on [display on][curson on][blinking on]. */
};
/* To test the parameter passing mechanism, the queue on which messages are /* To test the parameter passing mechanism, the queue on which messages are
received is passed in as a parameter even though it is available as a file * received is passed in as a parameter even though it is available as a file
scope variable anyway. */ * scope variable anyway. */
pxLCDQueue = ( QueueHandle_t * ) pvParameters; pxLCDQueue = ( QueueHandle_t * ) pvParameters;
/* Configure the LCD. */ /* Configure the LCD. */
uxIndex = 0; uxIndex = 0;
while( uxIndex < sizeof( ucCFGData ) )
{
prvPDCWrite( PDC_LCD_CSR, ucCFGData[ uxIndex ] );
uxIndex++;
vTaskDelay( mainCHAR_WRITE_DELAY );
}
/* Turn the LCD Backlight on. */ while( uxIndex < sizeof( ucCFGData ) )
prvPDCWrite( PDC_CSR, 0x01 ); {
prvPDCWrite( PDC_LCD_CSR, ucCFGData[ uxIndex ] );
uxIndex++;
vTaskDelay( mainCHAR_WRITE_DELAY );
}
/* Clear display. */ /* Turn the LCD Backlight on. */
vTaskDelay( mainCHAR_WRITE_DELAY ); prvPDCWrite( PDC_CSR, 0x01 );
prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR );
uxIndex = 0; /* Clear display. */
for( ;; ) vTaskDelay( mainCHAR_WRITE_DELAY );
{ prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR );
/* Wait for a message to arrive. */
if( xQueueReceive( *pxLCDQueue, &xReceivedMessage, portMAX_DELAY ) )
{
/* Which row does the received message say to write to? */
PDCLCDSetPos( 0, xReceivedMessage.xRow );
/* Where is the string we are going to display? */ uxIndex = 0;
pcString = *xReceivedMessage.ppcMessageToDisplay;
for( ; ; )
while( *pcString ) {
{ /* Wait for a message to arrive. */
/* Don't write out the string too quickly as LCD's are usually if( xQueueReceive( *pxLCDQueue, &xReceivedMessage, portMAX_DELAY ) )
pretty slow devices. */ {
vTaskDelay( mainCHAR_WRITE_DELAY ); /* Which row does the received message say to write to? */
prvPDCWrite( PDC_LCD_RAM, *pcString ); PDCLCDSetPos( 0, xReceivedMessage.xRow );
pcString++;
} /* Where is the string we are going to display? */
} pcString = *xReceivedMessage.ppcMessageToDisplay;
}
while( *pcString )
{
/* Don't write out the string too quickly as LCD's are usually
* pretty slow devices. */
vTaskDelay( mainCHAR_WRITE_DELAY );
prvPDCWrite( PDC_LCD_RAM, *pcString );
pcString++;
}
}
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvADCCoRoutine( CoRoutineHandle_t xHandle, unsigned portBASE_TYPE uxIndex ) static void prvADCCoRoutine( CoRoutineHandle_t xHandle,
unsigned portBASE_TYPE uxIndex )
{ {
static unsigned long ulADCValue; static unsigned long ulADCValue;
static char cMessageBuffer[ mainMAX_ADC_STRING_LEN ]; static char cMessageBuffer[ mainMAX_ADC_STRING_LEN ];
static char *pcMessage; static char * pcMessage;
static xLCDMessage xMessageToSend; static xLCDMessage xMessageToSend;
/* Co-routines MUST start with a call to crSTART(). */ /* Co-routines MUST start with a call to crSTART(). */
crSTART( xHandle ); crSTART( xHandle );
for( ;; )
{
/* Start an ADC conversion. */
ADCProcessorTrigger( ADC_BASE, 0 );
/* Simply delay - when we unblock the result should be available */
crDELAY( xHandle, mainADC_DELAY );
/* Get the ADC result. */
ADCSequenceDataGet( ADC_BASE, 0, &ulADCValue );
/* Create a string with the result. */ for( ; ; )
sprintf( cMessageBuffer, "ADC = %d ", ulADCValue ); {
pcMessage = cMessageBuffer; /* Start an ADC conversion. */
ADCProcessorTrigger( ADC_BASE, 0 );
/* Configure the message we are going to send for display. */ /* Simply delay - when we unblock the result should be available */
xMessageToSend.ppcMessageToDisplay = ( char** ) &pcMessage; crDELAY( xHandle, mainADC_DELAY );
xMessageToSend.xRow = mainBOTTOM_ROW;
/* Get the ADC result. */
/* Send the string to the LCD task for display. We are sending ADCSequenceDataGet( ADC_BASE, 0, &ulADCValue );
on a task queue so do not have the option to block. */
if( !xQueueSend( xLCDQueue, ( void * ) &xMessageToSend, 0 ) ) /* Create a string with the result. */
{ sprintf( cMessageBuffer, "ADC = %d ", ulADCValue );
uxErrorStatus = pdFAIL; pcMessage = cMessageBuffer;
}
} /* Configure the message we are going to send for display. */
xMessageToSend.ppcMessageToDisplay = ( char ** ) &pcMessage;
/* Co-routines MUST end with a call to crEND(). */ xMessageToSend.xRow = mainBOTTOM_ROW;
crEND();
/* Send the string to the LCD task for display. We are sending
* on a task queue so do not have the option to block. */
if( !xQueueSend( xLCDQueue, ( void * ) &xMessageToSend, 0 ) )
{
uxErrorStatus = pdFAIL;
}
}
/* Co-routines MUST end with a call to crEND(). */
crEND();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Setup the PLL. */ /* Setup the PLL. */
SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ ); SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ );
/* Initialise the hardware used to talk to the LCD, LED's and UART. */
PDCInit();
vParTestInitialise();
vSerialInit();
/* The ADC is used to read the light sensor. */ /* Initialise the hardware used to talk to the LCD, LED's and UART. */
SysCtlPeripheralEnable( SYSCTL_PERIPH_ADC ); PDCInit();
ADCSequenceConfigure( ADC_BASE, 3, ADC_TRIGGER_PROCESSOR, 0); vParTestInitialise();
vSerialInit();
/* The ADC is used to read the light sensor. */
SysCtlPeripheralEnable( SYSCTL_PERIPH_ADC );
ADCSequenceConfigure( ADC_BASE, 3, ADC_TRIGGER_PROCESSOR, 0 );
ADCSequenceStepConfigure( ADC_BASE, 0, 0, ADC_CTL_CH0 | ADC_CTL_END ); ADCSequenceStepConfigure( ADC_BASE, 0, 0, ADC_CTL_CH0 | ADC_CTL_END );
ADCSequenceEnable( ADC_BASE, 0 ); ADCSequenceEnable( ADC_BASE, 0 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvPDCWrite( char cAddress, char cData ) static void prvPDCWrite( char cAddress,
char cData )
{ {
vTaskSuspendAll(); vTaskSuspendAll();
{ {
PDCWrite( cAddress, cData ); PDCWrite( cAddress, cData );
} }
xTaskResumeAll(); xTaskResumeAll();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vSetErrorLED( void ) void vSetErrorLED( void )
{ {
vParTestSetLED( mainFAIL_LED, pdTRUE ); vParTestSetLED( mainFAIL_LED, pdTRUE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* The co-routines are executed in the idle task using the idle task /* The co-routines are executed in the idle task using the idle task
hook. */ * hook. */
for( ;; ) for( ; ; )
{ {
/* Schedule the co-routines. */ /* Schedule the co-routines. */
vCoRoutineSchedule(); vCoRoutineSchedule();
/* Run the register check function between each co-routine. */ /* Run the register check function between each co-routine. */
vSetAndCheckRegisters(); vSetAndCheckRegisters();
/* See if the comms task and co-routine has found any errors. */ /* See if the comms task and co-routine has found any errors. */
if( uxGetCommsStatus() != pdPASS ) if( uxGetCommsStatus() != pdPASS )
{ {
vParTestSetLED( mainFAIL_LED, pdTRUE ); vParTestSetLED( mainFAIL_LED, pdTRUE );
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -49,10 +49,10 @@
* "qemu-system-arm -machine lm3s6965evb -s -S -kernel [pat_to]\RTOSDemo.elf" * "qemu-system-arm -machine lm3s6965evb -s -S -kernel [pat_to]\RTOSDemo.elf"
* *
* To enable FreeRTOS+Trace: * To enable FreeRTOS+Trace:
* 1) Add #include "trcRecorder.h" to the bottom of FreeRTOSConfig.h. * 1) Add #include "trcRecorder.h" to the bottom of FreeRTOSConfig.h.
* 2) Call vTraceEnable( TRC_START ); at the top of main. * 2) Call vTraceEnable( TRC_START ); at the top of main.
* 3) Ensure the "FreeRTOS+Trace Recorder" folder in the Project Explorer * 3) Ensure the "FreeRTOS+Trace Recorder" folder in the Project Explorer
* window is not excluded from the build. * window is not excluded from the build.
* *
* To retrieve the trace files: * To retrieve the trace files:
* 1) Use the Memory windows in the Debug perspective to dump RAM from the * 1) Use the Memory windows in the Debug perspective to dump RAM from the
@ -60,10 +60,10 @@
*/ */
/************************************************************************* /*************************************************************************
* Please ensure to read http://www.freertos.org/portlm3sx965.html * Please ensure to read http://www.freertos.org/portlm3sx965.html
* which provides information on configuring and running this demo for the * which provides information on configuring and running this demo for the
* various Luminary Micro EKs. * various Luminary Micro EKs.
*************************************************************************/ *************************************************************************/
/* Standard includes. */ /* Standard includes. */
#include <stdio.h> #include <stdio.h>
@ -101,37 +101,37 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The time between cycles of the 'check' functionality (defined within the /* The time between cycles of the 'check' functionality (defined within the
tick hook. */ * tick hook. */
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* Task stack sizes. */ /* Task stack sizes. */
#define mainOLED_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 40 ) #define mainOLED_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 40 )
#define mainMESSAGE_BUFFER_TASKS_STACK_SIZE ( 100 ) #define mainMESSAGE_BUFFER_TASKS_STACK_SIZE ( 100 )
/* Task priorities. */ /* Task priorities. */
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* The maximum number of message that can be waiting for display at any one /* The maximum number of message that can be waiting for display at any one
time. */ * time. */
#define mainOLED_QUEUE_SIZE ( 3 ) #define mainOLED_QUEUE_SIZE ( 3 )
/* Dimensions the buffer into which the jitter time is written. */ /* Dimensions the buffer into which the jitter time is written. */
#define mainMAX_MSG_LEN 25 #define mainMAX_MSG_LEN 25
/* The period of the system clock in nano seconds. This is used to calculate /* The period of the system clock in nano seconds. This is used to calculate
the jitter time in nano seconds. */ * the jitter time in nano seconds. */
#define mainNS_PER_CLOCK ( ( uint32_t ) ( ( 1.0 / ( double ) configCPU_CLOCK_HZ ) * 1000000000.0 ) ) #define mainNS_PER_CLOCK ( ( uint32_t ) ( ( 1.0 / ( double ) configCPU_CLOCK_HZ ) * 1000000000.0 ) )
/* Constants used when writing strings to the display. */ /* Constants used when writing strings to the display. */
#define mainCHARACTER_HEIGHT ( 9 ) #define mainCHARACTER_HEIGHT ( 9 )
#define mainMAX_ROWS_128 ( mainCHARACTER_HEIGHT * 14 ) #define mainMAX_ROWS_128 ( mainCHARACTER_HEIGHT * 14 )
#define mainMAX_ROWS_96 ( mainCHARACTER_HEIGHT * 10 ) #define mainMAX_ROWS_96 ( mainCHARACTER_HEIGHT * 10 )
#define mainMAX_ROWS_64 ( mainCHARACTER_HEIGHT * 7 ) #define mainMAX_ROWS_64 ( mainCHARACTER_HEIGHT * 7 )
#define mainFULL_SCALE ( 15 ) #define mainFULL_SCALE ( 15 )
#define ulSSI_FREQUENCY ( 3500000UL ) #define ulSSI_FREQUENCY ( 3500000UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -141,7 +141,7 @@ the jitter time in nano seconds. */
* access the display directly. Other tasks wanting to display a message send * access the display directly. Other tasks wanting to display a message send
* the message to the gatekeeper. * the message to the gatekeeper.
*/ */
static void prvOLEDTask( void *pvParameters ); static void prvOLEDTask( void * pvParameters );
/* /*
* Configure the hardware for the demo. * Configure the hardware for the demo.
@ -157,7 +157,8 @@ extern void vSetupHighFrequencyTimer( void );
/* /*
* Hook functions that can get called by the kernel. * Hook functions that can get called by the kernel.
*/ */
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/* /*
@ -176,294 +177,315 @@ const char * const pcWelcomeMessage = " www.FreeRTOS.org";
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/************************************************************************* /*************************************************************************
* Please ensure to read http://www.freertos.org/portlm3sx965.html * Please ensure to read http://www.freertos.org/portlm3sx965.html
* which provides information on configuring and running this demo for the * which provides information on configuring and running this demo for the
* various Luminary Micro EKs. * various Luminary Micro EKs.
*************************************************************************/ *************************************************************************/
int main( void ) int main( void )
{ {
/* Initialise the trace recorder. Use of the trace recorder is optional. /* Initialise the trace recorder. Use of the trace recorder is optional.
See http://www.FreeRTOS.org/trace for more information and the comments at * See http://www.FreeRTOS.org/trace for more information and the comments at
the top of this file regarding enabling trace in this demo. * the top of this file regarding enabling trace in this demo.
vTraceEnable( TRC_START ); */ * vTraceEnable( TRC_START ); */
prvSetupHardware(); prvSetupHardware();
/* Create the queue used by the OLED task. Messages for display on the OLED /* Create the queue used by the OLED task. Messages for display on the OLED
are received via this queue. */ * are received via this queue. */
xOLEDQueue = xQueueCreate( mainOLED_QUEUE_SIZE, sizeof( char * ) ); xOLEDQueue = xQueueCreate( mainOLED_QUEUE_SIZE, sizeof( char * ) );
/* Start the standard demo tasks. */ /* Start the standard demo tasks. */
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartQueuePeekTasks(); vStartQueuePeekTasks();
vStartQueueSetTasks(); vStartQueueSetTasks();
vStartEventGroupTasks(); vStartEventGroupTasks();
vStartMessageBufferTasks( mainMESSAGE_BUFFER_TASKS_STACK_SIZE ); vStartMessageBufferTasks( mainMESSAGE_BUFFER_TASKS_STACK_SIZE );
vStartStreamBufferTasks(); vStartStreamBufferTasks();
/* Start the tasks defined within this file/specific to this demo. */ /* Start the tasks defined within this file/specific to this demo. */
xTaskCreate( prvOLEDTask, "OLED", mainOLED_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( prvOLEDTask, "OLED", mainOLED_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
/* The suicide tasks must be created last as they need to know how many /* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation in order to ascertain whether * tasks were running prior to their creation in order to ascertain whether
or not the correct/expected number of tasks are running at any given time. */ * or not the correct/expected number of tasks are running at any given time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Uncomment the following line to configure the high frequency interrupt /* Uncomment the following line to configure the high frequency interrupt
used to measure the interrupt jitter time. * used to measure the interrupt jitter time.
vSetupHighFrequencyTimer(); */ * vSetupHighFrequencyTimer(); */
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle /* Will only get here if there was insufficient memory to create the idle
task. */ * task. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void prvSetupHardware( void ) void prvSetupHardware( void )
{ {
/* If running on Rev A2 silicon, turn the LDO voltage up to 2.75V. This is /* If running on Rev A2 silicon, turn the LDO voltage up to 2.75V. This is
a workaround to allow the PLL to operate reliably. */ * a workaround to allow the PLL to operate reliably. */
if( DEVICE_IS_REVA2 ) if( DEVICE_IS_REVA2 )
{ {
SysCtlLDOSet( SYSCTL_LDO_2_75V ); SysCtlLDOSet( SYSCTL_LDO_2_75V );
} }
/* Set the clocking to run from the PLL at 50 MHz */ /* Set the clocking to run from the PLL at 50 MHz */
SysCtlClockSet( SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ ); SysCtlClockSet( SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ );
/* Initialise the UART - QEMU usage does not seem to require this /* Initialise the UART - QEMU usage does not seem to require this
initialisation. */ * initialisation. */
SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 ); SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
UARTEnable( UART0_BASE ); UARTEnable( UART0_BASE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
static const char * pcMessage = "PASS"; static const char * pcMessage = "PASS";
static uint32_t ulTicksSinceLastDisplay = 0; static uint32_t ulTicksSinceLastDisplay = 0;
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* Called from every tick interrupt. Have enough ticks passed to make it /* Called from every tick interrupt. Have enough ticks passed to make it
time to perform our health status check again? */ * time to perform our health status check again? */
ulTicksSinceLastDisplay++; ulTicksSinceLastDisplay++;
if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
{
ulTicksSinceLastDisplay = 0;
/* Has an error been found in any task? */ if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
if( xAreStreamBufferTasksStillRunning() != pdTRUE ) {
{ ulTicksSinceLastDisplay = 0;
pcMessage = "ERROR IN STRM";
}
else if( xAreMessageBufferTasksStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN MSG";
}
else if( xIsCreateTaskStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN CREATE";
}
else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN BLOCK TIME";
}
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN SEMAPHORE";
}
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN PEEK Q";
}
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN REC MUTEX";
}
else if( xAreQueueSetTasksStillRunning() != pdPASS )
{
pcMessage = "ERROR IN Q SET";
}
else if( xAreEventGroupTasksStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN EVNT GRP";
}
/* Send the message to the OLED gatekeeper for display. */ /* Has an error been found in any task? */
xHigherPriorityTaskWoken = pdFALSE; if( xAreStreamBufferTasksStillRunning() != pdTRUE )
xQueueSendFromISR( xOLEDQueue, &pcMessage, &xHigherPriorityTaskWoken ); {
} pcMessage = "ERROR IN STRM";
}
else if( xAreMessageBufferTasksStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN MSG";
}
else if( xIsCreateTaskStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN CREATE";
}
else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN BLOCK TIME";
}
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN SEMAPHORE";
}
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN PEEK Q";
}
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN REC MUTEX";
}
else if( xAreQueueSetTasksStillRunning() != pdPASS )
{
pcMessage = "ERROR IN Q SET";
}
else if( xAreEventGroupTasksStillRunning() != pdTRUE )
{
pcMessage = "ERROR IN EVNT GRP";
}
/* Write to a queue that is in use as part of the queue set demo to /* Send the message to the OLED gatekeeper for display. */
demonstrate using queue sets from an ISR. */ xHigherPriorityTaskWoken = pdFALSE;
vQueueSetAccessQueueSetFromISR(); xQueueSendFromISR( xOLEDQueue, &pcMessage, &xHigherPriorityTaskWoken );
}
/* Call the event group ISR tests. */ /* Write to a queue that is in use as part of the queue set demo to
vPeriodicEventGroupsProcessing(); * demonstrate using queue sets from an ISR. */
vQueueSetAccessQueueSetFromISR();
/* Exercise stream buffers from interrupts. */ /* Call the event group ISR tests. */
vPeriodicStreamBufferProcessing(); vPeriodicEventGroupsProcessing();
/* Exercise stream buffers from interrupts. */
vPeriodicStreamBufferProcessing();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvPrintString( const char * pcString ) static void prvPrintString( const char * pcString )
{ {
while( *pcString != 0x00 ) while( *pcString != 0x00 )
{ {
UARTCharPut( UART0_BASE, *pcString ); UARTCharPut( UART0_BASE, *pcString );
pcString++; pcString++;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void prvOLEDTask( void *pvParameters ) void prvOLEDTask( void * pvParameters )
{ {
const char *pcMessage; const char * pcMessage;
uint32_t ulY, ulMaxY; uint32_t ulY, ulMaxY;
static char cMessage[ mainMAX_MSG_LEN ]; static char cMessage[ mainMAX_MSG_LEN ];
const unsigned char *pucImage; const unsigned char * pucImage;
/* Functions to access the OLED. The one used depends on the dev kit /* Functions to access the OLED. The one used depends on the dev kit
being used. */ * being used. */
void ( *vOLEDInit )( uint32_t ) = NULL; void ( * vOLEDInit )( uint32_t ) = NULL;
void ( *vOLEDStringDraw )( const char *, uint32_t, uint32_t, unsigned char ) = NULL; void ( * vOLEDStringDraw )( const char *,
void ( *vOLEDImageDraw )( const unsigned char *, uint32_t, uint32_t, uint32_t, uint32_t ) = NULL; uint32_t,
void ( *vOLEDClear )( void ) = NULL; uint32_t,
unsigned char ) = NULL;
void ( * vOLEDImageDraw )( const unsigned char *,
uint32_t,
uint32_t,
uint32_t,
uint32_t ) = NULL;
void ( * vOLEDClear )( void ) = NULL;
/* Prevent warnings about unused parameters. */ /* Prevent warnings about unused parameters. */
( void ) pvParameters; ( void ) pvParameters;
/* Map the OLED access functions to the driver functions that are appropriate /* Map the OLED access functions to the driver functions that are appropriate
for the evaluation kit being used. */ * for the evaluation kit being used. */
configASSERT( ( HWREG( SYSCTL_DID1 ) & SYSCTL_DID1_PRTNO_MASK ) == SYSCTL_DID1_PRTNO_6965 ); configASSERT( ( HWREG( SYSCTL_DID1 ) & SYSCTL_DID1_PRTNO_MASK ) == SYSCTL_DID1_PRTNO_6965 );
vOLEDInit = OSRAM128x64x4Init; vOLEDInit = OSRAM128x64x4Init;
vOLEDStringDraw = OSRAM128x64x4StringDraw; vOLEDStringDraw = OSRAM128x64x4StringDraw;
vOLEDImageDraw = OSRAM128x64x4ImageDraw; vOLEDImageDraw = OSRAM128x64x4ImageDraw;
vOLEDClear = OSRAM128x64x4Clear; vOLEDClear = OSRAM128x64x4Clear;
ulMaxY = mainMAX_ROWS_64; ulMaxY = mainMAX_ROWS_64;
pucImage = pucBasicBitmap; pucImage = pucBasicBitmap;
ulY = ulMaxY; ulY = ulMaxY;
/* Initialise the OLED and display a startup message. */ /* Initialise the OLED and display a startup message. */
vOLEDInit( ulSSI_FREQUENCY ); vOLEDInit( ulSSI_FREQUENCY );
vOLEDStringDraw( "POWERED BY FreeRTOS", 0, 0, mainFULL_SCALE ); vOLEDStringDraw( "POWERED BY FreeRTOS", 0, 0, mainFULL_SCALE );
vOLEDImageDraw( pucImage, 0, mainCHARACTER_HEIGHT + 1, bmpBITMAP_WIDTH, bmpBITMAP_HEIGHT ); vOLEDImageDraw( pucImage, 0, mainCHARACTER_HEIGHT + 1, bmpBITMAP_WIDTH, bmpBITMAP_HEIGHT );
for( ;; ) for( ; ; )
{ {
/* Wait for a message to arrive that requires displaying. */ /* Wait for a message to arrive that requires displaying. */
xQueueReceive( xOLEDQueue, &pcMessage, portMAX_DELAY ); xQueueReceive( xOLEDQueue, &pcMessage, portMAX_DELAY );
/* Write the message on the next available row. */ /* Write the message on the next available row. */
ulY += mainCHARACTER_HEIGHT; ulY += mainCHARACTER_HEIGHT;
if( ulY >= ulMaxY )
{
ulY = mainCHARACTER_HEIGHT;
vOLEDClear();
vOLEDStringDraw( pcWelcomeMessage, 0, 0, mainFULL_SCALE );
}
/* Display the message along with the maximum jitter time from the if( ulY >= ulMaxY )
high priority time test. */ {
sprintf( cMessage, "%s %u", pcMessage, ( unsigned int ) xTaskGetTickCount() ); ulY = mainCHARACTER_HEIGHT;
vOLEDStringDraw( cMessage, 0, ulY, mainFULL_SCALE ); vOLEDClear();
prvPrintString( cMessage ); vOLEDStringDraw( pcWelcomeMessage, 0, 0, mainFULL_SCALE );
prvPrintString( "\r\n" ); }
}
/* Display the message along with the maximum jitter time from the
* high priority time test. */
sprintf( cMessage, "%s %u", pcMessage, ( unsigned int ) xTaskGetTickCount() );
vOLEDStringDraw( cMessage, 0, ulY, mainFULL_SCALE );
prvPrintString( cMessage );
prvPrintString( "\r\n" );
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
volatile char *pcOverflowedTask = NULL; /* Prevent task name being optimised away. */ volatile char * pcOverflowedTask = NULL; /* Prevent task name being optimised away. */
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pxTask; ( void ) pxTask;
pcOverflowedTask = pcTaskName; pcOverflowedTask = pcTaskName;
vAssertCalled( __FILE__, __LINE__ ); vAssertCalled( __FILE__, __LINE__ );
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( const char *pcFile, uint32_t ulLine ) void vAssertCalled( const char * pcFile,
uint32_t ulLine )
{ {
volatile uint32_t ulSetTo1InDebuggerToExit = 0; volatile uint32_t ulSetTo1InDebuggerToExit = 0;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
while( ulSetTo1InDebuggerToExit == 0 ) while( ulSetTo1InDebuggerToExit == 0 )
{ {
/* Nothing to do here. Set the loop variable to a non zero value in /* Nothing to do here. Set the loop variable to a non zero value in
the debugger to step out of this function to the point that caused * the debugger to step out of this function to the point that caused
the assertion. */ * the assertion. */
( void ) pcFile; ( void ) pcFile;
( void ) ulLine; ( void ) ulLine;
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
} }
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */ * used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{ {
/* If the buffers to be provided to the Idle task are declared inside this /* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB; static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */ * state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB; *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */ /* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack; *ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory() * application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */ * to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
uint32_t * pulTimerTaskStackSize )
{ {
/* If the buffers to be provided to the Timer task are declared inside this /* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on * function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */ * the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB; static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer /* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */ * task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB; *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */ /* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack; *ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t, * Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
char * _sbrk_r (struct _reent *r, int incr) char * _sbrk_r( struct _reent * r,
int incr )
{ {
/* Just to keep the linker quiet. */ /* Just to keep the linker quiet. */
( void ) r; ( void ) r;
( void ) incr; ( void ) incr;
/* Check this function is never called by forcing an assert() if it is. */ /* Check this function is never called by forcing an assert() if it is. */
configASSERT( incr == -1 ); configASSERT( incr == -1 );
return NULL; return NULL;
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -80,26 +80,27 @@
#include "BlockQ.h" #include "BlockQ.h"
/* Delay between cycles of the 'check' task. */ /* Delay between cycles of the 'check' task. */
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* UART configuration - note this does not use the FIFO so is not very /* UART configuration - note this does not use the FIFO so is not very
efficient. */ * efficient. */
#define mainBAUD_RATE ( 19200 ) #define mainBAUD_RATE ( 19200 )
#define mainFIFO_SET ( 0x10 ) #define mainFIFO_SET ( 0x10 )
/* Demo task priorities. */ /* Demo task priorities. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* Demo board specifics. */ /* Demo board specifics. */
#define mainPUSH_BUTTON GPIO_PIN_4 #define mainPUSH_BUTTON GPIO_PIN_4
/* Misc. */ /* Misc. */
#define mainQUEUE_SIZE ( 3 ) #define mainQUEUE_SIZE ( 3 )
#define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS ) #define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS )
#define mainNO_DELAY ( ( TickType_t ) 0 ) #define mainNO_DELAY ( ( TickType_t ) 0 )
/* /*
* Configure the processor and peripherals for this demo. * Configure the processor and peripherals for this demo.
*/ */
@ -108,25 +109,25 @@ static void prvSetupHardware( void );
/* /*
* The 'check' task, as described at the top of this file. * The 'check' task, as described at the top of this file.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* The task that is woken by the ISR that processes GPIO interrupts originating * The task that is woken by the ISR that processes GPIO interrupts originating
* from the push button. * from the push button.
*/ */
static void vButtonHandlerTask( void *pvParameters ); static void vButtonHandlerTask( void * pvParameters );
/* /*
* The task that controls access to the LCD. * The task that controls access to the LCD.
*/ */
static void vPrintTask( void *pvParameter ); static void vPrintTask( void * pvParameter );
/* String that is transmitted on the UART. */ /* String that is transmitted on the UART. */
static char *cMessage = "Task woken by button interrupt! --- "; static char * cMessage = "Task woken by button interrupt! --- ";
static volatile char *pcNextChar; static volatile char * pcNextChar;
/* The semaphore used to wake the button handler task from within the GPIO /* The semaphore used to wake the button handler task from within the GPIO
interrupt handler. */ * interrupt handler. */
SemaphoreHandle_t xButtonSemaphore; SemaphoreHandle_t xButtonSemaphore;
/* The queue used to send strings to the print task for display on the LCD. */ /* The queue used to send strings to the print task for display on the LCD. */
@ -136,224 +137,226 @@ QueueHandle_t xPrintQueue;
int main( void ) int main( void )
{ {
/* Configure the clocks, UART and GPIO. */ /* Configure the clocks, UART and GPIO. */
prvSetupHardware(); prvSetupHardware();
/* Create the semaphore used to wake the button handler task from the GPIO /* Create the semaphore used to wake the button handler task from the GPIO
ISR. */ * ISR. */
vSemaphoreCreateBinary( xButtonSemaphore ); vSemaphoreCreateBinary( xButtonSemaphore );
xSemaphoreTake( xButtonSemaphore, 0 ); xSemaphoreTake( xButtonSemaphore, 0 );
/* Create the queue used to pass message to vPrintTask. */ /* Create the queue used to pass message to vPrintTask. */
xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( char * ) ); xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( char * ) );
/* Start the standard demo tasks. */ /* Start the standard demo tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
/* Start the tasks defined within the file. */ /* Start the tasks defined within the file. */
xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
xTaskCreate( vButtonHandlerTask, "Status", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY + 1, NULL ); xTaskCreate( vButtonHandlerTask, "Status", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY + 1, NULL );
xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY - 1, NULL ); xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY - 1, NULL );
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient heap to start the /* Will only get here if there was insufficient heap to start the
scheduler. */ * scheduler. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
portBASE_TYPE xErrorOccurred = pdFALSE; portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
const char *pcPassMessage = "PASS"; const char * pcPassMessage = "PASS";
const char *pcFailMessage = "FAIL"; const char * pcFailMessage = "FAIL";
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Perform this check every mainCHECK_DELAY milliseconds. */ /* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
/* Has an error been found in any task? */ /* Has an error been found in any task? */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
} }
if( xArePollingQueuesStillRunning() != pdTRUE )
{
xErrorOccurred = pdTRUE;
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
xErrorOccurred = pdTRUE;
}
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
} }
/* Send either a pass or fail message. If an error is found it is if( xAreSemaphoreTasksStillRunning() != pdTRUE )
never cleared again. We do not write directly to the LCD, but instead {
queue a message for display by the print task. */ xErrorOccurred = pdTRUE;
if( xErrorOccurred == pdTRUE ) }
{
xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY ); if( xAreBlockingQueuesStillRunning() != pdTRUE )
} {
else xErrorOccurred = pdTRUE;
{ }
xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY );
} /* 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. */
if( xErrorOccurred == pdTRUE )
{
xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY );
}
else
{
xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY );
}
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Setup the PLL. */ /* Setup the PLL. */
SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ ); SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ );
/* Setup the push button. */ /* Setup the push button. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOC );
GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN); GPIODirModeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN );
GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE ); GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_FALLING_EDGE );
IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY ); IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY );
GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON ); GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON );
IntEnable( INT_GPIOC ); IntEnable( INT_GPIOC );
/* Enable the UART. */ /* Enable the UART. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOA );
/* Set GPIO A0 and A1 as peripheral function. They are used to output the /* Set GPIO A0 and A1 as peripheral function. They are used to output the
UART signals. */ * UART signals. */
GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW ); GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW );
/* Configure the UART for 8-N-1 operation. */ /* Configure the UART for 8-N-1 operation. */
UARTConfigSet( UART0_BASE, mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE ); UARTConfigSet( UART0_BASE, mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE );
/* We don't want to use the fifo. This is for test purposes to generate /* We don't want to use the fifo. This is for test purposes to generate
as many interrupts as possible. */ * as many interrupts as possible. */
HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET; HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET;
/* Enable Tx interrupts. */ /* Enable Tx interrupts. */
HWREG( UART0_BASE + UART_O_IM ) |= UART_INT_TX; HWREG( UART0_BASE + UART_O_IM ) |= UART_INT_TX;
IntPrioritySet( INT_UART0, configKERNEL_INTERRUPT_PRIORITY ); IntPrioritySet( INT_UART0, configKERNEL_INTERRUPT_PRIORITY );
IntEnable( INT_UART0 ); IntEnable( INT_UART0 );
/* Initialise the LCD> */ /* Initialise the LCD> */
OSRAMInit( false ); OSRAMInit( false );
OSRAMStringDraw("www.FreeRTOS.org", 0, 0); OSRAMStringDraw( "www.FreeRTOS.org", 0, 0 );
OSRAMStringDraw("LM3S811 demo", 16, 1); OSRAMStringDraw( "LM3S811 demo", 16, 1 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vButtonHandlerTask( void *pvParameters ) static void vButtonHandlerTask( void * pvParameters )
{ {
const char *pcInterruptMessage = "Int"; const char * pcInterruptMessage = "Int";
for( ;; ) for( ; ; )
{ {
/* Wait for a GPIO interrupt to wake this task. */ /* Wait for a GPIO interrupt to wake this task. */
while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS ); while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS )
{
}
/* Start the Tx of the message on the UART. */ /* Start the Tx of the message on the UART. */
UARTIntDisable( UART0_BASE, UART_INT_TX ); UARTIntDisable( UART0_BASE, UART_INT_TX );
{ {
pcNextChar = cMessage; pcNextChar = cMessage;
/* Send the first character. */ /* Send the first character. */
if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) ) if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
{ {
HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar; HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
} }
pcNextChar++; pcNextChar++;
} }
UARTIntEnable(UART0_BASE, UART_INT_TX); UARTIntEnable( UART0_BASE, UART_INT_TX );
/* Queue a message for the print task to display on the LCD. */ /* Queue a message for the print task to display on the LCD. */
xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY ); xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY );
/* Make sure we don't process bounces. */ /* Make sure we don't process bounces. */
vTaskDelay( mainDEBOUNCE_DELAY ); vTaskDelay( mainDEBOUNCE_DELAY );
xSemaphoreTake( xButtonSemaphore, mainNO_DELAY ); xSemaphoreTake( xButtonSemaphore, mainNO_DELAY );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vUART_ISR(void) void vUART_ISR( void )
{ {
unsigned long ulStatus; unsigned long ulStatus;
/* What caused the interrupt. */ /* What caused the interrupt. */
ulStatus = UARTIntStatus( UART0_BASE, pdTRUE ); ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
/* Clear the interrupt. */ /* Clear the interrupt. */
UARTIntClear( UART0_BASE, ulStatus ); UARTIntClear( UART0_BASE, ulStatus );
/* Was a Tx interrupt pending? */ /* Was a Tx interrupt pending? */
if( ulStatus & UART_INT_TX ) if( ulStatus & UART_INT_TX )
{ {
/* Send the next character in the string. We are not using the FIFO. */ /* Send the next character in the string. We are not using the FIFO. */
if( *pcNextChar != 0 ) if( *pcNextChar != 0 )
{ {
if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) ) if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
{ {
HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar; HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
} }
pcNextChar++;
} pcNextChar++;
} }
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vGPIO_ISR( void ) void vGPIO_ISR( void )
{ {
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt. */ /* Clear the interrupt. */
GPIOPinIntClear(GPIO_PORTC_BASE, mainPUSH_BUTTON); GPIOPinIntClear( GPIO_PORTC_BASE, mainPUSH_BUTTON );
/* Wake the button handler task. */ /* Wake the button handler task. */
xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters ) static void vPrintTask( void * pvParameters )
{ {
char *pcMessage; char * pcMessage;
unsigned portBASE_TYPE uxLine = 0, uxRow = 0; unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
for( ;; ) for( ; ; )
{ {
/* Wait for a message to arrive. */ /* Wait for a message to arrive. */
xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY ); xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY );
/* Write the message to the LCD. */ /* Write the message to the LCD. */
uxRow++; uxRow++;
uxLine++; uxLine++;
OSRAMClear(); OSRAMClear();
OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01); OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01 );
} }
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -80,26 +80,27 @@
#include "BlockQ.h" #include "BlockQ.h"
/* Delay between cycles of the 'check' task. */ /* Delay between cycles of the 'check' task. */
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* UART configuration - note this does not use the FIFO so is not very /* UART configuration - note this does not use the FIFO so is not very
efficient. */ * efficient. */
#define mainBAUD_RATE ( 19200 ) #define mainBAUD_RATE ( 19200 )
#define mainFIFO_SET ( 0x10 ) #define mainFIFO_SET ( 0x10 )
/* Demo task priorities. */ /* Demo task priorities. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* Demo board specifics. */ /* Demo board specifics. */
#define mainPUSH_BUTTON GPIO_PIN_4 #define mainPUSH_BUTTON GPIO_PIN_4
/* Misc. */ /* Misc. */
#define mainQUEUE_SIZE ( 3 ) #define mainQUEUE_SIZE ( 3 )
#define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS ) #define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS )
#define mainNO_DELAY ( ( TickType_t ) 0 ) #define mainNO_DELAY ( ( TickType_t ) 0 )
/* /*
* Configure the processor and peripherals for this demo. * Configure the processor and peripherals for this demo.
*/ */
@ -108,25 +109,25 @@ static void prvSetupHardware( void );
/* /*
* The 'check' task, as described at the top of this file. * The 'check' task, as described at the top of this file.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* The task that is woken by the ISR that processes GPIO interrupts originating * The task that is woken by the ISR that processes GPIO interrupts originating
* from the push button. * from the push button.
*/ */
static void vButtonHandlerTask( void *pvParameters ); static void vButtonHandlerTask( void * pvParameters );
/* /*
* The task that controls access to the LCD. * The task that controls access to the LCD.
*/ */
static void vPrintTask( void *pvParameter ); static void vPrintTask( void * pvParameter );
/* String that is transmitted on the UART. */ /* String that is transmitted on the UART. */
static char *cMessage = "Task woken by button interrupt! --- "; static char * cMessage = "Task woken by button interrupt! --- ";
static volatile char *pcNextChar; static volatile char * pcNextChar;
/* The semaphore used to wake the button handler task from within the GPIO /* The semaphore used to wake the button handler task from within the GPIO
interrupt handler. */ * interrupt handler. */
SemaphoreHandle_t xButtonSemaphore; SemaphoreHandle_t xButtonSemaphore;
/* The queue used to send strings to the print task for display on the LCD. */ /* The queue used to send strings to the print task for display on the LCD. */
@ -136,223 +137,225 @@ QueueHandle_t xPrintQueue;
int main( void ) int main( void )
{ {
/* Configure the clocks, UART and GPIO. */ /* Configure the clocks, UART and GPIO. */
prvSetupHardware(); prvSetupHardware();
/* Create the semaphore used to wake the button handler task from the GPIO /* Create the semaphore used to wake the button handler task from the GPIO
ISR. */ * ISR. */
vSemaphoreCreateBinary( xButtonSemaphore ); vSemaphoreCreateBinary( xButtonSemaphore );
xSemaphoreTake( xButtonSemaphore, 0 ); xSemaphoreTake( xButtonSemaphore, 0 );
/* Create the queue used to pass message to vPrintTask. */ /* Create the queue used to pass message to vPrintTask. */
xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( char * ) ); xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( char * ) );
/* Start the standard demo tasks. */ /* Start the standard demo tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
/* Start the tasks defined within the file. */ /* Start the tasks defined within the file. */
xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
xTaskCreate( vButtonHandlerTask, "Status", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY + 1, NULL ); xTaskCreate( vButtonHandlerTask, "Status", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY + 1, NULL );
xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY - 1, NULL ); xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY - 1, NULL );
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient heap to start the /* Will only get here if there was insufficient heap to start the
scheduler. */ * scheduler. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
portBASE_TYPE xErrorOccurred = pdFALSE; portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
const char *pcPassMessage = "PASS"; const char * pcPassMessage = "PASS";
const char *pcFailMessage = "FAIL"; const char * pcFailMessage = "FAIL";
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Perform this check every mainCHECK_DELAY milliseconds. */ /* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
/* Has an error been found in any task? */ /* Has an error been found in any task? */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
} }
if( xArePollingQueuesStillRunning() != pdTRUE )
{
xErrorOccurred = pdTRUE;
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
xErrorOccurred = pdTRUE;
}
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
} }
/* Send either a pass or fail message. If an error is found it is if( xAreSemaphoreTasksStillRunning() != pdTRUE )
never cleared again. We do not write directly to the LCD, but instead {
queue a message for display by the print task. */ xErrorOccurred = pdTRUE;
if( xErrorOccurred == pdTRUE ) }
{
xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY ); if( xAreBlockingQueuesStillRunning() != pdTRUE )
} {
else xErrorOccurred = pdTRUE;
{ }
xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY );
} /* 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. */
if( xErrorOccurred == pdTRUE )
{
xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY );
}
else
{
xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY );
}
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Setup the PLL. */ /* Setup the PLL. */
SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ ); SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ );
/* Setup the push button. */ /* Setup the push button. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOC );
GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN); GPIODirModeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN );
GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE ); GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_FALLING_EDGE );
IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY ); IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY );
GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON ); GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON );
IntEnable( INT_GPIOC ); IntEnable( INT_GPIOC );
/* Enable the UART. */ /* Enable the UART. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOA );
/* Set GPIO A0 and A1 as peripheral function. They are used to output the /* Set GPIO A0 and A1 as peripheral function. They are used to output the
UART signals. */ * UART signals. */
GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW ); GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW );
/* Configure the UART for 8-N-1 operation. */ /* Configure the UART for 8-N-1 operation. */
UARTConfigSetExpClk( UART0_BASE, SysCtlClockGet(), mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE ); UARTConfigSetExpClk( UART0_BASE, SysCtlClockGet(), mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE );
/* We don't want to use the fifo. This is for test purposes to generate /* We don't want to use the fifo. This is for test purposes to generate
as many interrupts as possible. */ * as many interrupts as possible. */
HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET; HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET;
/* Enable Tx interrupts. */ /* Enable Tx interrupts. */
HWREG( UART0_BASE + UART_O_IM ) |= UART_INT_TX; HWREG( UART0_BASE + UART_O_IM ) |= UART_INT_TX;
IntPrioritySet( INT_UART0, configKERNEL_INTERRUPT_PRIORITY ); IntPrioritySet( INT_UART0, configKERNEL_INTERRUPT_PRIORITY );
IntEnable( INT_UART0 ); IntEnable( INT_UART0 );
/* Initialise the LCD> */ /* Initialise the LCD> */
OSRAMInit( false ); OSRAMInit( false );
OSRAMStringDraw("www.FreeRTOS.org", 0, 0); OSRAMStringDraw( "www.FreeRTOS.org", 0, 0 );
OSRAMStringDraw("LM3S811 demo", 16, 1); OSRAMStringDraw( "LM3S811 demo", 16, 1 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vButtonHandlerTask( void *pvParameters ) static void vButtonHandlerTask( void * pvParameters )
{ {
const char *pcInterruptMessage = "Int"; const char * pcInterruptMessage = "Int";
for( ;; ) for( ; ; )
{ {
/* Wait for a GPIO interrupt to wake this task. */ /* Wait for a GPIO interrupt to wake this task. */
while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS ); while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS )
{
}
/* Start the Tx of the message on the UART. */ /* Start the Tx of the message on the UART. */
UARTIntDisable( UART0_BASE, UART_INT_TX ); UARTIntDisable( UART0_BASE, UART_INT_TX );
{ {
pcNextChar = cMessage; pcNextChar = cMessage;
/* Send the first character. */ /* Send the first character. */
if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) ) if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
{ {
HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar; HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
} }
pcNextChar++; pcNextChar++;
} }
UARTIntEnable(UART0_BASE, UART_INT_TX); UARTIntEnable( UART0_BASE, UART_INT_TX );
/* Queue a message for the print task to display on the LCD. */ /* Queue a message for the print task to display on the LCD. */
xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY ); xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY );
/* Make sure we don't process bounces. */ /* Make sure we don't process bounces. */
vTaskDelay( mainDEBOUNCE_DELAY ); vTaskDelay( mainDEBOUNCE_DELAY );
xSemaphoreTake( xButtonSemaphore, mainNO_DELAY ); xSemaphoreTake( xButtonSemaphore, mainNO_DELAY );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vUART_ISR(void) void vUART_ISR( void )
{ {
unsigned long ulStatus; unsigned long ulStatus;
/* What caused the interrupt. */ /* What caused the interrupt. */
ulStatus = UARTIntStatus( UART0_BASE, pdTRUE ); ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
/* Clear the interrupt. */ /* Clear the interrupt. */
UARTIntClear( UART0_BASE, ulStatus ); UARTIntClear( UART0_BASE, ulStatus );
/* Was a Tx interrupt pending? */ /* Was a Tx interrupt pending? */
if( ulStatus & UART_INT_TX ) if( ulStatus & UART_INT_TX )
{ {
/* Send the next character in the string. We are not using the FIFO. */ /* Send the next character in the string. We are not using the FIFO. */
if( *pcNextChar != NULL ) if( *pcNextChar != NULL )
{ {
if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) ) if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
{ {
HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar; HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
} }
pcNextChar++;
} pcNextChar++;
} }
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vGPIO_ISR( void ) void vGPIO_ISR( void )
{ {
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt. */ /* Clear the interrupt. */
GPIOPinIntClear(GPIO_PORTC_BASE, mainPUSH_BUTTON); GPIOPinIntClear( GPIO_PORTC_BASE, mainPUSH_BUTTON );
/* Wake the button handler task. */ /* Wake the button handler task. */
xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters ) static void vPrintTask( void * pvParameters )
{ {
char *pcMessage; char * pcMessage;
unsigned portBASE_TYPE uxLine = 0, uxRow = 0; unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
for( ;; ) for( ; ; )
{ {
/* Wait for a message to arrive. */ /* Wait for a message to arrive. */
xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY ); xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY );
/* Write the message to the LCD. */ /* Write the message to the LCD. */
uxRow++; uxRow++;
uxLine++; uxLine++;
OSRAMClear(); OSRAMClear();
OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01); OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01 );
} }
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -26,16 +26,16 @@
/* /*
* This project contains an application demonstrating the use of the * This project contains an application demonstrating the use of the
* FreeRTOS.org mini real time scheduler on the Luminary Micro LM3S811 Eval * FreeRTOS.org mini real time scheduler on the Luminary Micro LM3S811 Eval
* board. See http://www.FreeRTOS.org for more information. * board. See http://www.FreeRTOS.org for more information.
* *
* main() simply sets up the hardware, creates all the demo application tasks, * main() simply sets up the hardware, creates all the demo application tasks,
* then starts the scheduler. http://www.freertos.org/a00102.html provides * then starts the scheduler. http://www.freertos.org/a00102.html provides
* more information on the standard demo tasks. * more information on the standard demo tasks.
* *
* In addition to a subset of the standard demo application tasks, main.c also * In addition to a subset of the standard demo application tasks, main.c also
* defines the following tasks: * defines the following tasks:
* *
* + A 'Print' task. The print task is the only task permitted to access the * + A 'Print' task. The print task is the only task permitted to access the
* LCD - thus ensuring mutual exclusion and consistent access to the resource. * LCD - thus ensuring mutual exclusion and consistent access to the resource.
@ -44,12 +44,12 @@
* blocked - only waking when a message is queued for display. * blocked - only waking when a message is queued for display.
* *
* + A 'Button handler' task. The eval board contains a user push button that * + A 'Button handler' task. The eval board contains a user push button that
* is configured to generate interrupts. The interrupt handler uses a * is configured to generate interrupts. The interrupt handler uses a
* semaphore to wake the button handler task - demonstrating how the priority * semaphore to wake the button handler task - demonstrating how the priority
* mechanism can be used to defer interrupt processing to the task level. The * mechanism can be used to defer interrupt processing to the task level. The
* button handler task sends a message both to the LCD (via the print task) and * button handler task sends a message both to the LCD (via the print task) and
* the UART where it can be viewed using a dumb terminal (via the UART to USB * the UART where it can be viewed using a dumb terminal (via the UART to USB
* converter on the eval board). NOTES: The dumb terminal must be closed in * converter on the eval board). NOTES: The dumb terminal must be closed in
* order to reflash the microcontroller. A very basic interrupt driven UART * order to reflash the microcontroller. A very basic interrupt driven UART
* driver is used that does not use the FIFO. 19200 baud is used. * driver is used that does not use the FIFO. 19200 baud is used.
* *
@ -80,281 +80,287 @@
#include "BlockQ.h" #include "BlockQ.h"
/* Delay between cycles of the 'check' task. */ /* Delay between cycles of the 'check' task. */
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* UART configuration - note this does not use the FIFO so is not very /* UART configuration - note this does not use the FIFO so is not very
efficient. */ * efficient. */
#define mainBAUD_RATE ( 19200 ) #define mainBAUD_RATE ( 19200 )
#define mainFIFO_SET ( 0x10 ) #define mainFIFO_SET ( 0x10 )
/* Demo task priorities. */ /* Demo task priorities. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* Demo board specifics. */ /* Demo board specifics. */
#define mainPUSH_BUTTON GPIO_PIN_4 #define mainPUSH_BUTTON GPIO_PIN_4
/* Misc. */ /* Misc. */
#define mainQUEUE_SIZE ( 3 ) #define mainQUEUE_SIZE ( 3 )
#define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS ) #define mainDEBOUNCE_DELAY ( ( TickType_t ) 150 / portTICK_PERIOD_MS )
#define mainNO_DELAY ( ( TickType_t ) 0 ) #define mainNO_DELAY ( ( TickType_t ) 0 )
/* /*
* Configure the processor and peripherals for this demo. * Configure the processor and peripherals for this demo.
*/ */
static void prvSetupHardware( void ); static void prvSetupHardware( void );
/* /*
* The 'check' task, as described at the top of this file. * The 'check' task, as described at the top of this file.
*/ */
static void vCheckTask( void *pvParameters ); static void vCheckTask( void * pvParameters );
/* /*
* The task that is woken by the ISR that processes GPIO interrupts originating * The task that is woken by the ISR that processes GPIO interrupts originating
* from the push button. * from the push button.
*/ */
static void vButtonHandlerTask( void *pvParameters ); static void vButtonHandlerTask( void * pvParameters );
/* /*
* The task that controls access to the LCD. * The task that controls access to the LCD.
*/ */
static void vPrintTask( void *pvParameter ); static void vPrintTask( void * pvParameter );
/* String that is transmitted on the UART. */ /* String that is transmitted on the UART. */
static char *cMessage = "Task woken by button interrupt! --- "; static char * cMessage = "Task woken by button interrupt! --- ";
static volatile char *pcNextChar; static volatile char * pcNextChar;
/* The semaphore used to wake the button handler task from within the GPIO /* The semaphore used to wake the button handler task from within the GPIO
interrupt handler. */ * interrupt handler. */
SemaphoreHandle_t xButtonSemaphore; SemaphoreHandle_t xButtonSemaphore;
/* The queue used to send strings to the print task for display on the LCD. */ /* The queue used to send strings to the print task for display on the LCD. */
QueueHandle_t xPrintQueue; QueueHandle_t xPrintQueue;
/* Newer library version. */ /* Newer library version. */
extern void UARTConfigSetExpClk(unsigned long ulBase, unsigned long ulUARTClk, unsigned long ulBaud, unsigned long ulConfig); extern void UARTConfigSetExpClk( unsigned long ulBase,
unsigned long ulUARTClk,
unsigned long ulBaud,
unsigned long ulConfig );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
{ {
/* Configure the clocks, UART and GPIO. */ /* Configure the clocks, UART and GPIO. */
prvSetupHardware(); prvSetupHardware();
/* Create the semaphore used to wake the button handler task from the GPIO /* Create the semaphore used to wake the button handler task from the GPIO
ISR. */ * ISR. */
vSemaphoreCreateBinary( xButtonSemaphore ); vSemaphoreCreateBinary( xButtonSemaphore );
xSemaphoreTake( xButtonSemaphore, 0 ); xSemaphoreTake( xButtonSemaphore, 0 );
/* Create the queue used to pass message to vPrintTask. */ /* Create the queue used to pass message to vPrintTask. */
xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( char * ) ); xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( char * ) );
/* Start the standard demo tasks. */ /* Start the standard demo tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
/* Start the tasks defined within the file. */ /* Start the tasks defined within the file. */
xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
xTaskCreate( vButtonHandlerTask, "Status", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY + 1, NULL ); xTaskCreate( vButtonHandlerTask, "Status", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY + 1, NULL );
xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY - 1, NULL ); xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY - 1, NULL );
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient heap to start the /* Will only get here if there was insufficient heap to start the
scheduler. */ * scheduler. */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vCheckTask( void *pvParameters ) static void vCheckTask( void * pvParameters )
{ {
portBASE_TYPE xErrorOccurred = pdFALSE; portBASE_TYPE xErrorOccurred = pdFALSE;
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
const char *pcPassMessage = "PASS"; const char * pcPassMessage = "PASS";
const char *pcFailMessage = "FAIL"; const char * pcFailMessage = "FAIL";
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */ * works correctly. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Perform this check every mainCHECK_DELAY milliseconds. */ /* Perform this check every mainCHECK_DELAY milliseconds. */
vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );
/* Has an error been found in any task? */ /* Has an error been found in any task? */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
} }
if( xArePollingQueuesStillRunning() != pdTRUE )
{
xErrorOccurred = pdTRUE;
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
xErrorOccurred = pdTRUE;
}
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
xErrorOccurred = pdTRUE; xErrorOccurred = pdTRUE;
} }
/* Send either a pass or fail message. If an error is found it is if( xAreSemaphoreTasksStillRunning() != pdTRUE )
never cleared again. We do not write directly to the LCD, but instead {
queue a message for display by the print task. */ xErrorOccurred = pdTRUE;
if( xErrorOccurred == pdTRUE ) }
{
xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY ); if( xAreBlockingQueuesStillRunning() != pdTRUE )
} {
else xErrorOccurred = pdTRUE;
{ }
xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY );
} /* 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. */
if( xErrorOccurred == pdTRUE )
{
xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY );
}
else
{
xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY );
}
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Setup the PLL. */ /* Setup the PLL. */
SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ ); SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ );
/* Setup the push button. */ /* Setup the push button. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOC );
GPIODirModeSet(GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN); GPIODirModeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_DIR_MODE_IN );
GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON,GPIO_FALLING_EDGE ); GPIOIntTypeSet( GPIO_PORTC_BASE, mainPUSH_BUTTON, GPIO_FALLING_EDGE );
IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY ); IntPrioritySet( INT_GPIOC, configKERNEL_INTERRUPT_PRIORITY );
GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON ); GPIOPinIntEnable( GPIO_PORTC_BASE, mainPUSH_BUTTON );
IntEnable( INT_GPIOC ); IntEnable( INT_GPIOC );
/* Enable the UART. */ /* Enable the UART. */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 );
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOA );
/* Set GPIO A0 and A1 as peripheral function. They are used to output the /* Set GPIO A0 and A1 as peripheral function. They are used to output the
UART signals. */ * UART signals. */
GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW ); GPIODirModeSet( GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW );
/* Configure the UART for 8-N-1 operation. */ /* Configure the UART for 8-N-1 operation. */
UARTConfigSetExpClk( UART0_BASE, SysCtlClockGet(), mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE ); UARTConfigSetExpClk( UART0_BASE, SysCtlClockGet(), mainBAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE );
/* We don't want to use the fifo. This is for test purposes to generate /* We don't want to use the fifo. This is for test purposes to generate
as many interrupts as possible. */ * as many interrupts as possible. */
HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET; HWREG( UART0_BASE + UART_O_LCR_H ) &= ~mainFIFO_SET;
/* Enable Tx interrupts. */ /* Enable Tx interrupts. */
HWREG( UART0_BASE + UART_O_IM ) |= UART_INT_TX; HWREG( UART0_BASE + UART_O_IM ) |= UART_INT_TX;
IntPrioritySet( INT_UART0, configKERNEL_INTERRUPT_PRIORITY ); IntPrioritySet( INT_UART0, configKERNEL_INTERRUPT_PRIORITY );
IntEnable( INT_UART0 ); IntEnable( INT_UART0 );
/* Initialise the LCD> */ /* Initialise the LCD> */
OSRAMInit( false ); OSRAMInit( false );
OSRAMStringDraw("www.FreeRTOS.org", 0, 0); OSRAMStringDraw( "www.FreeRTOS.org", 0, 0 );
OSRAMStringDraw("LM3S811 demo", 16, 1); OSRAMStringDraw( "LM3S811 demo", 16, 1 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vButtonHandlerTask( void *pvParameters ) static void vButtonHandlerTask( void * pvParameters )
{ {
const char *pcInterruptMessage = "Int"; const char * pcInterruptMessage = "Int";
for( ;; ) for( ; ; )
{ {
/* Wait for a GPIO interrupt to wake this task. */ /* Wait for a GPIO interrupt to wake this task. */
while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS ); while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS )
{
}
/* Start the Tx of the message on the UART. */ /* Start the Tx of the message on the UART. */
UARTIntDisable( UART0_BASE, UART_INT_TX ); UARTIntDisable( UART0_BASE, UART_INT_TX );
{ {
pcNextChar = cMessage; pcNextChar = cMessage;
/* Send the first character. */ /* Send the first character. */
if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) ) if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
{ {
HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar; HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
} }
pcNextChar++; pcNextChar++;
} }
UARTIntEnable(UART0_BASE, UART_INT_TX); UARTIntEnable( UART0_BASE, UART_INT_TX );
/* Queue a message for the print task to display on the LCD. */ /* Queue a message for the print task to display on the LCD. */
xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY ); xQueueSend( xPrintQueue, &pcInterruptMessage, portMAX_DELAY );
/* Make sure we don't process bounces. */ /* Make sure we don't process bounces. */
vTaskDelay( mainDEBOUNCE_DELAY ); vTaskDelay( mainDEBOUNCE_DELAY );
xSemaphoreTake( xButtonSemaphore, mainNO_DELAY ); xSemaphoreTake( xButtonSemaphore, mainNO_DELAY );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vUART_ISR(void) void vUART_ISR( void )
{ {
unsigned long ulStatus; unsigned long ulStatus;
/* What caused the interrupt. */ /* What caused the interrupt. */
ulStatus = UARTIntStatus( UART0_BASE, pdTRUE ); ulStatus = UARTIntStatus( UART0_BASE, pdTRUE );
/* Clear the interrupt. */ /* Clear the interrupt. */
UARTIntClear( UART0_BASE, ulStatus ); UARTIntClear( UART0_BASE, ulStatus );
/* Was a Tx interrupt pending? */ /* Was a Tx interrupt pending? */
if( ulStatus & UART_INT_TX ) if( ulStatus & UART_INT_TX )
{ {
/* Send the next character in the string. We are not using the FIFO. */ /* Send the next character in the string. We are not using the FIFO. */
if( *pcNextChar != NULL ) if( *pcNextChar != NULL )
{ {
if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) ) if( !( HWREG( UART0_BASE + UART_O_FR ) & UART_FR_TXFF ) )
{ {
HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar; HWREG( UART0_BASE + UART_O_DR ) = *pcNextChar;
} }
pcNextChar++;
} pcNextChar++;
} }
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vGPIO_ISR( void ) void vGPIO_ISR( void )
{ {
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt. */ /* Clear the interrupt. */
GPIOPinIntClear( GPIO_PORTC_BASE, mainPUSH_BUTTON ); GPIOPinIntClear( GPIO_PORTC_BASE, mainPUSH_BUTTON );
/* Wake the button handler task. */ /* Wake the button handler task. */
xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void vPrintTask( void *pvParameters ) static void vPrintTask( void * pvParameters )
{ {
char *pcMessage; char * pcMessage;
unsigned portBASE_TYPE uxLine = 0, uxRow = 0; unsigned portBASE_TYPE uxLine = 0, uxRow = 0;
for( ;; ) for( ; ; )
{ {
/* Wait for a message to arrive. */ /* Wait for a message to arrive. */
xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY ); xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY );
/* Write the message to the LCD. */ /* Write the message to the LCD. */
uxRow++; uxRow++;
uxLine++; uxLine++;
OSRAMClear(); OSRAMClear();
OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01); OSRAMStringDraw( pcMessage, uxLine & 0x3f, uxRow & 0x01 );
} }
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -70,32 +70,32 @@
#include "partest.h" #include "partest.h"
/* Priorities at which the tasks are created. */ /* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
/* The number of the LED that is toggled. */ /* The number of the LED that is toggled. */
#define mainLED_TO_TOGGLE ( 0 ) #define mainLED_TO_TOGGLE ( 0 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -117,85 +117,86 @@ static QueueHandle_t xQueue = NULL;
void main_blinky( void ) void main_blinky( void )
{ {
/* Create the queue. */ /* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */ ( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
NULL ); /* The task handle is not required, so NULL is passed. */ NULL ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
vParTestToggleLED( mainLED_TO_TOGGLE ); vParTestToggleLED( mainLED_TO_TOGGLE );
ulReceivedValue = 0U; ulReceivedValue = 0U;
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -91,28 +91,28 @@
#include "QueueSet.h" #include "QueueSet.h"
/* The period after which the check timer will expire provided no errors have /* The period after which the check timer will expire provided no errors have
been reported by any of the standard demo tasks. ms are converted to the * been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire if an error has been /* The period at which the check timer will expire if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/* A block time of zero simply means "don't block". */ /* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The base toggle rate used by the flash timers. Each toggle rate is a /* The base toggle rate used by the flash timers. Each toggle rate is a
multiple of this. */ * multiple of this. */
#define mainFLASH_TIMER_BASE_RATE ( 200UL / portTICK_PERIOD_MS ) #define mainFLASH_TIMER_BASE_RATE ( 200UL / portTICK_PERIOD_MS )
/* The LED toggle by the check timer. */ /* The LED toggle by the check timer. */
#define mainCHECK_LED ( 4 ) #define mainCHECK_LED ( 4 )
/* The LED toggled each time the task implemented by the prvSemaphoreTakeTask() /* The LED toggled each time the task implemented by the prvSemaphoreTakeTask()
function takes the semaphore that is given by the tick hook function. */ * function takes the semaphore that is given by the tick hook function. */
#define mainSEMAPHORE_LED ( 3 ) #define mainSEMAPHORE_LED ( 3 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -120,8 +120,8 @@ function takes the semaphore that is given by the tick hook function. */
* Register check tasks, as described at the top of this file. The nature of * Register check tasks, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly. * these files necessitates that they are written in an assembly.
*/ */
extern void vRegTest1Task( void *pvParameters ); extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void *pvParameters ); extern void vRegTest2Task( void * pvParameters );
/* /*
* The hardware only has a single LED. Simply toggle it. * The hardware only has a single LED. Simply toggle it.
@ -143,7 +143,7 @@ static void prvFlashTimerCallback( TimerHandle_t xTimer );
* The task that toggles an LED each time the semaphore 'given' by the tick * The task that toggles an LED each time the semaphore 'given' by the tick
* hook function (which is defined in main.c) is 'taken' in the task. * hook function (which is defined in main.c) is 'taken' in the task.
*/ */
static void prvSemaphoreTakeTask( void *pvParameters ); static void prvSemaphoreTakeTask( void * pvParameters );
/* /*
* Called by main() to create the comprehensive test/demo application if * Called by main() to create the comprehensive test/demo application if
@ -154,210 +154,214 @@ void main_full( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep * register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If * incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */ * a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/* The semaphore that is given by the tick hook function (defined in main.c) /* The semaphore that is given by the tick hook function (defined in main.c)
and taken by the task implemented by the prvSemaphoreTakeTask() function. The * and taken by the task implemented by the prvSemaphoreTakeTask() function. The
task toggles LED mainSEMAPHORE_LED each time the semaphore is taken. */ * task toggles LED mainSEMAPHORE_LED each time the semaphore is taken. */
SemaphoreHandle_t xLEDSemaphore = NULL; SemaphoreHandle_t xLEDSemaphore = NULL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xTimer = NULL; TimerHandle_t xTimer = NULL;
unsigned long ulTimer; unsigned long ulTimer;
const unsigned long ulTimersToCreate = 3L; const unsigned long ulTimersToCreate = 3L;
/* The register test tasks are asm functions that don't use a stack. The /* The register test tasks are asm functions that don't use a stack. The
stack allocated just has to be large enough to hold the task context, and * stack allocated just has to be large enough to hold the task context, and
for the additional required for the stack overflow checking to work (if * for the additional required for the stack overflow checking to work (if
configured). */ * configured). */
const size_t xRegTestStackSize = 25U; const size_t xRegTestStackSize = 25U;
/* Create the standard demo tasks */ /* Create the standard demo tasks */
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartCountingSemaphoreTasks(); vStartCountingSemaphoreTasks();
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
vStartQueueOverwriteTask( tskIDLE_PRIORITY ); vStartQueueOverwriteTask( tskIDLE_PRIORITY );
vStartQueueSetTasks(); vStartQueueSetTasks();
/* Create that is given from the tick hook function, and the task that /* Create that is given from the tick hook function, and the task that
toggles an LED each time the semaphore is given. */ * toggles an LED each time the semaphore is given. */
vSemaphoreCreateBinary( xLEDSemaphore ); vSemaphoreCreateBinary( xLEDSemaphore );
xTaskCreate( prvSemaphoreTakeTask, /* Function that implements the task. */ xTaskCreate( prvSemaphoreTakeTask, /* Function that implements the task. */
"Sem", /* Text name of the task. */ "Sem", /* Text name of the task. */
configMINIMAL_STACK_SIZE, /* Stack allocated to the task (in words). */ configMINIMAL_STACK_SIZE, /* Stack allocated to the task (in words). */
NULL, /* The task parameter is not used. */ NULL, /* The task parameter is not used. */
configMAX_PRIORITIES - 2, /* The priority of the task. */ configMAX_PRIORITIES - 2, /* The priority of the task. */
NULL ); /* Don't receive a handle back, it is not needed. */ NULL ); /* Don't receive a handle back, it is not needed. */
/* Create the register test tasks as described at the top of this file. /* Create the register test tasks as described at the top of this file.
These are naked functions that don't use any stack. A stack still has * These are naked functions that don't use any stack. A stack still has
to be allocated to hold the task context. */ * to be allocated to hold the task context. */
xTaskCreate( vRegTest1Task, /* Function that implements the task. */ xTaskCreate( vRegTest1Task, /* Function that implements the task. */
"Reg1", /* Text name of the task. */ "Reg1", /* Text name of the task. */
xRegTestStackSize, /* Stack allocated to the task. */ xRegTestStackSize, /* Stack allocated to the task. */
NULL, /* The task parameter is not used. */ NULL, /* The task parameter is not used. */
tskIDLE_PRIORITY, /* The priority to assign to the task. */ tskIDLE_PRIORITY, /* The priority to assign to the task. */
NULL ); /* Don't receive a handle back, it is not needed. */ NULL ); /* Don't receive a handle back, it is not needed. */
xTaskCreate( vRegTest2Task, /* Function that implements the task. */ xTaskCreate( vRegTest2Task, /* Function that implements the task. */
"Reg2", /* Text name of the task. */ "Reg2", /* Text name of the task. */
xRegTestStackSize, /* Stack allocated to the task. */ xRegTestStackSize, /* Stack allocated to the task. */
NULL, /* The task parameter is not used. */ NULL, /* The task parameter is not used. */
tskIDLE_PRIORITY, /* The priority to assign to the task. */ tskIDLE_PRIORITY, /* The priority to assign to the task. */
NULL ); /* Don't receive a handle back, it is not needed. */ NULL ); /* Don't receive a handle back, it is not needed. */
/* Create the three flash timers. */ /* Create the three flash timers. */
for( ulTimer = 0UL; ulTimer < ulTimersToCreate; ulTimer++ ) for( ulTimer = 0UL; ulTimer < ulTimersToCreate; ulTimer++ )
{ {
xTimer = xTimerCreate( "FlashTimer", /* A text name, purely to help debugging. */ xTimer = xTimerCreate( "FlashTimer", /* A text name, purely to help debugging. */
( mainFLASH_TIMER_BASE_RATE * ( ulTimer + 1UL ) ), /* The timer period, in this case 3000ms (3s). */ ( mainFLASH_TIMER_BASE_RATE * ( ulTimer + 1UL ) ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) ulTimer, /* The ID is used to hold the number of the LED that will be flashed. */ ( void * ) ulTimer, /* The ID is used to hold the number of the LED that will be flashed. */
prvFlashTimerCallback /* The callback function that inspects the status of all the other tasks. */ prvFlashTimerCallback /* The callback function that inspects the status of all the other tasks. */
); );
if( xTimer != NULL ) if( xTimer != NULL )
{ {
xTimerStart( xTimer, mainDONT_BLOCK ); xTimerStart( xTimer, mainDONT_BLOCK );
} }
} }
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */ prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
); );
/* If the software timer was created successfully, start it. It won't /* If the software timer was created successfully, start it. It won't
actually start running until the scheduler starts. A block time of * actually start running until the scheduler starts. A block time of
zero is used in this call, although any value could be used as the block * zero is used in this call, although any value could be used as the block
time will be ignored because the scheduler has not started yet. */ * time will be ignored because the scheduler has not started yet. */
if( xTimer != NULL ) if( xTimer != NULL )
{ {
xTimerStart( xTimer, mainDONT_BLOCK ); xTimerStart( xTimer, mainDONT_BLOCK );
} }
/* Start the kernel. From here on, only tasks and interrupts will run. */ /* Start the kernel. From here on, only tasks and interrupts will run. */
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then there * line will never be reached. If the following line does execute, then there
was insufficient FreeRTOS heap memory available for the idle and/or timer * was insufficient FreeRTOS heap memory available for the idle and/or timer
tasks to be created. See the memory management section on the FreeRTOS web * tasks to be created. See the memory management section on the FreeRTOS web
site, or the FreeRTOS tutorial books for more details. */ * site, or the FreeRTOS tutorial books for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* See the description at the top of this file. */ /* See the description at the top of this file. */
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangedTimerPeriodAlready = pdFALSE; static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Check all the demo and test tasks to ensure that they are all still /* Check all the demo and test tasks to ensure that they are all still
running, and that none have detected an error. */ * running, and that none have detected an error. */
if( xAreDynamicPriorityTasksStillRunning() != pdPASS ) if( xAreDynamicPriorityTasksStillRunning() != pdPASS )
{ {
ulErrorFound |= ( 0x01UL << 0UL ); ulErrorFound |= ( 0x01UL << 0UL );
} }
if( xAreBlockTimeTestTasksStillRunning() != pdPASS ) if( xAreBlockTimeTestTasksStillRunning() != pdPASS )
{ {
ulErrorFound |= ( 0x01UL << 1UL ); ulErrorFound |= ( 0x01UL << 1UL );
} }
if( xAreCountingSemaphoreTasksStillRunning() != pdPASS ) if( xAreCountingSemaphoreTasksStillRunning() != pdPASS )
{ {
ulErrorFound |= ( 0x01UL << 2UL ); ulErrorFound |= ( 0x01UL << 2UL );
} }
if( xAreRecursiveMutexTasksStillRunning() != pdPASS ) if( xAreRecursiveMutexTasksStillRunning() != pdPASS )
{ {
ulErrorFound |= ( 0x01UL << 3UL ); ulErrorFound |= ( 0x01UL << 3UL );
} }
/* Check that the register test 1 task is still running. */ /* Check that the register test 1 task is still running. */
if( ulLastRegTest1Value == ulRegTest1LoopCounter ) if( ulLastRegTest1Value == ulRegTest1LoopCounter )
{ {
ulErrorFound |= ( 0x01UL << 4UL ); ulErrorFound |= ( 0x01UL << 4UL );
} }
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ ulLastRegTest1Value = ulRegTest1LoopCounter;
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
{
ulErrorFound |= ( 0x01UL << 5UL );
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
if( xAreQueueSetTasksStillRunning() != pdPASS ) /* Check that the register test 2 task is still running. */
{ if( ulLastRegTest2Value == ulRegTest2LoopCounter )
ulErrorFound |= ( 0x01UL << 6UL ); {
} ulErrorFound |= ( 0x01UL << 5UL );
}
if( xIsQueueOverwriteTaskStillRunning() != pdPASS ) ulLastRegTest2Value = ulRegTest2LoopCounter;
{
ulErrorFound |= ( 0x01UL << 7UL );
}
/* Toggle the check LED to give an indication of the system status. If if( xAreQueueSetTasksStillRunning() != pdPASS )
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then {
everything is ok. A faster toggle indicates an error. */ ulErrorFound |= ( 0x01UL << 6UL );
vParTestToggleLED( mainCHECK_LED ); }
/* Have any errors been latched in ulErrorFound? If so, shorten the if( xIsQueueOverwriteTaskStillRunning() != pdPASS )
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 ulErrorFound |= ( 0x01UL << 7UL );
toggles. */ }
if( ulErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == pdFALSE )
{
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time. /* Toggle the check LED to give an indication of the system status. If
Functions called from inside of a timer callback function must * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
*never* attempt to block. */ * everything is ok. A faster toggle indicates an error. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); 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. */
if( ulErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == 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. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSemaphoreTakeTask( void *pvParameters ) static void prvSemaphoreTakeTask( void * pvParameters )
{ {
configASSERT( xLEDSemaphore ); configASSERT( xLEDSemaphore );
for( ;; ) for( ; ; )
{ {
/* Wait to obtain the semaphore - which is given by the tick hook /* Wait to obtain the semaphore - which is given by the tick hook
function every 50ms. */ * function every 50ms. */
xSemaphoreTake( xLEDSemaphore, portMAX_DELAY ); xSemaphoreTake( xLEDSemaphore, portMAX_DELAY );
vParTestToggleLED( mainSEMAPHORE_LED ); vParTestToggleLED( mainSEMAPHORE_LED );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvFlashTimerCallback( TimerHandle_t xTimer ) static void prvFlashTimerCallback( TimerHandle_t xTimer )
{ {
unsigned long ulLED; unsigned long ulLED;
/* This callback function is assigned to three separate software timers. /* This callback function is assigned to three separate software timers.
Each timer toggles a different LED. Obtain the number of the LED that * Each timer toggles a different LED. Obtain the number of the LED that
this timer is toggling. */ * this timer is toggling. */
ulLED = ( unsigned long ) pvTimerGetTimerID( xTimer ); ulLED = ( unsigned long ) pvTimerGetTimerID( xTimer );
/* Toggle the LED. */ /* Toggle the LED. */
vParTestToggleLED( ulLED ); vParTestToggleLED( ulLED );
} }

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -73,29 +73,29 @@
#include "stm320518_eval.h" #include "stm320518_eval.h"
/* Priorities at which the tasks are created. */ /* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -117,85 +117,86 @@ static QueueHandle_t xQueue = NULL;
void main_blinky( void ) void main_blinky( void )
{ {
/* Create the queue. */ /* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */ ( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
NULL ); /* The task handle is not required, so NULL is passed. */ NULL ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
vParTestToggleLED( LED1 ); vParTestToggleLED( LED1 );
ulReceivedValue = 0U; ulReceivedValue = 0U;
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -87,32 +87,32 @@
#include "stm320518_eval.h" #include "stm320518_eval.h"
/* The period after which the check timer will expire provided no errors have /* The period after which the check timer will expire provided no errors have
been reported by any of the standard demo tasks. ms are converted to the * been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire if an error has been /* The period at which the check timer will expire if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/* A block time of zero simply means "don't block". */ /* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The base toggle rate used by the flash timers. Each toggle rate is a /* The base toggle rate used by the flash timers. Each toggle rate is a
multiple of this. */ * multiple of this. */
#define mainFLASH_TIMER_BASE_RATE ( 200UL / portTICK_PERIOD_MS ) #define mainFLASH_TIMER_BASE_RATE ( 200UL / portTICK_PERIOD_MS )
/* The LED toggle by the check timer. */ /* The LED toggle by the check timer. */
#define mainCHECK_LED ( 3 ) #define mainCHECK_LED ( 3 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Register check tasks, as described at the top of this file. The nature of * Register check tasks, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly. * these files necessitates that they are written in an assembly.
*/ */
extern void vRegTest1Task( void *pvParameters ); extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void *pvParameters ); extern void vRegTest2Task( void * pvParameters );
/* /*
* The hardware only has a single LED. Simply toggle it. * The hardware only has a single LED. Simply toggle it.
@ -139,170 +139,174 @@ void main_full( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep * register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If * incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */ * a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xTimer = NULL; TimerHandle_t xTimer = NULL;
unsigned long ulTimer; unsigned long ulTimer;
const unsigned long ulTimersToCreate = 3L; const unsigned long ulTimersToCreate = 3L;
/* The register test tasks are asm functions that don't use a stack. The /* The register test tasks are asm functions that don't use a stack. The
stack allocated just has to be large enough to hold the task context, and * stack allocated just has to be large enough to hold the task context, and
for the additional required for the stack overflow checking to work (if * for the additional required for the stack overflow checking to work (if
configured). */ * configured). */
const size_t xRegTestStackSize = 25U; const size_t xRegTestStackSize = 25U;
/* Create the standard demo tasks */ /* Create the standard demo tasks */
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartCountingSemaphoreTasks(); vStartCountingSemaphoreTasks();
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
/* Create the register test tasks as described at the top of this file. /* Create the register test tasks as described at the top of this file.
These are naked functions that don't use any stack. A stack still has * These are naked functions that don't use any stack. A stack still has
to be allocated to hold the task context. */ * to be allocated to hold the task context. */
xTaskCreate( vRegTest1Task, /* Function that implements the task. */ xTaskCreate( vRegTest1Task, /* Function that implements the task. */
"Reg1", /* Text name of the task. */ "Reg1", /* Text name of the task. */
xRegTestStackSize, /* Stack allocated to the task. */ xRegTestStackSize, /* Stack allocated to the task. */
NULL, /* The task parameter is not used. */ NULL, /* The task parameter is not used. */
tskIDLE_PRIORITY, /* The priority to assign to the task. */ tskIDLE_PRIORITY, /* The priority to assign to the task. */
NULL ); /* Don't receive a handle back, it is not needed. */ NULL ); /* Don't receive a handle back, it is not needed. */
xTaskCreate( vRegTest2Task, /* Function that implements the task. */ xTaskCreate( vRegTest2Task, /* Function that implements the task. */
"Reg2", /* Text name of the task. */ "Reg2", /* Text name of the task. */
xRegTestStackSize, /* Stack allocated to the task. */ xRegTestStackSize, /* Stack allocated to the task. */
NULL, /* The task parameter is not used. */ NULL, /* The task parameter is not used. */
tskIDLE_PRIORITY, /* The priority to assign to the task. */ tskIDLE_PRIORITY, /* The priority to assign to the task. */
NULL ); /* Don't receive a handle back, it is not needed. */ NULL ); /* Don't receive a handle back, it is not needed. */
/* Create the three flash timers. */ /* Create the three flash timers. */
for( ulTimer = 0UL; ulTimer < ulTimersToCreate; ulTimer++ ) for( ulTimer = 0UL; ulTimer < ulTimersToCreate; ulTimer++ )
{ {
xTimer = xTimerCreate( "FlashTimer", /* A text name, purely to help debugging. */ xTimer = xTimerCreate( "FlashTimer", /* A text name, purely to help debugging. */
( mainFLASH_TIMER_BASE_RATE * ( ulTimer + 1UL ) ), /* The timer period, in this case 3000ms (3s). */ ( mainFLASH_TIMER_BASE_RATE * ( ulTimer + 1UL ) ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) ulTimer, /* The ID is used to hold the number of the LED that will be flashed. */ ( void * ) ulTimer, /* The ID is used to hold the number of the LED that will be flashed. */
prvFlashTimerCallback /* The callback function that inspects the status of all the other tasks. */ prvFlashTimerCallback /* The callback function that inspects the status of all the other tasks. */
); );
if( xTimer != NULL ) if( xTimer != NULL )
{ {
xTimerStart( xTimer, mainDONT_BLOCK ); xTimerStart( xTimer, mainDONT_BLOCK );
} }
} }
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */ prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
); );
/* If the software timer was created successfully, start it. It won't /* If the software timer was created successfully, start it. It won't
actually start running until the scheduler starts. A block time of * actually start running until the scheduler starts. A block time of
zero is used in this call, although any value could be used as the block * zero is used in this call, although any value could be used as the block
time will be ignored because the scheduler has not started yet. */ * time will be ignored because the scheduler has not started yet. */
if( xTimer != NULL ) if( xTimer != NULL )
{ {
xTimerStart( xTimer, mainDONT_BLOCK ); xTimerStart( xTimer, mainDONT_BLOCK );
} }
/* Start the kernel. From here on, only tasks and interrupts will run. */ /* Start the kernel. From here on, only tasks and interrupts will run. */
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then there * line will never be reached. If the following line does execute, then there
was insufficient FreeRTOS heap memory available for the idle and/or timer * was insufficient FreeRTOS heap memory available for the idle and/or timer
tasks to be created. See the memory management section on the FreeRTOS web * tasks to be created. See the memory management section on the FreeRTOS web
site, or the FreeRTOS tutorial books for more details. */ * site, or the FreeRTOS tutorial books for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* See the description at the top of this file. */ /* See the description at the top of this file. */
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangedTimerPeriodAlready = pdFALSE; static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Check all the demo and test tasks to ensure that they are all still /* Check all the demo and test tasks to ensure that they are all still
running, and that none have detected an error. */ * running, and that none have detected an error. */
if( xAreDynamicPriorityTasksStillRunning() != pdPASS ) if( xAreDynamicPriorityTasksStillRunning() != pdPASS )
{ {
ulErrorFound |= ( 0x01UL << 0UL ); ulErrorFound |= ( 0x01UL << 0UL );
} }
if( xAreBlockTimeTestTasksStillRunning() != pdPASS ) if( xAreBlockTimeTestTasksStillRunning() != pdPASS )
{ {
ulErrorFound |= ( 0x01UL << 1UL ); ulErrorFound |= ( 0x01UL << 1UL );
} }
if( xAreCountingSemaphoreTasksStillRunning() != pdPASS ) if( xAreCountingSemaphoreTasksStillRunning() != pdPASS )
{ {
ulErrorFound |= ( 0x01UL << 2UL ); ulErrorFound |= ( 0x01UL << 2UL );
} }
if( xAreRecursiveMutexTasksStillRunning() != pdPASS ) if( xAreRecursiveMutexTasksStillRunning() != pdPASS )
{ {
ulErrorFound |= ( 0x01UL << 3UL ); ulErrorFound |= ( 0x01UL << 3UL );
} }
/* Check that the register test 1 task is still running. */ /* Check that the register test 1 task is still running. */
if( ulLastRegTest1Value == ulRegTest1LoopCounter ) if( ulLastRegTest1Value == ulRegTest1LoopCounter )
{ {
ulErrorFound |= ( 0x01UL << 4UL ); ulErrorFound |= ( 0x01UL << 4UL );
} }
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ ulLastRegTest1Value = ulRegTest1LoopCounter;
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
{
ulErrorFound |= ( 0x01UL << 5UL );
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If /* Check that the register test 2 task is still running. */
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then if( ulLastRegTest2Value == ulRegTest2LoopCounter )
everything is ok. A faster toggle indicates an error. */ {
vParTestToggleLED( mainCHECK_LED ); ulErrorFound |= ( 0x01UL << 5UL );
}
/* Have any errors been latched in ulErrorFound? If so, shorten the ulLastRegTest2Value = ulRegTest2LoopCounter;
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 )
{
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time. /* Toggle the check LED to give an indication of the system status. If
Functions called from inside of a timer callback function must * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
*never* attempt to block. */ * everything is ok. A faster toggle indicates an error. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); 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. */
if( ulErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == 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. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvFlashTimerCallback( TimerHandle_t xTimer ) static void prvFlashTimerCallback( TimerHandle_t xTimer )
{ {
unsigned long ulLED; unsigned long ulLED;
/* This callback function is assigned to three separate software timers. /* This callback function is assigned to three separate software timers.
Each timer toggles a different LED. Obtain the number of the LED that * Each timer toggles a different LED. Obtain the number of the LED that
this timer is toggling. */ * this timer is toggling. */
ulLED = ( unsigned long ) pvTimerGetTimerID( xTimer ); ulLED = ( unsigned long ) pvTimerGetTimerID( xTimer );
/* Toggle the LED. */ /* Toggle the LED. */
vParTestToggleLED( ulLED ); vParTestToggleLED( ulLED );
} }

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -70,30 +70,30 @@
#include "semphr.h" #include "semphr.h"
/* Priorities at which the tasks are created. */ /* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -110,85 +110,86 @@ static QueueHandle_t xQueue = NULL;
void main_blinky( void ) void main_blinky( void )
{ {
/* Create the queue. */ /* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */ ( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
NULL ); /* The task handle is not required, so NULL is passed. */ NULL ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
configTOGGLE_LED(); configTOGGLE_LED();
ulReceivedValue = 0U; ulReceivedValue = 0U;
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -70,30 +70,30 @@
#include "semphr.h" #include "semphr.h"
/* Priorities at which the tasks are created. */ /* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -110,85 +110,86 @@ static QueueHandle_t xQueue = NULL;
void main_blinky( void ) void main_blinky( void )
{ {
/* Create the queue. */ /* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */ ( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
NULL ); /* The task handle is not required, so NULL is passed. */ NULL ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
configTOGGLE_LED(); configTOGGLE_LED();
ulReceivedValue = 0U; ulReceivedValue = 0U;
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -85,24 +85,24 @@
#include "QueueOverwrite.h" #include "QueueOverwrite.h"
/* Priorities for the demo application tasks. */ /* Priorities for the demo application tasks. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* A block time of zero simply means "don't block". */ /* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The period after which the check timer will expire, in ms, provided no errors /* The period after which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the * have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been /* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -116,144 +116,147 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer );
* of the FPU registers, as described at the top of this file. The nature of * of the FPU registers, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly file. * these files necessitates that they are written in an assembly file.
*/ */
extern void vRegTest1Task( void *pvParameters ); extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void *pvParameters ); extern void vRegTest2Task( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep * register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If * incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */ * a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xCheckTimer = NULL; TimerHandle_t xCheckTimer = NULL;
/* Start all the other standard demo/test tasks. The have not particular /* Start all the other standard demo/test tasks. The have not particular
functionality, but do demonstrate how to use the FreeRTOS API and test the * functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */ * kernel port. */
vStartQueueSetTasks(); vStartQueueSetTasks();
vStartQueueOverwriteTask( tskIDLE_PRIORITY ); vStartQueueOverwriteTask( tskIDLE_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartGenericQueueTasks( tskIDLE_PRIORITY ); vStartGenericQueueTasks( tskIDLE_PRIORITY );
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
vStartMathTasks( mainFLOP_TASK_PRIORITY ); vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* Create the register check tasks, as described at the top of this /* Create the register check tasks, as described at the top of this
file */ * file */
xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */ prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
); );
if( xCheckTimer != NULL ) if( xCheckTimer != NULL )
{ {
xTimerStart( xCheckTimer, mainDONT_BLOCK ); xTimerStart( xCheckTimer, mainDONT_BLOCK );
} }
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangedTimerPeriodAlready = pdFALSE; static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xAreQueueSetTasksStillRunning() != pdTRUE ) if( xAreQueueSetTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xIsQueueOverwriteTaskStillRunning() != pdTRUE ) if( xIsQueueOverwriteTaskStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
/* Check that the register test 1 task is still running. */ /* Check that the register test 1 task is still running. */
if( ulLastRegTest1Value == ulRegTest1LoopCounter ) if( ulLastRegTest1Value == ulRegTest1LoopCounter )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ ulLastRegTest1Value = ulRegTest1LoopCounter;
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
{
ulErrorFound = pdTRUE;
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If /* Check that the register test 2 task is still running. */
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then if( ulLastRegTest2Value == ulRegTest2LoopCounter )
everything is ok. A faster toggle indicates an error. */ {
configTOGGLE_LED(); ulErrorFound = pdTRUE;
}
/* Have any errors been latch in ulErrorFound? If so, shorten the ulLastRegTest2Value = ulRegTest2LoopCounter;
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 )
{
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time. /* Toggle the check LED to give an indication of the system status. If
Functions called from inside of a timer callback function must * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
*never* attempt to block. */ * everything is ok. A faster toggle indicates an error. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); 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. */
if( ulErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == 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. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -35,9 +35,9 @@
* This file implements the code that is not demo specific, including the * This file implements the code that is not demo specific, including the
* hardware setup and FreeRTOS hook functions. * hardware setup and FreeRTOS hook functions.
* *
* *
* Additional code: * Additional code:
* *
* This demo does not contain a non-kernel interrupt service routine that * This demo does not contain a non-kernel interrupt service routine that
* can be used as an example for application writers to use as a reference. * can be used as an example for application writers to use as a reference.
* Therefore, the framework of a dummy (not installed) handler is provided * Therefore, the framework of a dummy (not installed) handler is provided
@ -55,8 +55,8 @@
#include "task.h" #include "task.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -65,9 +65,9 @@ or 0 to run the more comprehensive test and demo application. */
*/ */
static void prvSetupHardware( void ); static void prvSetupHardware( void );
/* /*
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
*/ */
extern void main_blinky( void ); extern void main_blinky( void );
extern void main_full( void ); extern void main_full( void );
@ -76,111 +76,118 @@ extern void main_full( void );
int main( void ) int main( void )
{ {
/* Prepare the hardware to run this demo. */ /* Prepare the hardware to run this demo. */
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
{ {
main_blinky(); main_blinky();
} }
#else #else
{ {
main_full(); main_full();
} }
#endif #endif
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
configCONFIGURE_LED(); configCONFIGURE_LED();
/* Ensure all priority bits are assigned as preemption priority bits. */ /* Ensure all priority bits are assigned as preemption priority bits. */
NVIC_SetPriorityGrouping( 0 ); NVIC_SetPriorityGrouping( 0 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* This function will be called by each tick interrupt if /* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be * configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so * added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API * code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */ * functions can be used (those that end in FromISR()). */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef JUST_AN_EXAMPLE_ISR #ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void) void Dummy_IRQHandler( void )
{ {
long lHigherPriorityTaskWoken = pdFALSE; long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */ /* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit(); Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a /* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note * task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. */ * lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* If there was a task that was blocked on the semaphore, and giving the /* If there was a task that was blocked on the semaphore, and giving the
semaphore caused the task to unblock, and the unblocked task has a priority * semaphore caused the task to unblock, and the unblocked task has a priority
higher than the current Running state task (the task that this interrupt * higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE * interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the * internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to * portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority, * ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */ * task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
} }
#endif /* JUST_AN_EXAMPLE_ISR */ #endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -70,30 +70,30 @@
#include "semphr.h" #include "semphr.h"
/* Priorities at which the tasks are created. */ /* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -110,85 +110,86 @@ static QueueHandle_t xQueue = NULL;
void main_blinky( void ) void main_blinky( void )
{ {
/* Create the queue. */ /* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */ ( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
NULL ); /* The task handle is not required, so NULL is passed. */ NULL ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
configTOGGLE_LED(); configTOGGLE_LED();
ulReceivedValue = 0U; ulReceivedValue = 0U;
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -83,24 +83,24 @@
#include "recmutex.h" #include "recmutex.h"
/* Priorities for the demo application tasks. */ /* Priorities for the demo application tasks. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* A block time of zero simply means "don't block". */ /* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The period after which the check timer will expire, in ms, provided no errors /* The period after which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the * have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been /* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -114,139 +114,142 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer );
* of the FPU registers, as described at the top of this file. The nature of * of the FPU registers, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly file. * these files necessitates that they are written in an assembly file.
*/ */
extern void vRegTest1Task( void *pvParameters ); extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void *pvParameters ); extern void vRegTest2Task( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep * register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If * incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */ * a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xCheckTimer = NULL; TimerHandle_t xCheckTimer = NULL;
/* Start all the other standard demo/test tasks. The have not particular /* Start all the other standard demo/test tasks. The have not particular
functionality, but do demonstrate how to use the FreeRTOS API and test the * functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */ * kernel port. */
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartCountingSemaphoreTasks(); vStartCountingSemaphoreTasks();
vStartGenericQueueTasks( tskIDLE_PRIORITY ); vStartGenericQueueTasks( tskIDLE_PRIORITY );
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartMathTasks( mainFLOP_TASK_PRIORITY ); vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* Create the register check tasks, as described at the top of this /* Create the register check tasks, as described at the top of this
file */ * file */
xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */ prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
); );
if( xCheckTimer != NULL ) if( xCheckTimer != NULL )
{ {
xTimerStart( xCheckTimer, mainDONT_BLOCK ); xTimerStart( xCheckTimer, mainDONT_BLOCK );
} }
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangedTimerPeriodAlready = pdFALSE; static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
/* Check that the register test 1 task is still running. */ /* Check that the register test 1 task is still running. */
if( ulLastRegTest1Value == ulRegTest1LoopCounter ) if( ulLastRegTest1Value == ulRegTest1LoopCounter )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ ulLastRegTest1Value = ulRegTest1LoopCounter;
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
{
ulErrorFound = pdTRUE;
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If /* Check that the register test 2 task is still running. */
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then if( ulLastRegTest2Value == ulRegTest2LoopCounter )
everything is ok. A faster toggle indicates an error. */ {
configTOGGLE_LED(); ulErrorFound = pdTRUE;
}
/* Have any errors been latch in ulErrorFound? If so, shorten the ulLastRegTest2Value = ulRegTest2LoopCounter;
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 )
{
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time. /* Toggle the check LED to give an indication of the system status. If
Functions called from inside of a timer callback function must * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
*never* attempt to block. */ * everything is ok. A faster toggle indicates an error. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); 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. */
if( ulErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == 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. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -47,10 +47,10 @@
* that is found on the FreeRTOS.org web site. * that is found on the FreeRTOS.org web site.
*/ */
/* /*
* The following #error directive is to remind users that a batch file must be * The following #error directive is to remind users that a batch file must be
* executed prior to this project being built. The batch file *cannot* be * executed prior to this project being built. The batch file *cannot* be
* executed from within the IDE! Once it has been executed, re-open or refresh * executed from within the IDE! Once it has been executed, re-open or refresh
* the Eclipse project and remove the #error line below. * the Eclipse project and remove the #error line below.
*/ */
#error Ensure CreateProjectDirectoryStructure.bat has been executed before building. See comment immediately above. #error Ensure CreateProjectDirectoryStructure.bat has been executed before building. See comment immediately above.
@ -68,8 +68,8 @@
#include "QueueOverwrite.h" #include "QueueOverwrite.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -89,128 +89,131 @@ extern void main_full( void );
int main( void ) int main( void )
{ {
/* Prepare the hardware to run this demo. */ /* Prepare the hardware to run this demo. */
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
{ {
main_blinky(); main_blinky();
} }
#else #else
{ {
main_full(); main_full();
} }
#endif #endif
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
configCONFIGURE_LED(); configCONFIGURE_LED();
/* Ensure all priority bits are assigned as preemption priority bits. */ /* Ensure all priority bits are assigned as preemption priority bits. */
NVIC_SetPriorityGrouping( 0 ); NVIC_SetPriorityGrouping( 0 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; )
{ for( ; ; )
__asm volatile( "NOP" ); {
}; __asm volatile ( "NOP" );
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; )
{ for( ; ; )
__asm volatile( "NOP" ); {
} __asm volatile ( "NOP" );
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* This function will be called by each tick interrupt if /* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be * configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so * added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API * code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */ * functions can be used (those that end in FromISR()). */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
/* Write to a queue that is in use as part of the queue set demo to /* Write to a queue that is in use as part of the queue set demo to
demonstrate using queue sets from an ISR. */ * demonstrate using queue sets from an ISR. */
vQueueSetAccessQueueSetFromISR(); vQueueSetAccessQueueSetFromISR();
/* Test the ISR safe queue overwrite functions. */ /* Test the ISR safe queue overwrite functions. */
vQueueOverwritePeriodicISRDemo(); vQueueOverwritePeriodicISRDemo();
} }
#endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */ #endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef JUST_AN_EXAMPLE_ISR #ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void) void Dummy_IRQHandler( void )
{ {
long lHigherPriorityTaskWoken = pdFALSE; long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */ /* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit(); Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a /* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note * task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. */ * lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* If there was a task that was blocked on the semaphore, and giving the /* If there was a task that was blocked on the semaphore, and giving the
semaphore caused the task to unblock, and the unblocked task has a priority * semaphore caused the task to unblock, and the unblocked task has a priority
higher than the current Running state task (the task that this interrupt * higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE * interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the * internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to * portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority, * ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */ * task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
} }
#endif /* JUST_AN_EXAMPLE_ISR */ #endif /* JUST_AN_EXAMPLE_ISR */

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -70,30 +70,30 @@
#include "semphr.h" #include "semphr.h"
/* Priorities at which the tasks are created. */ /* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -110,88 +110,87 @@ static QueueHandle_t xQueue = NULL;
void main_blinky( void ) void main_blinky( void )
{ {
/* Create the queue. */ /* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */ ( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
NULL ); /* The task handle is not required, so NULL is passed. */ NULL ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ) for( ; ; )
{ {
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
configTOGGLE_LED(); configTOGGLE_LED();
ulReceivedValue = 0U; ulReceivedValue = 0U;
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -85,24 +85,24 @@
#include "QueueOverwrite.h" #include "QueueOverwrite.h"
/* Priorities for the demo application tasks. */ /* Priorities for the demo application tasks. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* A block time of zero simply means "don't block". */ /* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The period after which the check timer will expire, in ms, provided no errors /* The period after which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the * have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been /* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -116,499 +116,498 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer );
* of the FPU registers, as described at the top of this file. The nature of * of the FPU registers, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly file. * these files necessitates that they are written in an assembly file.
*/ */
static void vRegTest1Task( void *pvParameters ); static void vRegTest1Task( void * pvParameters );
static void vRegTest2Task( void *pvParameters ); static void vRegTest2Task( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the /* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep * register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If * incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */ * a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xCheckTimer = NULL; TimerHandle_t xCheckTimer = NULL;
/* Start all the other standard demo/test tasks. The have not particular /* Start all the other standard demo/test tasks. The have not particular
functionality, but do demonstrate how to use the FreeRTOS API and test the * functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */ * kernel port. */
vStartQueueSetTasks(); vStartQueueSetTasks();
vStartQueueOverwriteTask( tskIDLE_PRIORITY ); vStartQueueOverwriteTask( tskIDLE_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartGenericQueueTasks( tskIDLE_PRIORITY ); vStartGenericQueueTasks( tskIDLE_PRIORITY );
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
vStartMathTasks( mainFLOP_TASK_PRIORITY ); vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* Create the register check tasks, as described at the top of this /* Create the register check tasks, as described at the top of this
file */ * file */
xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */ prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
); );
if( xCheckTimer != NULL ) if( xCheckTimer != NULL )
{ {
xTimerStart( xCheckTimer, mainDONT_BLOCK ); xTimerStart( xCheckTimer, mainDONT_BLOCK );
} }
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ) for( ; ; )
{ {
__asm volatile( "NOP" ); __asm volatile ( "NOP" );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangedTimerPeriodAlready = pdFALSE; static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */ * that they are all still running, and that none have detected an error. */
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xAreQueueSetTasksStillRunning() != pdTRUE ) if( xAreQueueSetTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xIsQueueOverwriteTaskStillRunning() != pdTRUE ) if( xIsQueueOverwriteTaskStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
/* Check that the register test 1 task is still running. */ /* Check that the register test 1 task is still running. */
if( ulLastRegTest1Value == ulRegTest1LoopCounter ) if( ulLastRegTest1Value == ulRegTest1LoopCounter )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */ ulLastRegTest1Value = ulRegTest1LoopCounter;
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
{
ulErrorFound = pdTRUE;
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Toggle the check LED to give an indication of the system status. If /* Check that the register test 2 task is still running. */
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then if( ulLastRegTest2Value == ulRegTest2LoopCounter )
everything is ok. A faster toggle indicates an error. */ {
configTOGGLE_LED(); ulErrorFound = pdTRUE;
}
/* Have any errors been latch in ulErrorFound? If so, shorten the ulLastRegTest2Value = ulRegTest2LoopCounter;
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 )
{
lChangedTimerPeriodAlready = pdTRUE;
/* This call to xTimerChangePeriod() uses a zero block time. /* Toggle the check LED to give an indication of the system status. If
Functions called from inside of a timer callback function must * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
*never* attempt to block. */ * everything is ok. A faster toggle indicates an error. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); 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. */
if( ulErrorFound != pdFALSE )
{
if( lChangedTimerPeriodAlready == 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. */
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
}
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* This is a naked function. */ /* This is a naked function. */
static void vRegTest1Task( void *pvParameters ) static void vRegTest1Task( void * pvParameters )
{ {
__asm volatile __asm volatile
( (
" \n" /* Fill the core registers with known values. */ " \n"/* Fill the core registers with known values. */
" mov r0, #100 \n" " mov r0, #100 \n"
" mov r1, #101 \n" " mov r1, #101 \n"
" mov r2, #102 \n" " mov r2, #102 \n"
" mov r3, #103 \n" " mov r3, #103 \n"
" mov r4, #104 \n" " mov r4, #104 \n"
" mov r5, #105 \n" " mov r5, #105 \n"
" mov r6, #106 \n" " mov r6, #106 \n"
" mov r7, #107 \n" " mov r7, #107 \n"
" mov r8, #108 \n" " mov r8, #108 \n"
" mov r9, #109 \n" " mov r9, #109 \n"
" mov r10, #110 \n" " mov r10, #110 \n"
" mov r11, #111 \n" " mov r11, #111 \n"
" mov r12, #112 \n" " mov r12, #112 \n"
" \n" " \n"
" vmov d0, r0, r1 \n" /* Fill the VFP registers with known values. */ " vmov d0, r0, r1 \n"/* Fill the VFP registers with known values. */
" vmov d1, r2, r3 \n" " vmov d1, r2, r3 \n"
" vmov d2, r4, r5 \n" " vmov d2, r4, r5 \n"
" vmov d3, r6, r7 \n" " vmov d3, r6, r7 \n"
" vmov d4, r8, r9 \n" " vmov d4, r8, r9 \n"
" vmov d5, r10, r11 \n" " vmov d5, r10, r11 \n"
" vmov d6, r0, r1 \n" " vmov d6, r0, r1 \n"
" vmov d7, r2, r3 \n" " vmov d7, r2, r3 \n"
" vmov d8, r4, r5 \n" " vmov d8, r4, r5 \n"
" vmov d9, r6, r7 \n" " vmov d9, r6, r7 \n"
" vmov d10, r8, r9 \n" " vmov d10, r8, r9 \n"
" vmov d11, r10, r11 \n" " vmov d11, r10, r11 \n"
" vmov d12, r0, r1 \n" " vmov d12, r0, r1 \n"
" vmov d13, r2, r3 \n" " vmov d13, r2, r3 \n"
" vmov d14, r4, r5 \n" " vmov d14, r4, r5 \n"
" vmov d15, r6, r7 \n" " vmov d15, r6, r7 \n"
" \n" " \n"
"reg1_loop: \n" /* Check all the VFP registers still contain the values set above." */ "reg1_loop: \n"/* Check all the VFP registers still contain the values set above." */
" push { r0-r1 } \n" /* First save registers that are clobbered by the test. */ " push { r0-r1 } \n"/* First save registers that are clobbered by the test. */
" \n" " \n"
" vmov r0, r1, d0 \n" " vmov r0, r1, d0 \n"
" cmp r0, #100 \n" " cmp r0, #100 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #101 \n" " cmp r1, #101 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d1 \n" " vmov r0, r1, d1 \n"
" cmp r0, #102 \n" " cmp r0, #102 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #103 \n" " cmp r1, #103 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d2 \n" " vmov r0, r1, d2 \n"
" cmp r0, #104 \n" " cmp r0, #104 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #105 \n" " cmp r1, #105 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d3 \n" " vmov r0, r1, d3 \n"
" cmp r0, #106 \n" " cmp r0, #106 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #107 \n" " cmp r1, #107 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d4 \n" " vmov r0, r1, d4 \n"
" cmp r0, #108 \n" " cmp r0, #108 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #109 \n" " cmp r1, #109 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d5 \n" " vmov r0, r1, d5 \n"
" cmp r0, #110 \n" " cmp r0, #110 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #111 \n" " cmp r1, #111 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d6 \n" " vmov r0, r1, d6 \n"
" cmp r0, #100 \n" " cmp r0, #100 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #101 \n" " cmp r1, #101 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d7 \n" " vmov r0, r1, d7 \n"
" cmp r0, #102 \n" " cmp r0, #102 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #103 \n" " cmp r1, #103 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d8 \n" " vmov r0, r1, d8 \n"
" cmp r0, #104 \n" " cmp r0, #104 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #105 \n" " cmp r1, #105 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d9 \n" " vmov r0, r1, d9 \n"
" cmp r0, #106 \n" " cmp r0, #106 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #107 \n" " cmp r1, #107 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d10 \n" " vmov r0, r1, d10 \n"
" cmp r0, #108 \n" " cmp r0, #108 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #109 \n" " cmp r1, #109 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d11 \n" " vmov r0, r1, d11 \n"
" cmp r0, #110 \n" " cmp r0, #110 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #111 \n" " cmp r1, #111 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d12 \n" " vmov r0, r1, d12 \n"
" cmp r0, #100 \n" " cmp r0, #100 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #101 \n" " cmp r1, #101 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d13 \n" " vmov r0, r1, d13 \n"
" cmp r0, #102 \n" " cmp r0, #102 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #103 \n" " cmp r1, #103 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d14 \n" " vmov r0, r1, d14 \n"
" cmp r0, #104 \n" " cmp r0, #104 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #105 \n" " cmp r1, #105 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" vmov r0, r1, d15 \n" " vmov r0, r1, d15 \n"
" cmp r0, #106 \n" " cmp r0, #106 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" cmp r1, #107 \n" " cmp r1, #107 \n"
" bne reg1_error_loopf \n" " bne reg1_error_loopf \n"
" \n" " \n"
" pop {r0-r1} \n" /* Restore the registers that were clobbered by the test. */ " pop {r0-r1} \n"/* Restore the registers that were clobbered by the test. */
" \n" " \n"
" b reg1_loopf_pass \n" /* VFP register test passed. Jump to the core register test. */ " b reg1_loopf_pass \n"/* VFP register test passed. Jump to the core register test. */
" \n" " \n"
"reg1_error_loopf: \n" "reg1_error_loopf: \n"
" b reg1_error_loopf \n" /* If this line is hit then a VFP register value was found to be\n incorrect. */ " b reg1_error_loopf \n"/* If this line is hit then a VFP register value was found to be\n incorrect. */
" \n" " \n"
"reg1_loopf_pass: \n" "reg1_loopf_pass: \n"
" \n" " \n"
" cmp r0, #100 \n" " cmp r0, #100 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" cmp r1, #101 \n" " cmp r1, #101 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" cmp r2, #102 \n" " cmp r2, #102 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" cmp r3, #103 \n" " cmp r3, #103 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" cmp r4, #104 \n" " cmp r4, #104 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" cmp r5, #105 \n" " cmp r5, #105 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" cmp r6, #106 \n" " cmp r6, #106 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" cmp r7, #107 \n" " cmp r7, #107 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" cmp r8, #108 \n" " cmp r8, #108 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" cmp r9, #109 \n" " cmp r9, #109 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" cmp r10, #110 \n" " cmp r10, #110 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" cmp r11, #111 \n" " cmp r11, #111 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" cmp r12, #112 \n" " cmp r12, #112 \n"
" bne reg1_error_loop \n" " bne reg1_error_loop \n"
" \n" " \n"
" push { r0-r1 } \n" /* Everything passed, increment the loop counter. */ " push { r0-r1 } \n"/* Everything passed, increment the loop counter. */
" ldr r0, =ulRegTest1LoopCounter \n" " ldr r0, =ulRegTest1LoopCounter \n"
" ldr r1, [r0] \n" " ldr r1, [r0] \n"
" adds r1, r1, #1 \n" " adds r1, r1, #1 \n"
" str r1, [r0] \n" " str r1, [r0] \n"
" pop { r0-r1 } \n" " pop { r0-r1 } \n"
" \n" " \n"
" b reg1_loop \n" /* Start again. */ " b reg1_loop \n"/* Start again. */
" \n" " \n"
"reg1_error_loop: \n" /* If this line is hit then there was an error in a core register value. */ "reg1_error_loop: \n"/* If this line is hit then there was an error in a core register value. */
" b reg1_error_loop \n" /* The loop ensures the loop counter stops incrementing. */ " b reg1_error_loop \n"/* The loop ensures the loop counter stops incrementing. */
" nop " " nop "
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* This is a naked function. */ /* This is a naked function. */
static void vRegTest2Task( void *pvParameters ) static void vRegTest2Task( void * pvParameters )
{ {
__asm volatile __asm volatile
( (
" mov r0, #-1 \n" /* Set all the core registers to known values. */ " mov r0, #-1 \n"/* Set all the core registers to known values. */
" mov r1, #1 \n" " mov r1, #1 \n"
" mov r2, #2 \n" " mov r2, #2 \n"
" mov r3, #3 \n" " mov r3, #3 \n"
" mov r4, #4 \n" " mov r4, #4 \n"
" mov r5, #5 \n" " mov r5, #5 \n"
" mov r6, #6 \n" " mov r6, #6 \n"
" mov r7, #7 \n" " mov r7, #7 \n"
" mov r8, #8 \n" " mov r8, #8 \n"
" mov r9, #9 \n" " mov r9, #9 \n"
" mov r10, #10 \n" " mov r10, #10 \n"
" mov r11, #11 \n" " mov r11, #11 \n"
" mov r12, #12 \n" " mov r12, #12 \n"
" \n" " \n"
" vmov d0, r0, r1 \n" /* Set all the VFP to known values. */ " vmov d0, r0, r1 \n"/* Set all the VFP to known values. */
" vmov d1, r2, r3 \n" " vmov d1, r2, r3 \n"
" vmov d2, r4, r5 \n" " vmov d2, r4, r5 \n"
" vmov d3, r6, r7 \n" " vmov d3, r6, r7 \n"
" vmov d4, r8, r9 \n" " vmov d4, r8, r9 \n"
" vmov d5, r10, r11 \n" " vmov d5, r10, r11 \n"
" vmov d6, r0, r1 \n" " vmov d6, r0, r1 \n"
" vmov d7, r2, r3 \n" " vmov d7, r2, r3 \n"
" vmov d8, r4, r5 \n" " vmov d8, r4, r5 \n"
" vmov d9, r6, r7 \n" " vmov d9, r6, r7 \n"
" vmov d10, r8, r9 \n" " vmov d10, r8, r9 \n"
" vmov d11, r10, r11 \n" " vmov d11, r10, r11 \n"
" vmov d12, r0, r1 \n" " vmov d12, r0, r1 \n"
" vmov d13, r2, r3 \n" " vmov d13, r2, r3 \n"
" vmov d14, r4, r5 \n" " vmov d14, r4, r5 \n"
" vmov d15, r6, r7 \n" " vmov d15, r6, r7 \n"
" \n" " \n"
"reg2_loop: \n" "reg2_loop: \n"
" \n" " \n"
" push { r0-r1 } \n" /* Check all the VFP registers still contain the values set above. */ " push { r0-r1 } \n"/* Check all the VFP registers still contain the values set above. */
" vmov r0, r1, d0 \n" /*First save registers that are clobbered by the test. */ " vmov r0, r1, d0 \n"/*First save registers that are clobbered by the test. */
" cmp r0, #-1 \n" " cmp r0, #-1 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #1 \n" " cmp r1, #1 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d1 \n" " vmov r0, r1, d1 \n"
" cmp r0, #2 \n" " cmp r0, #2 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #3 \n" " cmp r1, #3 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d2 \n" " vmov r0, r1, d2 \n"
" cmp r0, #4 \n" " cmp r0, #4 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #5 \n" " cmp r1, #5 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d3 \n" " vmov r0, r1, d3 \n"
" cmp r0, #6 \n" " cmp r0, #6 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #7 \n" " cmp r1, #7 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d4 \n" " vmov r0, r1, d4 \n"
" cmp r0, #8 \n" " cmp r0, #8 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #9 \n" " cmp r1, #9 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d5 \n" " vmov r0, r1, d5 \n"
" cmp r0, #10 \n" " cmp r0, #10 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #11 \n" " cmp r1, #11 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d6 \n" " vmov r0, r1, d6 \n"
" cmp r0, #-1 \n" " cmp r0, #-1 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #1 \n" " cmp r1, #1 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d7 \n" " vmov r0, r1, d7 \n"
" cmp r0, #2 \n" " cmp r0, #2 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #3 \n" " cmp r1, #3 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d8 \n" " vmov r0, r1, d8 \n"
" cmp r0, #4 \n" " cmp r0, #4 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #5 \n" " cmp r1, #5 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d9 \n" " vmov r0, r1, d9 \n"
" cmp r0, #6 \n" " cmp r0, #6 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #7 \n" " cmp r1, #7 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d10 \n" " vmov r0, r1, d10 \n"
" cmp r0, #8 \n" " cmp r0, #8 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #9 \n" " cmp r1, #9 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d11 \n" " vmov r0, r1, d11 \n"
" cmp r0, #10 \n" " cmp r0, #10 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #11 \n" " cmp r1, #11 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d12 \n" " vmov r0, r1, d12 \n"
" cmp r0, #-1 \n" " cmp r0, #-1 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #1 \n" " cmp r1, #1 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d13 \n" " vmov r0, r1, d13 \n"
" cmp r0, #2 \n" " cmp r0, #2 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #3 \n" " cmp r1, #3 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d14 \n" " vmov r0, r1, d14 \n"
" cmp r0, #4 \n" " cmp r0, #4 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #5 \n" " cmp r1, #5 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" vmov r0, r1, d15 \n" " vmov r0, r1, d15 \n"
" cmp r0, #6 \n" " cmp r0, #6 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" cmp r1, #7 \n" " cmp r1, #7 \n"
" bne reg2_error_loopf \n" " bne reg2_error_loopf \n"
" \n" " \n"
" pop {r0-r1} \n" /* Restore the registers that were clobbered by the test. */ " pop {r0-r1} \n"/* Restore the registers that were clobbered by the test. */
" \n" " \n"
" b reg2_loopf_pass \n" /* VFP register test passed. Jump to the core register test. */ " b reg2_loopf_pass \n"/* VFP register test passed. Jump to the core register test. */
" \n" " \n"
"reg2_error_loopf: \n" "reg2_error_loopf: \n"
" b reg2_error_loopf \n" /* If this line is hit then a VFP register value was found to be incorrect. */ " b reg2_error_loopf \n"/* If this line is hit then a VFP register value was found to be incorrect. */
" \n" " \n"
"reg2_loopf_pass: \n" "reg2_loopf_pass: \n"
" \n" " \n"
" cmp r0, #-1 \n" " cmp r0, #-1 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" cmp r1, #1 \n" " cmp r1, #1 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" cmp r2, #2 \n" " cmp r2, #2 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" cmp r3, #3 \n" " cmp r3, #3 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" cmp r4, #4 \n" " cmp r4, #4 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" cmp r5, #5 \n" " cmp r5, #5 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" cmp r6, #6 \n" " cmp r6, #6 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" cmp r7, #7 \n" " cmp r7, #7 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" cmp r8, #8 \n" " cmp r8, #8 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" cmp r9, #9 \n" " cmp r9, #9 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" cmp r10, #10 \n" " cmp r10, #10 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" cmp r11, #11 \n" " cmp r11, #11 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" cmp r12, #12 \n" " cmp r12, #12 \n"
" bne reg2_error_loop \n" " bne reg2_error_loop \n"
" \n" " \n"
" push { r0-r1 } \n" /* Increment the loop counter to indicate this test is still functioning correctly. */ " push { r0-r1 } \n"/* Increment the loop counter to indicate this test is still functioning correctly. */
" ldr r0, =ulRegTest2LoopCounter \n" " ldr r0, =ulRegTest2LoopCounter \n"
" ldr r1, [r0] \n" " ldr r1, [r0] \n"
" adds r1, r1, #1 \n" " adds r1, r1, #1 \n"
" str r1, [r0] \n" " str r1, [r0] \n"
" \n" " \n"
" movs r0, #0x01 \n" /* Yield to increase test coverage. */ " movs r0, #0x01 \n"/* Yield to increase test coverage. */
" ldr r1, =0xe000ed04 \n" /*NVIC_INT_CTRL */ " ldr r1, =0xe000ed04 \n"/*NVIC_INT_CTRL */
" lsl r0, r0, #28 \n" /* Shift to PendSV bit */ " lsl r0, r0, #28 \n"/* Shift to PendSV bit */
" str r0, [r1] \n" " str r0, [r1] \n"
" dsb \n" " dsb \n"
" pop { r0-r1 } \n" " pop { r0-r1 } \n"
" \n" " \n"
" b reg2_loop \n" /* Start again. */ " b reg2_loop \n"/* Start again. */
" \n" " \n"
"reg2_error_loop: \n" /* If this line is hit then there was an error in a core register value. */ "reg2_error_loop: \n"/* If this line is hit then there was an error in a core register value. */
" b reg2_error_loop \n" /* This loop ensures the loop counter variable stops incrementing. */ " b reg2_error_loop \n"/* This loop ensures the loop counter variable stops incrementing. */
" nop \n" " nop \n"
); );
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -57,8 +57,8 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* NOTE: If an IAR build results in an undefined "reference to __write" linker /* NOTE: If an IAR build results in an undefined "reference to __write" linker
error then set the printf formatter project option to "tiny" and the scanf * error then set the printf formatter project option to "tiny" and the scanf
formatter project option to "small". */ * formatter project option to "small". */
/* /*
* Set up the hardware ready to run this demo. * Set up the hardware ready to run this demo.
@ -76,99 +76,107 @@ extern void main_full( void );
int main( void ) int main( void )
{ {
/* See http://www.FreeRTOS.org/TI_MSP432_Free_RTOS_Demo.html for instructions. */ /* See http://www.FreeRTOS.org/TI_MSP432_Free_RTOS_Demo.html for instructions. */
/* Prepare the hardware to run this demo. */ /* Prepare the hardware to run this demo. */
prvSetupHardware(); prvSetupHardware();
/* The configCREATE_SIMPLE_TICKLESS_DEMO setting is described at the top /* The configCREATE_SIMPLE_TICKLESS_DEMO setting is described at the top
of this file. */ * of this file. */
#if( configCREATE_SIMPLE_TICKLESS_DEMO == 1 ) #if ( configCREATE_SIMPLE_TICKLESS_DEMO == 1 )
{ {
main_blinky(); main_blinky();
} }
#else #else
{ {
main_full(); main_full();
} }
#endif #endif
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
extern void FPU_enableModule( void ); extern void FPU_enableModule( void );
/* The clocks are not configured here, but inside main_full() and /* The clocks are not configured here, but inside main_full() and
main_blinky() as the full demo uses a fast clock and the blinky demo uses * main_blinky() as the full demo uses a fast clock and the blinky demo uses
a slow clock. */ * a slow clock. */
/* Stop the watchdog timer. */ /* Stop the watchdog timer. */
MAP_WDT_A_holdTimer(); MAP_WDT_A_holdTimer();
/* Ensure the FPU is enabled. */ /* Ensure the FPU is enabled. */
FPU_enableModule(); FPU_enableModule();
/* Selecting P1.2 and P1.3 in UART mode and P1.0 as output (LED) */ /* Selecting P1.2 and P1.3 in UART mode and P1.0 as output (LED) */
MAP_GPIO_setAsPeripheralModuleFunctionInputPin( GPIO_PORT_P1, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION ); MAP_GPIO_setAsPeripheralModuleFunctionInputPin( GPIO_PORT_P1, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION );
MAP_GPIO_setOutputLowOnPin( GPIO_PORT_P1, GPIO_PIN0 ); MAP_GPIO_setOutputLowOnPin( GPIO_PORT_P1, GPIO_PIN0 );
MAP_GPIO_setAsOutputPin( GPIO_PORT_P1, GPIO_PIN0 ); MAP_GPIO_setAsOutputPin( GPIO_PORT_P1, GPIO_PIN0 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* vApplicationMallocFailedHook() will only be called if /* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails. * function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue, * pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the * timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the * demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in * heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used * FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not * to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */ * provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts * task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time * to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the * specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also * vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling * important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up * function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */ * memory allocated by the kernel to any task that has since been deleted. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void *malloc( size_t xSize ) void * malloc( size_t xSize )
{ {
/* There should not be a heap defined, so trap any attempts to call /* There should not be a heap defined, so trap any attempts to call
malloc. */ * malloc. */
Interrupt_disableMaster(); Interrupt_disableMaster();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -57,8 +57,8 @@
#include "board.h" #include "board.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -72,49 +72,50 @@ static void prvSetupHardware( void );
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
*/ */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
extern void main_blinky( void ); extern void main_blinky( void );
#else #else
extern void main_full( void ); extern void main_full( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
{ {
/* Configure the hardware ready to run the demo. */ /* Configure the hardware ready to run the demo. */
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
#else #else
{ {
main_full(); main_full();
} }
#endif #endif
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Disable watchdog. */ /* Disable watchdog. */
WDT_Disable( WDT ); WDT_Disable( WDT );
WDT_Disable( ( Wdt * ) RSWDT ); WDT_Disable( ( Wdt * ) RSWDT );
SCB_EnableICache(); SCB_EnableICache();
SCB_EnableDCache(); SCB_EnableDCache();
LED_Configure( 0 ); LED_Configure( 0 );
LED_Configure( 1 ); LED_Configure( 1 );
@ -123,70 +124,71 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
( void ) xFreeHeapSpace; ( void ) xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo(); vQueueOverwritePeriodicISRDemo();
/* Call the periodic event group from ISR demo. */ /* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing(); vPeriodicEventGroupsProcessing();
/* Call the code that uses a mutex from an ISR. */ /* Call the code that uses a mutex from an ISR. */
vInterruptSemaphorePeriodicTest(); vInterruptSemaphorePeriodicTest();
/* Call the code that 'gives' a task notification from an ISR. */ /* Call the code that 'gives' a task notification from an ISR. */
xNotifyTaskFromISR(); xNotifyTaskFromISR();
} }
#endif #endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -194,5 +196,5 @@ void vApplicationTickHook( void )
int __write( int x ); int __write( int x );
int __write( int x ) int __write( int x )
{ {
return x; return x;
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -57,8 +57,8 @@
#include "board.h" #include "board.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -72,49 +72,50 @@ static void prvSetupHardware( void );
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
*/ */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
extern void main_blinky( void ); extern void main_blinky( void );
#else #else
extern void main_full( void ); extern void main_full( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
{ {
/* Configure the hardware ready to run the demo. */ /* Configure the hardware ready to run the demo. */
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
#else #else
{ {
main_full(); main_full();
} }
#endif #endif
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* Disable watchdog. */ /* Disable watchdog. */
WDT_Disable( WDT0 ); WDT_Disable( WDT0 );
WDT_Disable( WDT1 ); WDT_Disable( WDT1 );
SCB_EnableICache(); SCB_EnableICache();
SCB_EnableDCache(); SCB_EnableDCache();
LED_Configure( 0 ); LED_Configure( 0 );
LED_Configure( 1 ); LED_Configure( 1 );
@ -123,70 +124,71 @@ static void prvSetupHardware( void )
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
( void ) xFreeHeapSpace; ( void ) xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo(); vQueueOverwritePeriodicISRDemo();
/* Call the periodic event group from ISR demo. */ /* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing(); vPeriodicEventGroupsProcessing();
/* Call the code that uses a mutex from an ISR. */ /* Call the code that uses a mutex from an ISR. */
vInterruptSemaphorePeriodicTest(); vInterruptSemaphorePeriodicTest();
/* Call the code that 'gives' a task notification from an ISR. */ /* Call the code that 'gives' a task notification from an ISR. */
xNotifyTaskFromISR(); xNotifyTaskFromISR();
} }
#endif #endif /* if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -194,5 +196,5 @@ void vApplicationTickHook( void )
int __write( int x ); int __write( int x );
int __write( int x ) int __write( int x )
{ {
return x; return x;
} }

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -42,7 +42,7 @@
#include "semphr.h" #include "semphr.h"
/* Standard demo includes - these are needed here as the tick hook function is /* Standard demo includes - these are needed here as the tick hook function is
defined in this file. */ * defined in this file. */
#include "TimerDemo.h" #include "TimerDemo.h"
#include "QueueOverwrite.h" #include "QueueOverwrite.h"
#include "EventGroupsDemo.h" #include "EventGroupsDemo.h"
@ -51,8 +51,8 @@ defined in this file. */
#include "TaskNotify.h" #include "TaskNotify.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */ * or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 #define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -70,212 +70,212 @@ static void prvSystemClockConfig( void );
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
*/ */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
extern void main_blinky( void ); extern void main_blinky( void );
#else #else
extern void main_full( void ); extern void main_full( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ #endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented /* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */ * within this file. */
void vApplicationMallocFailedHook( void ); void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void ); void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
void vApplicationTickHook( void ); void vApplicationTickHook( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
{ {
/* Configure the hardware ready to run the demo. */ /* Configure the hardware ready to run the demo. */
prvSetupHardware(); prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */ * of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{ {
main_blinky(); main_blinky();
} }
#else #else
{ {
main_full(); main_full();
} }
#endif #endif
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitTypeDef GPIO_InitStruct;
/* Configure Flash prefetch and Instruction cache through ART accelerator. */ /* Configure Flash prefetch and Instruction cache through ART accelerator. */
#if( ART_ACCLERATOR_ENABLE != 0 ) #if ( ART_ACCLERATOR_ENABLE != 0 )
{ {
__HAL_FLASH_ART_ENABLE(); __HAL_FLASH_ART_ENABLE();
} }
#endif /* ART_ACCLERATOR_ENABLE */ #endif /* ART_ACCLERATOR_ENABLE */
/* Set Interrupt Group Priority */ /* Set Interrupt Group Priority */
HAL_NVIC_SetPriorityGrouping( NVIC_PRIORITYGROUP_4 ); HAL_NVIC_SetPriorityGrouping( NVIC_PRIORITYGROUP_4 );
/* Init the low level hardware. */ /* Init the low level hardware. */
HAL_MspInit(); HAL_MspInit();
/* Configure the System clock to have a frequency of 200 MHz */ /* Configure the System clock to have a frequency of 200 MHz */
prvSystemClockConfig(); prvSystemClockConfig();
/* Enable GPIOB Clock (to be able to program the configuration /* Enable GPIOB Clock (to be able to program the configuration
registers) and configure for LED output. */ * registers) and configure for LED output. */
__GPIOG_CLK_ENABLE(); __GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init( GPIOF, &GPIO_InitStruct ); HAL_GPIO_Init( GPIOF, &GPIO_InitStruct );
/* MCO2 : Pin PC9 */ /* MCO2 : Pin PC9 */
HAL_RCC_MCOConfig( RCC_MCO2, RCC_MCO2SOURCE_SYSCLK, RCC_MCODIV_1 ); HAL_RCC_MCOConfig( RCC_MCO2, RCC_MCO2SOURCE_SYSCLK, RCC_MCODIV_1 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSystemClockConfig( void ) static void prvSystemClockConfig( void )
{ {
/* The system Clock is configured as follow : /* The system Clock is configured as follow :
System Clock source = PLL (HSE) * System Clock source = PLL (HSE)
SYSCLK(Hz) = 200000000 * SYSCLK(Hz) = 200000000
HCLK(Hz) = 200000000 * HCLK(Hz) = 200000000
AHB Prescaler = 1 * AHB Prescaler = 1
APB1 Prescaler = 4 * APB1 Prescaler = 4
APB2 Prescaler = 2 * APB2 Prescaler = 2
HSE Frequency(Hz) = 25000000 * HSE Frequency(Hz) = 25000000
PLL_M = 25 * PLL_M = 25
PLL_N = 400 * PLL_N = 400
PLL_P = 2 * PLL_P = 2
PLL_Q = 7 * PLL_Q = 7
VDD(V) = 3.3 * VDD(V) = 3.3
Main regulator output voltage = Scale1 mode * Main regulator output voltage = Scale1 mode
Flash Latency(WS) = 7 */ * Flash Latency(WS) = 7 */
RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable HSE Oscillator and activate PLL with HSE as source */ /* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_OFF; RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25; RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 400; RCC_OscInitStruct.PLL.PLLN = 400;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7; RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct); HAL_RCC_OscConfig( &RCC_OscInitStruct );
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */ * clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.ClockType = ( RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 );
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
configASSERT( HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) == HAL_OK ); configASSERT( HAL_RCC_ClockConfig( &RCC_ClkInitStruct, FLASH_LATENCY_7 ) == HAL_OK );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
/* Force an assert. */ /* Force an assert. */
configASSERT( ( volatile void * ) NULL ); configASSERT( ( volatile void * ) NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeHeapSpace; volatile size_t xFreeHeapSpace;
/* This is just a trivial example of an idle hook. It is called on each /* This is just a trivial example of an idle hook. It is called on each
cycle of the idle task. It must *NOT* attempt to block. In this case the * cycle of the idle task. It must *NOT* attempt to block. In this case the
idle task just queries the amount of FreeRTOS heap that remains. See the * idle task just queries the amount of FreeRTOS heap that remains. See the
memory management section on the http://www.FreeRTOS.org web site for memory * memory management section on the http://www.FreeRTOS.org web site for memory
management options. If there is a lot of heap memory free then the * management options. If there is a lot of heap memory free then the
configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up * configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
RAM. */ * RAM. */
xFreeHeapSpace = xPortGetFreeHeapSize(); xFreeHeapSpace = xPortGetFreeHeapSize();
/* Remove compiler warning about xFreeHeapSpace being set but never used. */ /* Remove compiler warning about xFreeHeapSpace being set but never used. */
( void ) xFreeHeapSpace; ( void ) xFreeHeapSpace;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vAssertCalled( uint32_t ulLine, const char *pcFile ) void vAssertCalled( uint32_t ulLine,
const char * pcFile )
{ {
volatile unsigned long ul = 0; volatile unsigned long ul = 0;
( void ) pcFile; ( void ) pcFile;
( void ) ulLine; ( void ) ulLine;
taskENTER_CRITICAL(); taskENTER_CRITICAL();
{ {
/* Set ul to a non-zero value using the debugger to step out of this /* Set ul to a non-zero value using the debugger to step out of this
function. */ * function. */
while( ul == 0 ) while( ul == 0 )
{ {
__NOP(); __NOP();
} }
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 )
{ {
/* The full demo includes a software timer demo/test that requires /* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */ * prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Call the periodic queue overwrite from ISR demo. */ /* Call the periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo(); vQueueOverwritePeriodicISRDemo();
/* Call the periodic event group from ISR demo. */ /* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing(); vPeriodicEventGroupsProcessing();
/* Call the code that uses a mutex from an ISR. */ /* Call the code that uses a mutex from an ISR. */
vInterruptSemaphorePeriodicTest(); vInterruptSemaphorePeriodicTest();
/* Use a queue set from an ISR. */ /* Use a queue set from an ISR. */
vQueueSetAccessQueueSetFromISR(); vQueueSetAccessQueueSetFromISR();
/* Use task notifications from an ISR. */ /* Use task notifications from an ISR. */
xNotifyTaskFromISR(); xNotifyTaskFromISR();
} }
#endif #endif /* if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -135,77 +135,77 @@
#include "dynamic.h" #include "dynamic.h"
/* The rate at which data is sent to the queue, specified in milliseconds, and /* The rate at which data is sent to the queue, specified in milliseconds, and
converted to ticks using the portTICK_PERIOD_MS constant. */ * converted to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* The LED toggled by the check timer callback function. This is an LED in the /* The LED toggled by the check timer callback function. This is an LED in the
second digit of the two digit 7 segment display. See the documentation page * second digit of the two digit 7 segment display. See the documentation page
for this demo on the FreeRTOS.org web site to see which LED this relates to. */ * for this demo on the FreeRTOS.org web site to see which LED this relates to. */
#define mainCHECK_LED ( 1UL << 3UL ) #define mainCHECK_LED ( 1UL << 3UL )
/* The LED toggle by the queue receive task. This is an LED in the second digit /* The LED toggle by the queue receive task. This is an LED in the second digit
of the two digit 7 segment display. See the documentation page for this demo on * of the two digit 7 segment display. See the documentation page for this demo on
the FreeRTOS.org web site to see which LED this relates to. */ * the FreeRTOS.org web site to see which LED this relates to. */
#define mainTASK_CONTROLLED_LED 0x07UL #define mainTASK_CONTROLLED_LED 0x07UL
/* The LED turned on by the button interrupt, and turned off by the LED timer. /* The LED turned on by the button interrupt, and turned off by the LED timer.
This is an LED in the second digit of the two digit 7 segment display. See the * This is an LED in the second digit of the two digit 7 segment display. See the
documentation page for this demo on the FreeRTOS.org web site to see which LED * documentation page for this demo on the FreeRTOS.org web site to see which LED
this relates to. */ * this relates to. */
#define mainTIMER_CONTROLLED_LED 0x05UL #define mainTIMER_CONTROLLED_LED 0x05UL
/* The LED used by the comtest tasks. See the comtest.c file for more /* The LED used by the comtest tasks. See the comtest.c file for more
information. The LEDs used by the comtest task are in the second digit of the * information. The LEDs used by the comtest task are in the second digit of the
two digit 7 segment display. See the documentation page for this demo on the * two digit 7 segment display. See the documentation page for this demo on the
FreeRTOS.org web site to see which LEDs this relates to. */ * FreeRTOS.org web site to see which LEDs this relates to. */
#define mainCOM_TEST_LED 0x03UL #define mainCOM_TEST_LED 0x03UL
/* Constant used by the standard timer test functions. */ /* Constant used by the standard timer test functions. */
#define mainTIMER_TEST_PERIOD ( 50 ) #define mainTIMER_TEST_PERIOD ( 50 )
/* Priorities used by the various different standard demo tasks. */ /* Priorities used by the various different standard demo tasks. */
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) #define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* Priorities defined in this main-full.c file. */ /* Priorities defined in this main-full.c file. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The period at which the check timer will expire, in ms, provided no errors /* The period at which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the * have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been /* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_PERIOD_MS )
/* The period at which the digit counter timer will expire, in ms, and converted /* The period at which the digit counter timer will expire, in ms, and converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainDIGIT_COUNTER_TIMER_PERIOD_MS ( 250UL / portTICK_PERIOD_MS ) #define mainDIGIT_COUNTER_TIMER_PERIOD_MS ( 250UL / portTICK_PERIOD_MS )
/* The LED will remain on until the button has not been pushed for a full /* The LED will remain on until the button has not been pushed for a full
5000ms. */ * 5000ms. */
#define mainLED_TIMER_PERIOD_MS ( 5000UL / portTICK_PERIOD_MS ) #define mainLED_TIMER_PERIOD_MS ( 5000UL / portTICK_PERIOD_MS )
/* A zero block time. */ /* A zero block time. */
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* Baud rate used by the comtest tasks. */ /* Baud rate used by the comtest tasks. */
#define mainCOM_TEST_BAUD_RATE ( 115200UL ) #define mainCOM_TEST_BAUD_RATE ( 115200UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -218,8 +218,8 @@ static void prvSetupHardware( void );
* The application specific (not common demo) tasks as described in the comments * The application specific (not common demo) tasks as described in the comments
* at the top of this file. * at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* The LED timer callback function. This does nothing but switch an LED off. * The LED timer callback function. This does nothing but switch an LED off.
@ -240,7 +240,8 @@ static void prvDigitCounterTimerCallback( TimerHandle_t xTimer );
* This is not a 'standard' partest function, so the prototype is not in * This is not a 'standard' partest function, so the prototype is not in
* partest.h, and is instead included here. * partest.h, and is instead included here.
*/ */
void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue ); void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED,
signed portBASE_TYPE xValue );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -248,394 +249,401 @@ void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE x
static QueueHandle_t xQueue = NULL; static QueueHandle_t xQueue = NULL;
/* The LED software timer. This uses prvLEDTimerCallback() as it's callback /* The LED software timer. This uses prvLEDTimerCallback() as it's callback
function. */ * function. */
static TimerHandle_t xLEDTimer = NULL; static TimerHandle_t xLEDTimer = NULL;
/* The digit counter software timer. This displays a counting digit on one half /* The digit counter software timer. This displays a counting digit on one half
of the seven segment displays. */ * of the seven segment displays. */
static TimerHandle_t xDigitCounterTimer = NULL; static TimerHandle_t xDigitCounterTimer = NULL;
/* The check timer. This uses prvCheckTimerCallback() as its callback /* The check timer. This uses prvCheckTimerCallback() as its callback
function. */ * function. */
static TimerHandle_t xCheckTimer = NULL; static TimerHandle_t xCheckTimer = NULL;
/* If an error is detected in a standard demo task, then pcStatusMessage will /* If an error is detected in a standard demo task, then pcStatusMessage will
be set to point to a string that identifies the offending task. This is just * be set to point to a string that identifies the offending task. This is just
to make debugging easier. */ * to make debugging easier. */
static const char *pcStatusMessage = NULL; static const char * pcStatusMessage = NULL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main(void) int main( void )
{ {
/* Configure the NVIC, LED outputs and button inputs. */ /* Configure the NVIC, LED outputs and button inputs. */
prvSetupHardware(); prvSetupHardware();
/* Create the queue. */ /* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two application specific demo tasks, as described in the /* Start the two application specific demo tasks, as described in the
comments at the top of this file. */ * comments at the top of this file. */
xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Create the software timer that is responsible for turning off the LED /* Create the software timer that is responsible for turning off the LED
if the button is not pushed within 5000ms, as described at the top of * if the button is not pushed within 5000ms, as described at the top of
this file. */ * this file. */
xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */ xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */
( mainLED_TIMER_PERIOD_MS ),/* The timer period, in this case 5000ms (5s). */ ( mainLED_TIMER_PERIOD_MS ), /* The timer period, in this case 5000ms (5s). */
pdFALSE, /* This is a one-shot timer, so xAutoReload is set to pdFALSE. */ pdFALSE, /* This is a one-shot timer, so xAutoReload is set to pdFALSE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvLEDTimerCallback /* The callback function that switches the LED off. */ prvLEDTimerCallback /* The callback function that switches the LED off. */
); );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */ prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
); );
/* Create the software timer that performs the 'digit counting' /* Create the software timer that performs the 'digit counting'
functionality, as described at the top of this file. */ * functionality, as described at the top of this file. */
xDigitCounterTimer = xTimerCreate( "DigitCounter", /* A text name, purely to help debugging. */ xDigitCounterTimer = xTimerCreate( "DigitCounter", /* A text name, purely to help debugging. */
( mainDIGIT_COUNTER_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainDIGIT_COUNTER_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvDigitCounterTimerCallback /* The callback function that inspects the status of all the other tasks. */ prvDigitCounterTimerCallback /* The callback function that inspects the status of all the other tasks. */
); );
/* Create a lot of 'standard demo' tasks. Over 40 tasks are created in /* Create a lot of 'standard demo' tasks. Over 40 tasks are created in
this demo. For a much simpler demo, select the 'blinky' build * this demo. For a much simpler demo, select the 'blinky' build
configuration. */ * configuration. */
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY ); vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY ); vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );
vStartQueuePeekTasks(); vStartQueuePeekTasks();
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
vStartTimerDemoTask( mainTIMER_TEST_PERIOD ); vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartCountingSemaphoreTasks(); vStartCountingSemaphoreTasks();
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
/* The suicide tasks must be created last, as they need to know how many /* The suicide tasks must be created last, as they need to know how many
tasks were running prior to their creation in order to ascertain whether * tasks were running prior to their creation in order to ascertain whether
or not the correct/expected number of tasks are running at any given * or not the correct/expected number of tasks are running at any given
time. */ * time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
/* Check the standard demo tasks are running without error. Latch the /* Check the standard demo tasks are running without error. Latch the
latest reported error in the pcStatusMessage character pointer. */ * latest reported error in the pcStatusMessage character pointer. */
if( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: GenQueue"; pcStatusMessage = "Error: GenQueue";
} }
if( xAreQueuePeekTasksStillRunning() != pdTRUE ) if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: QueuePeek\r\n"; pcStatusMessage = "Error: QueuePeek\r\n";
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: BlockQueue\r\n"; pcStatusMessage = "Error: BlockQueue\r\n";
} }
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: BlockTime\r\n"; pcStatusMessage = "Error: BlockTime\r\n";
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: SemTest\r\n"; pcStatusMessage = "Error: SemTest\r\n";
} }
if( xIsCreateTaskStillRunning() != pdTRUE ) if( xIsCreateTaskStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: Death\r\n"; pcStatusMessage = "Error: Death\r\n";
} }
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: RecMutex\r\n"; pcStatusMessage = "Error: RecMutex\r\n";
} }
if( xAreComTestTasksStillRunning() != pdPASS ) if( xAreComTestTasksStillRunning() != pdPASS )
{ {
pcStatusMessage = "Error: ComTest\r\n"; pcStatusMessage = "Error: ComTest\r\n";
} }
if( xAreTimerDemoTasksStillRunning( ( mainCHECK_TIMER_PERIOD_MS ) ) != pdTRUE ) if( xAreTimerDemoTasksStillRunning( ( mainCHECK_TIMER_PERIOD_MS ) ) != pdTRUE )
{ {
pcStatusMessage = "Error: TimerDemo"; pcStatusMessage = "Error: TimerDemo";
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: PollQueue"; pcStatusMessage = "Error: PollQueue";
} }
if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: CountSem"; pcStatusMessage = "Error: CountSem";
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: DynamicPriority"; pcStatusMessage = "Error: DynamicPriority";
} }
/* Toggle the check LED to give an indication of the system status. If /* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. vParTestToggleLED() * everything is ok. A faster toggle indicates an error. vParTestToggleLED()
is not used to toggle this particular LED as it is on a different IP port * is not used to toggle this particular LED as it is on a different IP port
to to the LEDs controlled by ParTest.c. A critical section is not required * to to the LEDs controlled by ParTest.c. A critical section is not required
as the only other place this port is accessed is from another timer - and * as the only other place this port is accessed is from another timer - and
only one timer can be running at any one time. */ * only one timer can be running at any one time. */
if( ( FM3_GPIO->PDOR3 & mainCHECK_LED ) != 0 ) if( ( FM3_GPIO->PDOR3 & mainCHECK_LED ) != 0 )
{ {
FM3_GPIO->PDOR3 &= ~mainCHECK_LED; FM3_GPIO->PDOR3 &= ~mainCHECK_LED;
} }
else else
{ {
FM3_GPIO->PDOR3 |= mainCHECK_LED; FM3_GPIO->PDOR3 |= mainCHECK_LED;
} }
/* Have any errors been latch in pcStatusMessage? If so, shorten the /* Have any errors been latch in pcStatusMessage? If so, shorten the
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. * period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
This will result in an increase in the rate at which mainCHECK_LED * This will result in an increase in the rate at which mainCHECK_LED
toggles. */ * toggles. */
if( pcStatusMessage != NULL ) if( pcStatusMessage != NULL )
{ {
/* This call to xTimerChangePeriod() uses a zero block time. Functions /* This call to xTimerChangePeriod() uses a zero block time. Functions
called from inside of a timer callback function must *never* attempt * called from inside of a timer callback function must *never* attempt
to block. */ * to block. */
xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvLEDTimerCallback( TimerHandle_t xTimer ) static void prvLEDTimerCallback( TimerHandle_t xTimer )
{ {
/* The timer has expired - so no button pushes have occurred in the last /* The timer has expired - so no button pushes have occurred in the last
five seconds - turn the LED off. */ * five seconds - turn the LED off. */
vParTestSetLED( mainTIMER_CONTROLLED_LED, pdFALSE ); vParTestSetLED( mainTIMER_CONTROLLED_LED, pdFALSE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvDigitCounterTimerCallback( TimerHandle_t xTimer ) static void prvDigitCounterTimerCallback( TimerHandle_t xTimer )
{ {
/* Define the bit patterns that display numbers on the seven segment display. */ /* Define the bit patterns that display numbers on the seven segment display. */
static const unsigned short usNumbersPatterns[] = { 0x8004, 0xF204, 0x4804, 0x6004, 0x3204, 0x2404, 0x0404, 0xF104, 0x0004, 0x2004 }; static const unsigned short usNumbersPatterns[] = { 0x8004, 0xF204, 0x4804, 0x6004, 0x3204, 0x2404, 0x0404, 0xF104, 0x0004, 0x2004 };
static long lCounter = 0L; static long lCounter = 0L;
const long lNumberOfDigits = 10L; const long lNumberOfDigits = 10L;
unsigned short usCheckLEDState; unsigned short usCheckLEDState;
/* Unfortunately the LED uses the same port as the digit counter, so remember /* Unfortunately the LED uses the same port as the digit counter, so remember
the state of the check LED. A critical section is not required to access * the state of the check LED. A critical section is not required to access
the port as only one timer can be executing at any one time. */ * the port as only one timer can be executing at any one time. */
usCheckLEDState = ( FM3_GPIO->PDOR3 & mainCHECK_LED ); usCheckLEDState = ( FM3_GPIO->PDOR3 & mainCHECK_LED );
/* Display the next number, counting up. */ /* Display the next number, counting up. */
FM3_GPIO->PDOR3 = usNumbersPatterns[ lCounter ] | usCheckLEDState; FM3_GPIO->PDOR3 = usNumbersPatterns[ lCounter ] | usCheckLEDState;
/* Move onto the next digit. */ /* Move onto the next digit. */
lCounter++; lCounter++;
/* Ensure the counter does not go off the end of the array. */ /* Ensure the counter does not go off the end of the array. */
if( lCounter >= lNumberOfDigits ) if( lCounter >= lNumberOfDigits )
{ {
lCounter = 0L; lCounter = 0L;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The ISR executed when the user button is pushed. */ /* The ISR executed when the user button is pushed. */
void INT0_7_Handler( void ) void INT0_7_Handler( void )
{ {
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* The button was pushed, so ensure the LED is on before resetting the /* The button was pushed, so ensure the LED is on before resetting the
LED timer. The LED timer will turn the LED off if the button is not * LED timer. The LED timer will turn the LED off if the button is not
pushed within 5000ms. */ * pushed within 5000ms. */
vParTestSetLEDFromISR( mainTIMER_CONTROLLED_LED, pdTRUE ); vParTestSetLEDFromISR( mainTIMER_CONTROLLED_LED, pdTRUE );
/* This interrupt safe FreeRTOS function can be called from this interrupt /* This interrupt safe FreeRTOS function can be called from this interrupt
because the interrupt priority is below the * because the interrupt priority is below the
configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */ * configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken ); xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken );
/* Clear the interrupt before leaving. This just clears all the interrupts /* Clear the interrupt before leaving. This just clears all the interrupts
for simplicity, as only one is actually used in this simple demo anyway. */ * for simplicity, as only one is actually used in this simple demo anyway. */
FM3_EXTI->EICL = 0x0000; FM3_EXTI->EICL = 0x0000;
/* If calling xTimerResetFromISR() caused a task (in this case the timer /* If calling xTimerResetFromISR() caused a task (in this case the timer
service/daemon task) to unblock, and the unblocked task has a priority * service/daemon task) to unblock, and the unblocked task has a priority
higher than or equal to the task that was interrupted, then * higher than or equal to the task that was interrupted, then
xHigherPriorityTaskWoken will now be set to pdTRUE, and calling * xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */ * portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* The timer command queue will have been filled when the timer test tasks /* The timer command queue will have been filled when the timer test tasks
were created in main() (this is part of the test they perform). Therefore, * were created in main() (this is part of the test they perform). Therefore,
while the check and digit counter timers can be created in main(), they * while the check and digit counter timers can be created in main(), they
cannot be started from main(). Once the scheduler has started, the timer * cannot be started from main(). Once the scheduler has started, the timer
service task will drain the command queue, and now the check and digit * service task will drain the command queue, and now the check and digit
counter timers can be started successfully. */ * counter timers can be started successfully. */
xTimerStart( xCheckTimer, portMAX_DELAY ); xTimerStart( xCheckTimer, portMAX_DELAY );
xTimerStart( xDigitCounterTimer, portMAX_DELAY ); xTimerStart( xDigitCounterTimer, portMAX_DELAY );
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle an LED. 0 is used as the block time so the sending operation * toggle an LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK ); xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
vParTestToggleLED( mainTASK_CONTROLLED_LED ); vParTestToggleLED( mainTASK_CONTROLLED_LED );
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
const unsigned short usButtonInputBit = 0x01U; const unsigned short usButtonInputBit = 0x01U;
SystemInit(); SystemInit();
SystemCoreClockUpdate(); SystemCoreClockUpdate();
/* Initialise the IO used for the LEDs on the 7 segment displays. */ /* Initialise the IO used for the LEDs on the 7 segment displays. */
vParTestInitialise(); vParTestInitialise();
/* Set the switches to input (P18->P1F). */ /* Set the switches to input (P18->P1F). */
FM3_GPIO->DDR5 = 0x0000; FM3_GPIO->DDR5 = 0x0000;
FM3_GPIO->PFR5 = 0x0000; FM3_GPIO->PFR5 = 0x0000;
/* Assign the button input as GPIO. */ /* Assign the button input as GPIO. */
FM3_GPIO->PFR5 |= usButtonInputBit; FM3_GPIO->PFR5 |= usButtonInputBit;
/* Button interrupt on falling edge. */ /* Button interrupt on falling edge. */
FM3_EXTI->ELVR = 0x0003; FM3_EXTI->ELVR = 0x0003;
/* Clear all external interrupts. */ /* Clear all external interrupts. */
FM3_EXTI->EICL = 0x0000; FM3_EXTI->EICL = 0x0000;
/* Enable the button interrupt. */ /* Enable the button interrupt. */
FM3_EXTI->ENIR |= usButtonInputBit; FM3_EXTI->ENIR |= usButtonInputBit;
/* Setup the GPIO and the NVIC for the switch used in this simple demo. */ /* Setup the GPIO and the NVIC for the switch used in this simple demo. */
NVIC_SetPriority( EXINT0_7_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); NVIC_SetPriority( EXINT0_7_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
NVIC_EnableIRQ( EXINT0_7_IRQn ); NVIC_EnableIRQ( EXINT0_7_IRQn );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeStackSpace; volatile size_t xFreeStackSpace;
/* This function is called on each cycle of the idle task. In this case it /* This function is called on each cycle of the idle task. In this case it
does nothing useful, other than report the amount of FreeRTOS heap that * does nothing useful, other than report the amount of FreeRTOS heap that
remains unallocated. */ * remains unallocated. */
xFreeStackSpace = xPortGetFreeHeapSize(); xFreeStackSpace = xPortGetFreeHeapSize();
if( xFreeStackSpace > 100 ) if( xFreeStackSpace > 100 )
{ {
/* By now, the kernel has allocated everything it is going to, so /* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then * if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be * the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */ * reduced accordingly. */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* Call the periodic timer test, which tests the timer API functions that /* Call the periodic timer test, which tests the timer API functions that
can be called from an ISR. */ * can be called from an ISR. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -136,77 +136,77 @@
#include "dynamic.h" #include "dynamic.h"
/* The rate at which data is sent to the queue, specified in milliseconds, and /* The rate at which data is sent to the queue, specified in milliseconds, and
converted to ticks using the portTICK_PERIOD_MS constant. */ * converted to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* The LED toggled by the check timer callback function. This is an LED in the /* The LED toggled by the check timer callback function. This is an LED in the
second digit of the two digit 7 segment display. See the documentation page * second digit of the two digit 7 segment display. See the documentation page
for this demo on the FreeRTOS.org web site to see which LED this relates to. */ * for this demo on the FreeRTOS.org web site to see which LED this relates to. */
#define mainCHECK_LED 0x07UL #define mainCHECK_LED 0x07UL
/* The LED toggle by the queue receive task. This is an LED in the second digit /* The LED toggle by the queue receive task. This is an LED in the second digit
of the two digit 7 segment display. See the documentation page for this demo on * of the two digit 7 segment display. See the documentation page for this demo on
the FreeRTOS.org web site to see which LED this relates to. */ * the FreeRTOS.org web site to see which LED this relates to. */
#define mainTASK_CONTROLLED_LED 0x06UL #define mainTASK_CONTROLLED_LED 0x06UL
/* The LED turned on by the button interrupt, and turned off by the LED timer. /* The LED turned on by the button interrupt, and turned off by the LED timer.
This is an LED in the second digit of the two digit 7 segment display. See the * This is an LED in the second digit of the two digit 7 segment display. See the
documentation page for this demo on the FreeRTOS.org web site to see which LED * documentation page for this demo on the FreeRTOS.org web site to see which LED
this relates to. */ * this relates to. */
#define mainTIMER_CONTROLLED_LED 0x05UL #define mainTIMER_CONTROLLED_LED 0x05UL
/* The LED used by the comtest tasks. See the comtest.c file for more /* The LED used by the comtest tasks. See the comtest.c file for more
information. The LEDs used by the comtest task are in the second digit of the * information. The LEDs used by the comtest task are in the second digit of the
two digit 7 segment display. See the documentation page for this demo on the * two digit 7 segment display. See the documentation page for this demo on the
FreeRTOS.org web site to see which LEDs this relates to. */ * FreeRTOS.org web site to see which LEDs this relates to. */
#define mainCOM_TEST_LED ( 3 ) #define mainCOM_TEST_LED ( 3 )
/* Constant used by the standard timer test functions. */ /* Constant used by the standard timer test functions. */
#define mainTIMER_TEST_PERIOD ( 50 ) #define mainTIMER_TEST_PERIOD ( 50 )
/* Priorities used by the various different standard demo tasks. */ /* Priorities used by the various different standard demo tasks. */
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) #define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* Priorities defined in this main-full.c file. */ /* Priorities defined in this main-full.c file. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The period at which the check timer will expire, in ms, provided no errors /* The period at which the check timer will expire, in ms, provided no errors
have been reported by any of the standard demo tasks. ms are converted to the * have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */ * equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been /* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent * reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */ * in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_PERIOD_MS ) #define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_PERIOD_MS )
/* The period at which the digit counter timer will expire, in ms, and converted /* The period at which the digit counter timer will expire, in ms, and converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainDIGIT_COUNTER_TIMER_PERIOD_MS ( 250UL / portTICK_PERIOD_MS ) #define mainDIGIT_COUNTER_TIMER_PERIOD_MS ( 250UL / portTICK_PERIOD_MS )
/* The LED will remain on until the button has not been pushed for a full /* The LED will remain on until the button has not been pushed for a full
5000ms. */ * 5000ms. */
#define mainLED_TIMER_PERIOD_MS ( 5000UL / portTICK_PERIOD_MS ) #define mainLED_TIMER_PERIOD_MS ( 5000UL / portTICK_PERIOD_MS )
/* A zero block time. */ /* A zero block time. */
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* Baud rate used by the comtest tasks. */ /* Baud rate used by the comtest tasks. */
#define mainCOM_TEST_BAUD_RATE ( 115200UL ) #define mainCOM_TEST_BAUD_RATE ( 115200UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -219,8 +219,8 @@ static void prvSetupHardware( void );
* The application specific (not common demo) tasks as described in the comments * The application specific (not common demo) tasks as described in the comments
* at the top of this file. * at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* The LED timer callback function. This does nothing but switch an LED off. * The LED timer callback function. This does nothing but switch an LED off.
@ -241,7 +241,8 @@ static void prvDigitCounterTimerCallback( TimerHandle_t xTimer );
* This is not a 'standard' partest function, so the prototype is not in * This is not a 'standard' partest function, so the prototype is not in
* partest.h, and is instead included here. * partest.h, and is instead included here.
*/ */
void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue ); void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED,
signed portBASE_TYPE xValue );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -249,377 +250,384 @@ void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE x
static QueueHandle_t xQueue = NULL; static QueueHandle_t xQueue = NULL;
/* The LED software timer. This uses prvLEDTimerCallback() as it's callback /* The LED software timer. This uses prvLEDTimerCallback() as it's callback
function. */ * function. */
static TimerHandle_t xLEDTimer = NULL; static TimerHandle_t xLEDTimer = NULL;
/* The digit counter software timer. This displays a counting digit on one half /* The digit counter software timer. This displays a counting digit on one half
of the seven segment displays. */ * of the seven segment displays. */
static TimerHandle_t xDigitCounterTimer = NULL; static TimerHandle_t xDigitCounterTimer = NULL;
/* The check timer. This uses prvCheckTimerCallback() as its callback /* The check timer. This uses prvCheckTimerCallback() as its callback
function. */ * function. */
static TimerHandle_t xCheckTimer = NULL; static TimerHandle_t xCheckTimer = NULL;
/* If an error is detected in a standard demo task, then pcStatusMessage will /* If an error is detected in a standard demo task, then pcStatusMessage will
be set to point to a string that identifies the offending task. This is just * be set to point to a string that identifies the offending task. This is just
to make debugging easier. */ * to make debugging easier. */
static const char *pcStatusMessage = NULL; static const char * pcStatusMessage = NULL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main(void) int main( void )
{ {
/* Configure the NVIC, LED outputs and button inputs. */ /* Configure the NVIC, LED outputs and button inputs. */
prvSetupHardware(); prvSetupHardware();
/* Create the queue. */ /* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two application specific demo tasks, as described in the /* Start the two application specific demo tasks, as described in the
comments at the top of this file. */ * comments at the top of this file. */
xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Create the software timer that is responsible for turning off the LED /* Create the software timer that is responsible for turning off the LED
if the button is not pushed within 5000ms, as described at the top of * if the button is not pushed within 5000ms, as described at the top of
this file. */ * this file. */
xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */ xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */
( mainLED_TIMER_PERIOD_MS ),/* The timer period, in this case 5000ms (5s). */ ( mainLED_TIMER_PERIOD_MS ), /* The timer period, in this case 5000ms (5s). */
pdFALSE, /* This is a one-shot timer, so xAutoReload is set to pdFALSE. */ pdFALSE, /* This is a one-shot timer, so xAutoReload is set to pdFALSE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvLEDTimerCallback /* The callback function that switches the LED off. */ prvLEDTimerCallback /* The callback function that switches the LED off. */
); );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */ prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
); );
/* Create the software timer that performs the 'digit counting' /* Create the software timer that performs the 'digit counting'
functionality, as described at the top of this file. */ * functionality, as described at the top of this file. */
xDigitCounterTimer = xTimerCreate( "DigitCounter", /* A text name, purely to help debugging. */ xDigitCounterTimer = xTimerCreate( "DigitCounter", /* A text name, purely to help debugging. */
( mainDIGIT_COUNTER_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainDIGIT_COUNTER_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvDigitCounterTimerCallback /* The callback function that inspects the status of all the other tasks. */ prvDigitCounterTimerCallback /* The callback function that inspects the status of all the other tasks. */
); );
/* Create a lot of 'standard demo' tasks. Over 40 tasks are created in /* Create a lot of 'standard demo' tasks. Over 40 tasks are created in
this demo. For a much simpler demo, select the 'blinky' build * this demo. For a much simpler demo, select the 'blinky' build
configuration. */ * configuration. */
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY ); vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY ); vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );
vStartQueuePeekTasks(); vStartQueuePeekTasks();
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
vStartTimerDemoTask( mainTIMER_TEST_PERIOD ); vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartCountingSemaphoreTasks(); vStartCountingSemaphoreTasks();
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
/* The suicide tasks must be created last, as they need to know how many /* The suicide tasks must be created last, as they need to know how many
tasks were running prior to their creation in order to ascertain whether * tasks were running prior to their creation in order to ascertain whether
or not the correct/expected number of tasks are running at any given * or not the correct/expected number of tasks are running at any given
time. */ * time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
/* Check the standard demo tasks are running without error. Latch the /* Check the standard demo tasks are running without error. Latch the
latest reported error in the pcStatusMessage character pointer. */ * latest reported error in the pcStatusMessage character pointer. */
if( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: GenQueue"; pcStatusMessage = "Error: GenQueue";
} }
if( xAreQueuePeekTasksStillRunning() != pdTRUE ) if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: QueuePeek\r\n"; pcStatusMessage = "Error: QueuePeek\r\n";
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: BlockQueue\r\n"; pcStatusMessage = "Error: BlockQueue\r\n";
} }
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: BlockTime\r\n"; pcStatusMessage = "Error: BlockTime\r\n";
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: SemTest\r\n"; pcStatusMessage = "Error: SemTest\r\n";
} }
if( xIsCreateTaskStillRunning() != pdTRUE ) if( xIsCreateTaskStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: Death\r\n"; pcStatusMessage = "Error: Death\r\n";
} }
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: RecMutex\r\n"; pcStatusMessage = "Error: RecMutex\r\n";
} }
if( xAreComTestTasksStillRunning() != pdPASS ) if( xAreComTestTasksStillRunning() != pdPASS )
{ {
pcStatusMessage = "Error: ComTest\r\n"; pcStatusMessage = "Error: ComTest\r\n";
} }
if( xAreTimerDemoTasksStillRunning( ( mainCHECK_TIMER_PERIOD_MS ) ) != pdTRUE ) if( xAreTimerDemoTasksStillRunning( ( mainCHECK_TIMER_PERIOD_MS ) ) != pdTRUE )
{ {
pcStatusMessage = "Error: TimerDemo"; pcStatusMessage = "Error: TimerDemo";
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: PollQueue"; pcStatusMessage = "Error: PollQueue";
} }
if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: CountSem"; pcStatusMessage = "Error: CountSem";
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
pcStatusMessage = "Error: DynamicPriority"; pcStatusMessage = "Error: DynamicPriority";
} }
/* Toggle the check LED to give an indication of the system status. If /* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then * the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */ * everything is ok. A faster toggle indicates an error. */
vParTestToggleLED( mainCHECK_LED ); vParTestToggleLED( mainCHECK_LED );
/* Have any errors been latch in pcStatusMessage? If so, shorten the /* Have any errors been latch in pcStatusMessage? If so, shorten the
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. * period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
This will result in an increase in the rate at which mainCHECK_LED * This will result in an increase in the rate at which mainCHECK_LED
toggles. */ * toggles. */
if( pcStatusMessage != NULL ) if( pcStatusMessage != NULL )
{ {
/* This call to xTimerChangePeriod() uses a zero block time. Functions /* This call to xTimerChangePeriod() uses a zero block time. Functions
called from inside of a timer callback function must *never* attempt * called from inside of a timer callback function must *never* attempt
to block. */ * to block. */
xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvLEDTimerCallback( TimerHandle_t xTimer ) static void prvLEDTimerCallback( TimerHandle_t xTimer )
{ {
/* The timer has expired - so no button pushes have occurred in the last /* The timer has expired - so no button pushes have occurred in the last
five seconds - turn the LED off. */ * five seconds - turn the LED off. */
vParTestSetLED( mainTIMER_CONTROLLED_LED, pdFALSE ); vParTestSetLED( mainTIMER_CONTROLLED_LED, pdFALSE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvDigitCounterTimerCallback( TimerHandle_t xTimer ) static void prvDigitCounterTimerCallback( TimerHandle_t xTimer )
{ {
/* Define the bit patterns that display numbers on the seven segment display. */ /* Define the bit patterns that display numbers on the seven segment display. */
static const unsigned short usNumbersPatterns[] = { 0xC000U, 0xF900U, 0xA400U, 0xB000U, 0x9900U, 0x9200U, 0x8200U, 0xF800U, 0x8000U, 0x9000U }; static const unsigned short usNumbersPatterns[] = { 0xC000U, 0xF900U, 0xA400U, 0xB000U, 0x9900U, 0x9200U, 0x8200U, 0xF800U, 0x8000U, 0x9000U };
static long lCounter = 0L; static long lCounter = 0L;
const long lNumberOfDigits = 10L; const long lNumberOfDigits = 10L;
/* Display the next number, counting up. */ /* Display the next number, counting up. */
FM3_GPIO->PDOR1 = usNumbersPatterns[ lCounter ]; FM3_GPIO->PDOR1 = usNumbersPatterns[ lCounter ];
/* Move onto the next digit. */ /* Move onto the next digit. */
lCounter++; lCounter++;
/* Ensure the counter does not go off the end of the array. */ /* Ensure the counter does not go off the end of the array. */
if( lCounter >= lNumberOfDigits ) if( lCounter >= lNumberOfDigits )
{ {
lCounter = 0L; lCounter = 0L;
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The ISR executed when the user button is pushed. */ /* The ISR executed when the user button is pushed. */
void INT0_7_Handler( void ) void INT0_7_Handler( void )
{ {
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* The button was pushed, so ensure the LED is on before resetting the /* The button was pushed, so ensure the LED is on before resetting the
LED timer. The LED timer will turn the LED off if the button is not * LED timer. The LED timer will turn the LED off if the button is not
pushed within 5000ms. */ * pushed within 5000ms. */
vParTestSetLEDFromISR( mainTIMER_CONTROLLED_LED, pdTRUE ); vParTestSetLEDFromISR( mainTIMER_CONTROLLED_LED, pdTRUE );
/* This interrupt safe FreeRTOS function can be called from this interrupt /* This interrupt safe FreeRTOS function can be called from this interrupt
because the interrupt priority is below the * because the interrupt priority is below the
configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */ * configMAX_SYSCALL_INTERRUPT_PRIORITY setting in FreeRTOSConfig.h. */
xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken ); xTimerResetFromISR( xLEDTimer, &xHigherPriorityTaskWoken );
/* Clear the interrupt before leaving. This just clears all the interrupts /* Clear the interrupt before leaving. This just clears all the interrupts
for simplicity, as only one is actually used in this simple demo anyway. */ * for simplicity, as only one is actually used in this simple demo anyway. */
FM3_EXTI->EICL = 0x0000; FM3_EXTI->EICL = 0x0000;
/* If calling xTimerResetFromISR() caused a task (in this case the timer /* If calling xTimerResetFromISR() caused a task (in this case the timer
service/daemon task) to unblock, and the unblocked task has a priority * service/daemon task) to unblock, and the unblocked task has a priority
higher than or equal to the task that was interrupted, then * higher than or equal to the task that was interrupted, then
xHigherPriorityTaskWoken will now be set to pdTRUE, and calling * xHigherPriorityTaskWoken will now be set to pdTRUE, and calling
portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */ * portEND_SWITCHING_ISR() will ensure the unblocked task runs next. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* The timer command queue will have been filled when the timer test tasks /* The timer command queue will have been filled when the timer test tasks
were created in main() (this is part of the test they perform). Therefore, * were created in main() (this is part of the test they perform). Therefore,
while the check and digit counter timers can be created in main(), they * while the check and digit counter timers can be created in main(), they
cannot be started from main(). Once the scheduler has started, the timer * cannot be started from main(). Once the scheduler has started, the timer
service task will drain the command queue, and now the check and digit * service task will drain the command queue, and now the check and digit
counter timers can be started successfully. */ * counter timers can be started successfully. */
xTimerStart( xCheckTimer, portMAX_DELAY ); xTimerStart( xCheckTimer, portMAX_DELAY );
xTimerStart( xDigitCounterTimer, portMAX_DELAY ); xTimerStart( xDigitCounterTimer, portMAX_DELAY );
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle an LED. 0 is used as the block time so the sending operation * toggle an LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK ); xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
vParTestToggleLED( mainTASK_CONTROLLED_LED ); vParTestToggleLED( mainTASK_CONTROLLED_LED );
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
const unsigned short usButtonInputBit = 0x01U; const unsigned short usButtonInputBit = 0x01U;
SystemInit(); SystemInit();
SystemCoreClockUpdate(); SystemCoreClockUpdate();
/* Initialise the IO used for the LEDs on the 7 segment displays. */ /* Initialise the IO used for the LEDs on the 7 segment displays. */
vParTestInitialise(); vParTestInitialise();
/* Set the switches to input (P18->P1F). */ /* Set the switches to input (P18->P1F). */
FM3_GPIO->DDR5 = 0x0000; FM3_GPIO->DDR5 = 0x0000;
FM3_GPIO->PFR5 = 0x0000; FM3_GPIO->PFR5 = 0x0000;
/* Assign the button input as GPIO. */ /* Assign the button input as GPIO. */
FM3_GPIO->PFR1 |= usButtonInputBit; FM3_GPIO->PFR1 |= usButtonInputBit;
/* Button interrupt on falling edge. */ /* Button interrupt on falling edge. */
FM3_EXTI->ELVR = 0x0003; FM3_EXTI->ELVR = 0x0003;
/* Clear all external interrupts. */ /* Clear all external interrupts. */
FM3_EXTI->EICL = 0x0000; FM3_EXTI->EICL = 0x0000;
/* Enable the button interrupt. */ /* Enable the button interrupt. */
FM3_EXTI->ENIR |= usButtonInputBit; FM3_EXTI->ENIR |= usButtonInputBit;
/* Setup the GPIO and the NVIC for the switch used in this simple demo. */ /* Setup the GPIO and the NVIC for the switch used in this simple demo. */
NVIC_SetPriority( EXINT0_7_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); NVIC_SetPriority( EXINT0_7_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
NVIC_EnableIRQ( EXINT0_7_IRQn ); NVIC_EnableIRQ( EXINT0_7_IRQn );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* Called if a call to pvPortMalloc() fails because there is insufficient /* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called * free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software * internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the * timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */ * configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
( void ) pcTaskName; ( void ) pcTaskName;
( void ) pxTask; ( void ) pxTask;
/* Run time stack overflow checking is performed if /* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */ * function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS(); taskDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationIdleHook( void ) void vApplicationIdleHook( void )
{ {
volatile size_t xFreeStackSpace; volatile size_t xFreeStackSpace;
/* This function is called on each cycle of the idle task. In this case it /* This function is called on each cycle of the idle task. In this case it
does nothing useful, other than report the amount of FreeRTOS heap that * does nothing useful, other than report the amount of FreeRTOS heap that
remains unallocated. */ * remains unallocated. */
xFreeStackSpace = xPortGetFreeHeapSize(); xFreeStackSpace = xPortGetFreeHeapSize();
if( xFreeStackSpace > 100 ) if( xFreeStackSpace > 100 )
{ {
/* By now, the kernel has allocated everything it is going to, so /* By now, the kernel has allocated everything it is going to, so
if there is a lot of heap remaining unallocated then * if there is a lot of heap remaining unallocated then
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be * the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
reduced accordingly. */ * reduced accordingly. */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook( void ) void vApplicationTickHook( void )
{ {
/* Call the periodic timer test, which tests the timer API functions that /* Call the periodic timer test, which tests the timer API functions that
can be called from an ISR. */ * can be called from an ISR. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -98,222 +98,224 @@
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task priorities. */ /* Task priorities. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* Stack sizes are defined relative to configMINIMAL_STACK_SIZE so they scale /* Stack sizes are defined relative to configMINIMAL_STACK_SIZE so they scale
across projects that have that constant set differently - in this case the * across projects that have that constant set differently - in this case the
constant is different depending on the compiler in use. */ * constant is different depending on the compiler in use. */
#define mainMESSAGE_BUFFER_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) ) #define mainMESSAGE_BUFFER_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) )
#define mainCHECK_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) ) #define mainCHECK_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The task that checks the operation of all the other standard demo tasks, as /* The task that checks the operation of all the other standard demo tasks, as
* described at the top of this file. */ * described at the top of this file. */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
/* Start the standard demo tasks. */ /* Start the standard demo tasks. */
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY ); vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
vStartInterruptQueueTasks(); vStartInterruptQueueTasks();
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartQueuePeekTasks(); vStartQueuePeekTasks();
vStartQueueSetTasks(); vStartQueueSetTasks();
vStartEventGroupTasks(); vStartEventGroupTasks();
vStartMessageBufferTasks( mainMESSAGE_BUFFER_STACK_SIZE ); vStartMessageBufferTasks( mainMESSAGE_BUFFER_STACK_SIZE );
vStartStreamBufferTasks(); vStartStreamBufferTasks();
vCreateAbortDelayTasks(); vCreateAbortDelayTasks();
vStartCountingSemaphoreTasks(); vStartCountingSemaphoreTasks();
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartMessageBufferAMPTasks( configMINIMAL_STACK_SIZE ); vStartMessageBufferAMPTasks( configMINIMAL_STACK_SIZE );
vStartQueueOverwriteTask( tskIDLE_PRIORITY ); vStartQueueOverwriteTask( tskIDLE_PRIORITY );
vStartQueueSetPollingTask(); vStartQueueSetPollingTask();
vStartStaticallyAllocatedTasks(); vStartStaticallyAllocatedTasks();
vStartTaskNotifyTask(); vStartTaskNotifyTask();
vStartTaskNotifyArrayTask(); vStartTaskNotifyArrayTask();
vStartTimerDemoTask( 50 ); vStartTimerDemoTask( 50 );
vStartStreamBufferInterruptDemo(); vStartStreamBufferInterruptDemo();
vStartInterruptSemaphoreTasks(); vStartInterruptSemaphoreTasks();
/* The suicide tasks must be created last as they need to know how many /* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation in order to ascertain whether * tasks were running prior to their creation in order to ascertain whether
or not the correct/expected number of tasks are running at any given time. */ * or not the correct/expected number of tasks are running at any given time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* If configSUPPORT_STATIC_ALLOCATION was false then execution would only /* If configSUPPORT_STATIC_ALLOCATION was false then execution would only
get here if there was insufficient heap memory to create either the idle or * get here if there was insufficient heap memory to create either the idle or
timer tasks. As static allocation is used execution should never be able * timer tasks. As static allocation is used execution should never be able
to reach here. */ * to reach here. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* See the comments at the top of this file. */ /* See the comments at the top of this file. */
static void prvCheckTask( void *pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
static const char * pcMessage = "PASS"; static const char * pcMessage = "PASS";
const TickType_t xTaskPeriod = pdMS_TO_TICKS( 5000UL ); const TickType_t xTaskPeriod = pdMS_TO_TICKS( 5000UL );
TickType_t xPreviousWakeTime; TickType_t xPreviousWakeTime;
extern uint32_t ulNestCount; extern uint32_t ulNestCount;
/* Avoid warning about unused parameter. */ /* Avoid warning about unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
xPreviousWakeTime = xTaskGetTickCount(); xPreviousWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
vTaskDelayUntil( &xPreviousWakeTime, xTaskPeriod ); vTaskDelayUntil( &xPreviousWakeTime, xTaskPeriod );
/* Has an error been found in any task? */ /* Has an error been found in any task? */
if( xAreStreamBufferTasksStillRunning() != pdTRUE ) if( xAreStreamBufferTasksStillRunning() != pdTRUE )
{ {
pcMessage = "xAreStreamBufferTasksStillRunning() returned false"; pcMessage = "xAreStreamBufferTasksStillRunning() returned false";
} }
else if( xAreMessageBufferTasksStillRunning() != pdTRUE ) else if( xAreMessageBufferTasksStillRunning() != pdTRUE )
{ {
pcMessage = "xAreMessageBufferTasksStillRunning() returned false"; pcMessage = "xAreMessageBufferTasksStillRunning() returned false";
} }
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreGenericQueueTasksStillRunning() returned false";
}
else if( xIsCreateTaskStillRunning() != pdTRUE )
{
pcMessage = "xIsCreateTaskStillRunning() returned false";
}
else if( xAreIntQueueTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreIntQueueTasksStillRunning() returned false";
}
else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreBlockTimeTestTasksStillRunning() returned false";
}
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreSemaphoreTasksStillRunning() returned false";
}
else if( xArePollingQueuesStillRunning() != pdTRUE )
{
pcMessage = "xArePollingQueuesStillRunning() returned false";
}
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreQueuePeekTasksStillRunning() returned false";
}
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreRecursiveMutexTasksStillRunning() returned false";
}
else if( xAreQueueSetTasksStillRunning() != pdPASS )
{
pcMessage = "xAreQueueSetTasksStillRunning() returned false";
}
else if( xAreEventGroupTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreEventGroupTasksStillRunning() returned false";
}
else if( xAreAbortDelayTestTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreAbortDelayTestTasksStillRunning() returned false";
}
else if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreCountingSemaphoreTasksStillRunning() returned false";
}
else if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreDynamicPriorityTasksStillRunning() returned false";
}
else if( xAreMessageBufferAMPTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreMessageBufferAMPTasksStillRunning() returned false";
}
else if( xIsQueueOverwriteTaskStillRunning() != pdTRUE )
{
pcMessage = "xIsQueueOverwriteTaskStillRunning() returned false";
}
else if( xAreQueueSetPollTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreQueueSetPollTasksStillRunning() returned false";
}
else if( xAreStaticAllocationTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreStaticAllocationTasksStillRunning() returned false";
}
else if( xAreTaskNotificationTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreTaskNotificationTasksStillRunning() returned false";
}
else if( xAreTaskNotificationArrayTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreTaskNotificationArrayTasksStillRunning() returned false";
}
else if( xAreTimerDemoTasksStillRunning( xTaskPeriod ) != pdTRUE )
{
pcMessage = "xAreTimerDemoTasksStillRunning() returned false";
}
else if( xIsInterruptStreamBufferDemoStillRunning() != pdTRUE )
{
pcMessage = "xIsInterruptStreamBufferDemoStillRunning() returned false";
}
else if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreInterruptSemaphoreTasksStillRunning() returned false";
}
/* It is normally not good to call printf() from an embedded system, if( xAreGenericQueueTasksStillRunning() != pdTRUE )
although it is ok in this simulated case. */ {
printf( "%s : %d (%d)\r\n", pcMessage, (int) xTaskGetTickCount(), ( int ) ulNestCount ); pcMessage = "xAreGenericQueueTasksStillRunning() returned false";
} }
else if( xIsCreateTaskStillRunning() != pdTRUE )
{
pcMessage = "xIsCreateTaskStillRunning() returned false";
}
else if( xAreIntQueueTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreIntQueueTasksStillRunning() returned false";
}
else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreBlockTimeTestTasksStillRunning() returned false";
}
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreSemaphoreTasksStillRunning() returned false";
}
else if( xArePollingQueuesStillRunning() != pdTRUE )
{
pcMessage = "xArePollingQueuesStillRunning() returned false";
}
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreQueuePeekTasksStillRunning() returned false";
}
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreRecursiveMutexTasksStillRunning() returned false";
}
else if( xAreQueueSetTasksStillRunning() != pdPASS )
{
pcMessage = "xAreQueueSetTasksStillRunning() returned false";
}
else if( xAreEventGroupTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreEventGroupTasksStillRunning() returned false";
}
else if( xAreAbortDelayTestTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreAbortDelayTestTasksStillRunning() returned false";
}
else if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreCountingSemaphoreTasksStillRunning() returned false";
}
else if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreDynamicPriorityTasksStillRunning() returned false";
}
else if( xAreMessageBufferAMPTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreMessageBufferAMPTasksStillRunning() returned false";
}
else if( xIsQueueOverwriteTaskStillRunning() != pdTRUE )
{
pcMessage = "xIsQueueOverwriteTaskStillRunning() returned false";
}
else if( xAreQueueSetPollTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreQueueSetPollTasksStillRunning() returned false";
}
else if( xAreStaticAllocationTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreStaticAllocationTasksStillRunning() returned false";
}
else if( xAreTaskNotificationTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreTaskNotificationTasksStillRunning() returned false";
}
else if( xAreTaskNotificationArrayTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreTaskNotificationArrayTasksStillRunning() returned false";
}
else if( xAreTimerDemoTasksStillRunning( xTaskPeriod ) != pdTRUE )
{
pcMessage = "xAreTimerDemoTasksStillRunning() returned false";
}
else if( xIsInterruptStreamBufferDemoStillRunning() != pdTRUE )
{
pcMessage = "xIsInterruptStreamBufferDemoStillRunning() returned false";
}
else if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE )
{
pcMessage = "xAreInterruptSemaphoreTasksStillRunning() returned false";
}
/* 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 );
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vFullDemoTickHookFunction( void ) void vFullDemoTickHookFunction( void )
{ {
/* Write to a queue that is in use as part of the queue set demo to /* Write to a queue that is in use as part of the queue set demo to
demonstrate using queue sets from an ISR. */ * demonstrate using queue sets from an ISR. */
vQueueSetAccessQueueSetFromISR(); vQueueSetAccessQueueSetFromISR();
/* Call the event group ISR tests. */ /* Call the event group ISR tests. */
vPeriodicEventGroupsProcessing(); vPeriodicEventGroupsProcessing();
/* Exercise stream buffers from interrupts. */ /* Exercise stream buffers from interrupts. */
vPeriodicStreamBufferProcessing(); vPeriodicStreamBufferProcessing();
/* Exercise using queue overwrites from interrupts. */ /* Exercise using queue overwrites from interrupts. */
vQueueOverwritePeriodicISRDemo(); vQueueOverwritePeriodicISRDemo();
/* Exercise using Queue Sets from interrupts. */ /* Exercise using Queue Sets from interrupts. */
vQueueSetPollingInterruptAccess(); vQueueSetPollingInterruptAccess();
/* Exercise using task notifications from interrupts. */ /* Exercise using task notifications from interrupts. */
xNotifyTaskFromISR(); xNotifyTaskFromISR();
xNotifyArrayTaskFromISR(); xNotifyArrayTaskFromISR();
/* Exercise software timers from interrupts. */ /* Exercise software timers from interrupts. */
vTimerPeriodicISRTests(); vTimerPeriodicISRTests();
/* Exercise stream buffers from interrupts. */ /* Exercise stream buffers from interrupts. */
vBasicStreamBufferSendFromISR(); vBasicStreamBufferSendFromISR();
/* Exercise semaphores from interrupts. */ /* Exercise semaphores from interrupts. */
vInterruptSemaphorePeriodicTest(); vInterruptSemaphorePeriodicTest();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -70,8 +70,8 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask,
void vApplicationMallocFailedHook( void ) void vApplicationMallocFailedHook( void )
{ {
/* If configUSE_MALLOC_FAILED_HOOK is set to 1 then this function will /* If configUSE_MALLOC_FAILED_HOOK is set to 1 then this function will
* be called automatically if a call to pvPortMalloc() fails. pvPortMalloc() * be called automatically if a call to pvPortMalloc() fails. pvPortMalloc()
* is called automatically when a task, queue or semaphore is created. */ * is called automatically when a task, queue or semaphore is created. */
printf( "Application Malloc Failed Hook called\n" ); printf( "Application Malloc Failed Hook called\n" );
for( ; ; ) for( ; ; )

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -73,30 +73,30 @@
#include "partest.h" #include "partest.h"
/* Priorities at which the tasks are created. */ /* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted /* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */ * to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS ) #define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The number of items the queue can hold. This is 1 as the receive task /* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find * will remove items as they are added, meaning the send task should always find
the queue empty. */ * the queue empty. */
#define mainQUEUE_LENGTH ( 1 ) #define mainQUEUE_LENGTH ( 1 )
/* Values passed to the two tasks just to check the task parameter /* Values passed to the two tasks just to check the task parameter
functionality. */ * functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* The tasks as described in the comments at the top of this file. * The tasks as described in the comments at the top of this file.
*/ */
static void prvQueueReceiveTask( void *pvParameters ); static void prvQueueReceiveTask( void * pvParameters );
static void prvQueueSendTask( void *pvParameters ); static void prvQueueSendTask( void * pvParameters );
/* /*
* Called by main() to create the simply blinky style application if * Called by main() to create the simply blinky style application if
@ -113,85 +113,86 @@ static QueueHandle_t xQueue = NULL;
void main_blinky( void ) void main_blinky( void )
{ {
/* Create the queue. */ /* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
if( xQueue != NULL ) if( xQueue != NULL )
{ {
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
file. */ * file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */ ( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
NULL ); /* The task handle is not required, so NULL is passed. */ NULL ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
vTaskStartScheduler(); vTaskStartScheduler();
} }
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then * line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or * there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the * timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */ * FreeRTOS web site for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters ) static void prvQueueSendTask( void * pvParameters )
{ {
TickType_t xNextWakeTime; TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL; const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
/* Initialise xNextWakeTime - this only needs to be done once. */ /* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount(); xNextWakeTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Place this task in the blocked state until it is time to run again. /* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, the constant used converts ticks * The block time is specified in ticks, the constant used converts ticks
to ms. While in the Blocked state this task will not consume any CPU * to ms. While in the Blocked state this task will not consume any CPU
time. */ * time. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and /* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation * toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always * will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */ * be empty at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U ); xQueueSend( xQueue, &ulValueToSend, 0U );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters ) static void prvQueueReceiveTask( void * pvParameters )
{ {
unsigned long ulReceivedValue; unsigned long ulReceivedValue;
/* Check the task parameter is as expected. */ /* Check the task parameter is as expected. */
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
for( ;; ) for( ; ; )
{ {
/* Wait until something arrives in the queue - this task will block /* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */ * FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but /* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */ * is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL ) if( ulReceivedValue == 100UL )
{ {
vParTestToggleLED( 0 ); vParTestToggleLED( 0 );
ulReceivedValue = 0U; ulReceivedValue = 0U;
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -95,26 +95,26 @@
#include "comtest.h" #include "comtest.h"
/* Priorities for the demo application tasks. */ /* Priorities for the demo application tasks. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL ) #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* A block time of zero simply means "don't block". */ /* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL ) #define mainDONT_BLOCK ( 0UL )
/* The period after which the check timer will expire, converted to ticks. */ /* The period after which the check timer will expire, converted to ticks. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS ) #define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period after which the LED timer will expire, converted to ticks. */ /* The period after which the LED timer will expire, converted to ticks. */
#define mainLED_TIMER_PERIOD_MS ( 75UL / portTICK_PERIOD_MS ) #define mainLED_TIMER_PERIOD_MS ( 75UL / portTICK_PERIOD_MS )
/* Constants for the ComTest tasks. */ /* Constants for the ComTest tasks. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 19200 ) #define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 19200 )
#define mainCOM_TEST_LED ( 100 ) #define mainCOM_TEST_LED ( 100 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -131,211 +131,213 @@ static void prvLEDTimerCallback( TimerHandle_t xTimer );
/* /*
* The reg test tasks, as described at the top of this file. * The reg test tasks, as described at the top of this file.
*/ */
extern void vRegTestTask1( void *pvParameters ); extern void vRegTestTask1( void * pvParameters );
extern void vRegTestTask2( void *pvParameters ); extern void vRegTestTask2( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Variables that are incremented on each iteration of the reg test tasks - /* Variables that are incremented on each iteration of the reg test tasks -
provided the tasks have not reported any errors. The check task inspects these * provided the tasks have not reported any errors. The check task inspects these
variables to ensure they are still incrementing as expected. If a variable * variables to ensure they are still incrementing as expected. If a variable
stops incrementing then it is likely that its associate task has stalled. */ * stops incrementing then it is likely that its associate task has stalled. */
volatile unsigned long ulRegTest1Counter = 0, ulRegTest2Counter = 0; volatile unsigned long ulRegTest1Counter = 0, ulRegTest2Counter = 0;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void main_full( void ) void main_full( void )
{ {
TimerHandle_t xTimer = NULL; TimerHandle_t xTimer = NULL;
/* Start all the standard demo/test tasks. These have not particular /* Start all the standard demo/test tasks. These have not particular
functionality, but do demonstrate how to use the FreeRTOS API, and test the * functionality, but do demonstrate how to use the FreeRTOS API, and test the
kernel port. */ * kernel port. */
vStartIntegerMathTasks( tskIDLE_PRIORITY ); vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks(); vCreateBlockTimeTasks();
vStartCountingSemaphoreTasks(); vStartCountingSemaphoreTasks();
vStartGenericQueueTasks( tskIDLE_PRIORITY ); vStartGenericQueueTasks( tskIDLE_PRIORITY );
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartMathTasks( mainFLOP_TASK_PRIORITY ); vStartMathTasks( mainFLOP_TASK_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
/* Create the register test tasks, as described at the top of this file. */ /* Create the register test tasks, as described at the top of this file. */
xTaskCreate( vRegTestTask1, "Reg1...", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTestTask1, "Reg1...", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vRegTestTask2, "Reg2...", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); xTaskCreate( vRegTestTask2, "Reg2...", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
/* Create the software timer that performs the 'check' functionality, /* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ xTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */ prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
); );
if( xTimer != NULL ) if( xTimer != NULL )
{ {
xTimerStart( xTimer, mainDONT_BLOCK ); xTimerStart( xTimer, mainDONT_BLOCK );
} }
/* Create the software timer that performs the 'LED spin' functionality, /* Create the software timer that performs the 'LED spin' functionality,
as described at the top of this file. */ * as described at the top of this file. */
xTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */ xTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */
( mainLED_TIMER_PERIOD_MS ),/* The timer period, in this case 75ms. */ ( mainLED_TIMER_PERIOD_MS ), /* The timer period, in this case 75ms. */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( void * ) 0, /* The ID is not used, so can be set to anything. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */
prvLEDTimerCallback /* The callback function that toggles the white LEDs. */ prvLEDTimerCallback /* The callback function that toggles the white LEDs. */
); );
if( xTimer != NULL ) if( xTimer != NULL )
{ {
xTimerStart( xTimer, mainDONT_BLOCK ); xTimerStart( xTimer, mainDONT_BLOCK );
} }
/* The set of tasks created by the following function call have to be /* The set of tasks created by the following function call have to be
created last as they keep account of the number of tasks they expect to see * created last as they keep account of the number of tasks they expect to see
running. */ * running. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line /* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was * will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks * insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site * to be created. See the memory management section on the FreeRTOS web site
for more details. */ * for more details. */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer ) static void prvCheckTimerCallback( TimerHandle_t xTimer )
{ {
static long lChangeToRedLEDsAlready = pdFALSE; static long lChangeToRedLEDsAlready = pdFALSE;
static unsigned long ulLastRegTest1Counter = 0, ulLastRegTest2Counter = 0; static unsigned long ulLastRegTest1Counter = 0, ulLastRegTest2Counter = 0;
unsigned long ulErrorFound = pdFALSE; unsigned long ulErrorFound = pdFALSE;
/* LEDs are defaulted to use the Green LEDs. The Red LEDs are used if an error /* LEDs are defaulted to use the Green LEDs. The Red LEDs are used if an error
is found. */ * is found. */
static unsigned long ulLED1 = 8, ulLED2 = 11; static unsigned long ulLED1 = 8, ulLED2 = 11;
const unsigned long ulRedLED1 = 6, ulRedLED2 = 9; const unsigned long ulRedLED1 = 6, ulRedLED2 = 9;
/* Check all the demo tasks (other than the flash tasks) to ensure /* Check all the demo tasks (other than the flash tasks) to ensure
they are all still running, and that none have detected an error. */ * they are all still running, and that none have detected an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xAreBlockingQueuesStillRunning() != pdTRUE ) if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xIsCreateTaskStillRunning() != pdTRUE ) if( xIsCreateTaskStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xArePollingQueuesStillRunning() != pdTRUE ) if( xArePollingQueuesStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xAreSemaphoreTasksStillRunning() != pdTRUE ) if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xAreMathsTaskStillRunning() != pdTRUE ) if( xAreMathsTaskStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( xAreComTestTasksStillRunning() != pdTRUE ) if( xAreComTestTasksStillRunning() != pdTRUE )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
/* Check the reg test tasks are still cycling. They will stop /* Check the reg test tasks are still cycling. They will stop
incrementing their loop counters if they encounter an error. */ * incrementing their loop counters if they encounter an error. */
if( ulRegTest1Counter == ulLastRegTest1Counter ) if( ulRegTest1Counter == ulLastRegTest1Counter )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
if( ulRegTest2Counter == ulLastRegTest2Counter ) if( ulRegTest2Counter == ulLastRegTest2Counter )
{ {
ulErrorFound = pdTRUE; ulErrorFound = pdTRUE;
} }
ulLastRegTest1Counter = ulRegTest1Counter; ulLastRegTest1Counter = ulRegTest1Counter;
ulLastRegTest2Counter = ulRegTest2Counter; ulLastRegTest2Counter = ulRegTest2Counter;
/* Toggle the check LEDs to give an indication of the system status. If /* Toggle the check LEDs to give an indication of the system status. If
the green LEDs are toggling, then no errors have been detected. If the red * the green LEDs are toggling, then no errors have been detected. If the red
LEDs are toggling, then an error has been reported in at least one task. */ * LEDs are toggling, then an error has been reported in at least one task. */
vParTestToggleLED( ulLED1 ); vParTestToggleLED( ulLED1 );
vParTestToggleLED( ulLED2 ); vParTestToggleLED( ulLED2 );
/* Have any errors been latch in ulErrorFound? If so, ensure the gree LEDs /* Have any errors been latch in ulErrorFound? If so, ensure the gree LEDs
are off, then switch to using the red LEDs. */ * are off, then switch to using the red LEDs. */
if( ulErrorFound != pdFALSE ) if( ulErrorFound != pdFALSE )
{ {
if( lChangeToRedLEDsAlready == pdFALSE ) if( lChangeToRedLEDsAlready == pdFALSE )
{ {
lChangeToRedLEDsAlready = pdTRUE; lChangeToRedLEDsAlready = pdTRUE;
/* An error has been found. Switch to use the red LEDs. */ /* An error has been found. Switch to use the red LEDs. */
vParTestSetLED( ulLED1, pdFALSE ); vParTestSetLED( ulLED1, pdFALSE );
vParTestSetLED( ulLED2, pdFALSE ); vParTestSetLED( ulLED2, pdFALSE );
ulLED1 = ulRedLED1; ulLED1 = ulRedLED1;
ulLED2 = ulRedLED2; ulLED2 = ulRedLED2;
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvLEDTimerCallback( TimerHandle_t xTimer ) static void prvLEDTimerCallback( TimerHandle_t xTimer )
{ {
const unsigned long ulNumWhiteLEDs = 6; const unsigned long ulNumWhiteLEDs = 6;
static unsigned long ulLit1 = 2, ulLit2 = 1; static unsigned long ulLit1 = 2, ulLit2 = 1;
vParTestSetLED( ulLit2, pdFALSE ); vParTestSetLED( ulLit2, pdFALSE );
ulLit2 = ulLit1; ulLit2 = ulLit1;
ulLit1++; ulLit1++;
if( ulLit1 >= ulNumWhiteLEDs ) if( ulLit1 >= ulNumWhiteLEDs )
{ {
ulLit1 = 0; ulLit1 = 0;
} }
vParTestSetLED( ulLit1, pdTRUE ); vParTestSetLED( ulLit1, pdTRUE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,6 @@
/* /*
* FreeRTOS V202212.00 * FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -86,25 +86,25 @@
/* The time between cycles of the 'check' task - which depends on whether the /* The time between cycles of the 'check' task - which depends on whether the
check task has detected an error or not. */ * check task has detected an error or not. */
#define mainCHECK_DELAY_NO_ERROR ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY_NO_ERROR ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
#define mainCHECK_DELAY_ERROR ( ( TickType_t ) 500 / portTICK_PERIOD_MS ) #define mainCHECK_DELAY_ERROR ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
/* The LED controlled by the 'check' task. */ /* The LED controlled by the 'check' task. */
#define mainCHECK_LED ( 3 ) #define mainCHECK_LED ( 3 )
/* Task priorities. */ /* Task priorities. */
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainECHO_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainECHO_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* COM port and baud rate used by the echo task. */ /* COM port and baud rate used by the echo task. */
#define mainCOM0 ( 0 ) #define mainCOM0 ( 0 )
#define mainBAUD_RATE ( 115200 ) #define mainBAUD_RATE ( 115200 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -114,222 +114,235 @@ check task has detected an error or not. */
static void prvSetupHardware( void ); static void prvSetupHardware( void );
/* The 'check' task as described at the top of this file. */ /* The 'check' task as described at the top of this file. */
static void prvCheckTask( void *pvParameters ); static void prvCheckTask( void * pvParameters );
/* A simple task that echoes all the characters that are received on COM0 /* A simple task that echoes all the characters that are received on COM0
(USART1). */ * (USART1). */
static void prvUSARTEchoTask( void *pvParameters ); static void prvUSARTEchoTask( void * pvParameters );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int main( void ) int main( void )
{ {
#ifdef DEBUG #ifdef DEBUG
debug(); debug();
#endif #endif
/* Set up the clocks and memory interface. */ /* Set up the clocks and memory interface. */
prvSetupHardware(); prvSetupHardware();
/* Start the standard demo tasks. These are just here to exercise the /* Start the standard demo tasks. These are just here to exercise the
kernel port and provide examples of how the FreeRTOS API can be used. */ * kernel port and provide examples of how the FreeRTOS API can be used. */
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY ); vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY ); vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY ); vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );
vStartQueuePeekTasks(); vStartQueuePeekTasks();
vStartRecursiveMutexTasks(); vStartRecursiveMutexTasks();
/* Create the 'echo' task, which is also defined within this file. */ /* Create the 'echo' task, which is also defined within this file. */
xTaskCreate( prvUSARTEchoTask, "Echo", configMINIMAL_STACK_SIZE, NULL, mainECHO_TASK_PRIORITY, NULL ); xTaskCreate( prvUSARTEchoTask, "Echo", configMINIMAL_STACK_SIZE, NULL, mainECHO_TASK_PRIORITY, NULL );
/* Create the 'check' task, which is also defined within this file. */ /* Create the 'check' task, which is also defined within this file. */
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Start the scheduler. */ /* Start the scheduler. */
vTaskStartScheduler(); vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle /* Will only get here if there was insufficient memory to create the idle
task. The idle task is created within vTaskStartScheduler(). */ * task. The idle task is created within vTaskStartScheduler(). */
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Described at the top of this file. */ /* Described at the top of this file. */
static void prvCheckTask( void *pvParameters ) static void prvCheckTask( void * pvParameters )
{ {
TickType_t xLastExecutionTime; TickType_t xLastExecutionTime;
unsigned long ulTicksToWait = mainCHECK_DELAY_NO_ERROR; unsigned long ulTicksToWait = mainCHECK_DELAY_NO_ERROR;
/* Just to remove the compiler warning about the unused parameter. */ /* Just to remove the compiler warning about the unused parameter. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise the variable used to control our iteration rate prior to /* Initialise the variable used to control our iteration rate prior to
its first use. */ * its first use. */
xLastExecutionTime = xTaskGetTickCount(); xLastExecutionTime = xTaskGetTickCount();
for( ;; ) for( ; ; )
{ {
/* Wait until it is time to run the tests again. */ /* Wait until it is time to run the tests again. */
vTaskDelayUntil( &xLastExecutionTime, ulTicksToWait ); vTaskDelayUntil( &xLastExecutionTime, ulTicksToWait );
/* Has an error been found in any task? */ /* Has an error been found in any task? */
if( xAreGenericQueueTasksStillRunning() != pdTRUE ) if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{ {
/* Reduce the time between cycles of this task - which has the /* Reduce the time between cycles of this task - which has the
effect of increasing the rate at which the 'check' LED toggles to * effect of increasing the rate at which the 'check' LED toggles to
indicate the existence of an error to an observer. */ * indicate the existence of an error to an observer. */
ulTicksToWait = mainCHECK_DELAY_ERROR; ulTicksToWait = mainCHECK_DELAY_ERROR;
} }
else if( xAreQueuePeekTasksStillRunning() != pdTRUE ) else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{ {
ulTicksToWait = mainCHECK_DELAY_ERROR; ulTicksToWait = mainCHECK_DELAY_ERROR;
} }
else if( xAreBlockingQueuesStillRunning() != pdTRUE ) else if( xAreBlockingQueuesStillRunning() != pdTRUE )
{ {
ulTicksToWait = mainCHECK_DELAY_ERROR; ulTicksToWait = mainCHECK_DELAY_ERROR;
} }
else if( xAreSemaphoreTasksStillRunning() != pdTRUE ) else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{ {
ulTicksToWait = mainCHECK_DELAY_ERROR; ulTicksToWait = mainCHECK_DELAY_ERROR;
} }
else if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{ {
ulTicksToWait = mainCHECK_DELAY_ERROR; ulTicksToWait = mainCHECK_DELAY_ERROR;
} }
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{ {
ulTicksToWait = mainCHECK_DELAY_ERROR; ulTicksToWait = mainCHECK_DELAY_ERROR;
} }
vParTestToggleLED( mainCHECK_LED ); vParTestToggleLED( mainCHECK_LED );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Described at the top of this file. */ /* Described at the top of this file. */
static void prvUSARTEchoTask( void *pvParameters ) static void prvUSARTEchoTask( void * pvParameters )
{ {
signed char cChar; signed char cChar;
/* String declared static to ensure it does not end up on the stack, no matter /* String declared static to ensure it does not end up on the stack, no matter
what the optimisation level. */ * what the optimisation level. */
static const char *pcLongishString = static const char * pcLongishString =
"ABBA was a Swedish pop music group formed in Stockholm in 1972, consisting of Anni-Frid Frida Lyngstad, " "ABBA was a Swedish pop music group formed in Stockholm in 1972, consisting of Anni-Frid Frida Lyngstad, "
"Bjrn Ulvaeus, Benny Andersson and Agnetha Fltskog. Throughout the band's existence, Fltskog and Ulvaeus " "Bjrn Ulvaeus, Benny Andersson and Agnetha Fltskog. Throughout the band's existence, Fltskog and Ulvaeus "
"were a married couple, as were Lyngstad and Andersson - although both couples later divorced. They became one " "were a married couple, as were Lyngstad and Andersson - although both couples later divorced. They became one "
"of the most commercially successful acts in the history of popular music, and they topped the charts worldwide " "of the most commercially successful acts in the history of popular music, and they topped the charts worldwide "
"from 1972 to 1983. ABBA gained international popularity employing catchy song hooks, simple lyrics, sound " "from 1972 to 1983. ABBA gained international popularity employing catchy song hooks, simple lyrics, sound "
"effects (reverb, phasing) and a Wall of Sound achieved by overdubbing the female singers' voices in multiple " "effects (reverb, phasing) and a Wall of Sound achieved by overdubbing the female singers' voices in multiple "
"harmonies. As their popularity grew, they were sought after to tour Europe, Australia, and North America, drawing " "harmonies. As their popularity grew, they were sought after to tour Europe, Australia, and North America, drawing "
"crowds of ardent fans, notably in Australia. Touring became a contentious issue, being particularly cumbersome for " "crowds of ardent fans, notably in Australia. Touring became a contentious issue, being particularly cumbersome for "
"Fltskog, but they continued to release studio albums to widespread commercial success. At the height of their " "Fltskog, but they continued to release studio albums to widespread commercial success. At the height of their "
"popularity, however, both relationships began suffering strain that led ultimately to the collapse of first the " "popularity, however, both relationships began suffering strain that led ultimately to the collapse of first the "
"Ulvaeus-Fltskog marriage (in 1979) and then of the Andersson-Lyngstad marriage in 1981. In the late 1970s and early " "Ulvaeus-Fltskog marriage (in 1979) and then of the Andersson-Lyngstad marriage in 1981. In the late 1970s and early "
"1980s these relationship changes began manifesting in the group's music, as they produced more thoughtful, " "1980s these relationship changes began manifesting in the group's music, as they produced more thoughtful, "
"introspective lyrics with different compositions."; "introspective lyrics with different compositions.";
/* Just to avoid compiler warnings. */ /* Just to avoid compiler warnings. */
( void ) pvParameters; ( void ) pvParameters;
/* Initialise COM0, which is USART1 according to the STM32 libraries. */ /* Initialise COM0, which is USART1 according to the STM32 libraries. */
lCOMPortInit( mainCOM0, mainBAUD_RATE ); lCOMPortInit( mainCOM0, mainBAUD_RATE );
/* Try sending out a string all in one go, as a very basic test of the /* Try sending out a string all in one go, as a very basic test of the
lSerialPutString() function. */ * lSerialPutString() function. */
lSerialPutString( mainCOM0, pcLongishString, strlen( pcLongishString ) ); lSerialPutString( mainCOM0, pcLongishString, strlen( pcLongishString ) );
for( ;; ) for( ; ; )
{ {
/* Block to wait for a character to be received on COM0. */ /* Block to wait for a character to be received on COM0. */
xSerialGetChar( mainCOM0, &cChar, portMAX_DELAY ); xSerialGetChar( mainCOM0, &cChar, portMAX_DELAY );
/* Write the received character back to COM0. */ /* Write the received character back to COM0. */
xSerialPutChar( mainCOM0, cChar, 0 ); xSerialPutChar( mainCOM0, cChar, 0 );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupHardware( void ) static void prvSetupHardware( void )
{ {
/* RCC system reset(for debug purpose). */ /* RCC system reset(for debug purpose). */
RCC_DeInit (); RCC_DeInit();
/* Enable HSE. */ /* Enable HSE. */
RCC_HSEConfig( RCC_HSE_ON ); RCC_HSEConfig( RCC_HSE_ON );
/* Wait till HSE is ready. */ /* Wait till HSE is ready. */
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); while( RCC_GetFlagStatus( RCC_FLAG_HSERDY ) == RESET )
{
}
/* HCLK = SYSCLK. */ /* HCLK = SYSCLK. */
RCC_HCLKConfig( RCC_SYSCLK_Div1 ); RCC_HCLKConfig( RCC_SYSCLK_Div1 );
/* PCLK2 = HCLK. */ /* PCLK2 = HCLK. */
RCC_PCLK2Config( RCC_HCLK_Div1 ); RCC_PCLK2Config( RCC_HCLK_Div1 );
/* PCLK1 = HCLK/2. */ /* PCLK1 = HCLK/2. */
RCC_PCLK1Config( RCC_HCLK_Div2 ); RCC_PCLK1Config( RCC_HCLK_Div2 );
/* ADCCLK = PCLK2/4. */ /* ADCCLK = PCLK2/4. */
RCC_ADCCLKConfig( RCC_PCLK2_Div4 ); RCC_ADCCLKConfig( RCC_PCLK2_Div4 );
/* Flash 2 wait state. */ /* Flash 2 wait state. */
*( volatile unsigned long * )0x40022000 = 0x01; *( volatile unsigned long * ) 0x40022000 = 0x01;
/* PLLCLK = 8MHz * 9 = 72 MHz */ /* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_9 ); RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_9 );
/* Enable PLL. */ /* Enable PLL. */
RCC_PLLCmd( ENABLE ); RCC_PLLCmd( ENABLE );
/* Wait till PLL is ready. */ /* Wait till PLL is ready. */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY ) == RESET )
{
}
/* Select PLL as system clock source. */ /* Select PLL as system clock source. */
RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK); RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );
/* Wait till PLL is used as system clock source. */ /* Wait till PLL is used as system clock source. */
while (RCC_GetSYSCLKSource() != 0x08); while( RCC_GetSYSCLKSource() != 0x08 )
{
}
/* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */ /* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
| RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE ); | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE );
/* Set the Vector Table base address at 0x08000000. */ /* Set the Vector Table base address at 0x08000000. */
NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0 ); NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0 );
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
/* Configure HCLK clock as SysTick clock source. */ /* Configure HCLK clock as SysTick clock source. */
SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK ); SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK );
/* Initialise the IO used for the LED outputs. */ /* Initialise the IO used for the LED outputs. */
vParTestInitialise(); vParTestInitialise();
/* SPI2 Periph clock enable */ /* SPI2 Periph clock enable */
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE ); RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{ {
/* This function will get called if a task overflows its stack. If the /* This function will get called if a task overflows its stack. If the
parameters are corrupt then inspect pxCurrentTCB to find which was the * parameters are corrupt then inspect pxCurrentTCB to find which was the
offending task. */ * offending task. */
( void ) pxTask; ( void ) pxTask;
( void ) pcTaskName; ( void ) pcTaskName;
for( ;; ); for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void assert_failed( unsigned char *pucFile, unsigned long ulLine ) void assert_failed( unsigned char * pucFile,
unsigned long ulLine )
{ {
( void ) pucFile; ( void ) pucFile;
( void ) ulLine; ( void ) ulLine;
for( ;; ); for( ; ; )
{
}
} }

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