Fix formatting in kernel demo application files (#1148)

* Fix formatting in kernel demo application files

* Fix header check fail in the demo files

* Add ignored patterns in core header check file

* Fix formatting

* Update vApplicationStackOverflowHook for AVR_ATMega4809_MPLAB.X/main.c

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

* Update vApplicationStackOverflowHook for AVR_ATMega4809_MPLAB.X/main.c

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

* Update vApplicationStackOverflowHook for AVR_Dx_IAR/main.c

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

* Update vApplicationStackOverflowHook for AVR_Dx_IAR/main.c

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

* Update vApplicationStackOverflowHook for AVR_Dx_MPLAB.X/main.c

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

* Update vApplicationMallocFailedHook for AVR_Dx_MPLAB.X/main.c

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

* Fix formatting AVR32_UC3

---------

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/*
* 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
* 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.
The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used.
*/
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* The processor MUST be in supervisor mode when vTaskStartScheduler is
* called. The demo applications included in the FreeRTOS.org download switch
* to supervisor mode prior to main being called. If you are not using one of
* these demo application projects then ensure Supervisor mode is used.
*/
/*
* Creates all the demo application tasks, then starts the scheduler. The WEB
@ -70,29 +70,29 @@
#include "USB/USBSample.h"
/* Priorities for the demo application tasks. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainUSB_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainUSB_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* Constants required by the 'Check' task. */
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
#define mainCHECK_TASK_LED ( 3 )
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
#define mainCHECK_TASK_LED ( 3 )
/* Constants for the ComTest tasks. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 )
#define mainCOM_TEST_LED ( 4 ) /* Off the board. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 )
#define mainCOM_TEST_LED ( 4 ) /* Off the board. */
/*
* The task that executes at the highest priority and calls
* prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file.
*/
static void vErrorChecks( void *pvParameters );
static void vErrorChecks( void * pvParameters );
/*
* Configure the processor for use with the Atmel demo board. Setup is minimal
@ -115,132 +115,129 @@ static long prvCheckOtherTasksAreStillRunning( void );
*/
void main( void )
{
/* Setup any hardware that has not already been configured by the low
level init routines. */
prvSetupHardware();
/* Setup any hardware that has not already been configured by the low
* level init routines. */
prvSetupHardware();
/* Initialise the LED outputs for use by the demo application tasks. */
vParTestInitialise();
/* Initialise the LED outputs for use by the demo application tasks. */
vParTestInitialise();
/* Start all the standard demo application tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartDynamicPriorityTasks();
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
/* Start all the standard demo application tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartDynamicPriorityTasks();
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 );
/* 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 check task - which is defined in this file. */
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.
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();
vTaskStartScheduler();
/* We should never get here as control is now taken by the scheduler. */
return;
/* We should never get here as control is now taken by the scheduler. */
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
/* When using the JTAG debugger the hardware is not always initialised to
the correct default state. This line just ensures that this does not
cause all interrupts to be masked at the start. */
AT91C_BASE_AIC->AIC_EOICR = 0;
/* When using the JTAG debugger the hardware is not always initialised to
* the correct default state. This line just ensures that this does not
* cause all interrupts to be masked at the start. */
AT91C_BASE_AIC->AIC_EOICR = 0;
/* Most setup is performed by the low level init function called from the
startup asm file. */
/* 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
well as the UART Tx line. */
AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK );
/* Configure the PIO Lines corresponding to LED1 to LED4 to be outputs as
* well as the UART Tx line. */
AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK );
/* Enable the peripheral clock. */
AT91F_PMC_EnablePeriphClock( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA );
/* 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. */
( void ) pvParameters;
/* The parameters are not used in this task. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase. */
/* Cycle for ever, delaying then checking all the other tasks are still
* operating without error. If an error is detected then the delay period
* is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
* the on board LED flash rate will increase. */
for( ;; )
{
/* Delay until it is time to execute again. */
vTaskDelay( xDelayPeriod );
for( ; ; )
{
/* Delay until it is time to execute again. */
vTaskDelay( xDelayPeriod );
/* Check all the standard demo application tasks are executing without
error. */
if( prvCheckOtherTasksAreStillRunning() != 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
* error. */
if( prvCheckOtherTasksAreStillRunning() != pdPASS )
{
/* An error has been detected in one of the tasks - flash faster. */
xDelayPeriod = mainERROR_FLASH_PERIOD;
}
vParTestToggleLED( mainCHECK_TASK_LED );
}
vParTestToggleLED( mainCHECK_TASK_LED );
}
}
/*-----------------------------------------------------------*/
static long prvCheckOtherTasksAreStillRunning( void )
{
long lReturn = ( long ) pdPASS;
long lReturn = ( long ) pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected
an error. */
/* Check all the demo tasks (other than the flash tasks) to ensure
* that they are all still running, and that none of them have detected
* an error. */
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
lReturn = ( long ) pdFAIL;
}
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
lReturn = ( long ) pdFAIL;
}
if( xArePollingQueuesStillRunning() != pdTRUE )
{
lReturn = ( long ) pdFAIL;
}
if( xArePollingQueuesStillRunning() != pdTRUE )
{
lReturn = ( long ) pdFAIL;
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
lReturn = ( long ) pdFAIL;
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
lReturn = ( long ) pdFAIL;
}
if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
lReturn = ( long ) pdFAIL;
}
if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
lReturn = ( long ) pdFAIL;
}
if( xAreComTestTasksStillRunning() != pdTRUE )
{
lReturn = ( long ) pdFAIL;
}
if( xAreComTestTasksStillRunning() != pdTRUE )
{
lReturn = ( long ) pdFAIL;
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
lReturn = ( long ) pdFAIL;
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
lReturn = ( long ) pdFAIL;
}
return lReturn;
return lReturn;
}
/*-----------------------------------------------------------*/

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/*
* 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
* 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.
The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used.
*/
* NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
* The processor MUST be in supervisor mode when vTaskStartScheduler is
* called. The demo applications included in the FreeRTOS.org download switch
* to supervisor mode prior to main being called. If you are not using one of
* these demo application projects then ensure Supervisor mode is used.
*/
/*
@ -71,31 +71,31 @@
/*-----------------------------------------------------------*/
/* Constants to setup I/O and processor. */
#define mainTX_ENABLE ( ( unsigned long ) 0x00010000 ) /* UART1. */
#define mainRX_ENABLE ( ( unsigned long ) 0x00040000 ) /* UART1. */
#define mainBUS_CLK_FULL ( ( unsigned char ) 0x01 )
#define mainLED_TO_OUTPUT ( ( unsigned long ) 0xff0000 )
#define mainTX_ENABLE ( ( unsigned long ) 0x00010000 ) /* UART1. */
#define mainRX_ENABLE ( ( unsigned long ) 0x00040000 ) /* UART1. */
#define mainBUS_CLK_FULL ( ( unsigned char ) 0x01 )
#define mainLED_TO_OUTPUT ( ( unsigned long ) 0xff0000 )
/* Constants for the ComTest demo application tasks. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 )
#define mainCOM_TEST_LED ( 3 )
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 115200 )
#define mainCOM_TEST_LED ( 3 )
/* Priorities for the demo application tasks. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
/* Constants used by the "check" task. As described at the head of this file
the check task toggles an LED. The rate at which the LED flashes is used to
indicate whether an error has been detected or not. If the LED toggles every
3 seconds then no errors have been detected. If the rate increases to 500ms
then an error has been detected in at least one of the demo application tasks. */
#define mainCHECK_LED ( 7 )
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
* the check task toggles an LED. The rate at which the LED flashes is used to
* indicate whether an error has been detected or not. If the LED toggles every
* 3 seconds then no errors have been detected. If the rate increases to 500ms
* then an error has been detected in at least one of the demo application tasks. */
#define mainCHECK_LED ( 7 )
#define mainNO_ERROR_FLASH_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainERROR_FLASH_PERIOD ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
/*-----------------------------------------------------------*/
@ -110,7 +110,7 @@ static long prvCheckOtherTasksAreStillRunning( void );
* prvCheckOtherTasksAreStillRunning(). See the description at the top
* of the file.
*/
static void vErrorChecks( void *pvParameters );
static void vErrorChecks( void * pvParameters );
/*
* Configure the processor for use with the Keil demo board. This is very
@ -129,121 +129,121 @@ static void prvSetupHardware( void );
*/
int main( void )
{
/* Setup the hardware for use with the Keil demo board. */
prvSetupHardware();
/* Setup the hardware for use with the Keil demo board. */
prvSetupHardware();
/* Start the demo/test application tasks. */
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartDynamicPriorityTasks();
/* Start the demo/test application tasks. */
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartDynamicPriorityTasks();
/* Start the check task - which is defined in this file. This is the task
that periodically checks to see that all the other tasks are executing
without error. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Start the check task - which is defined in this file. This is the task
* that periodically checks to see that all the other tasks are executing
* without error. */
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.
The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used here. */
vTaskStartScheduler();
/* Should never reach here! If you do then there was not enough heap
available for the idle task to be created. */
for( ;; );
/* 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. */
( void ) pvParameters;
/* Parameters are not used. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. If an error is detected then the delay period
is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
the on board LED flash rate will increase.
/* Cycle for ever, delaying then checking all the other tasks are still
* operating without error. If an error is detected then the delay period
* is decreased from mainNO_ERROR_FLASH_PERIOD to mainERROR_FLASH_PERIOD so
* the on board LED flash rate will increase.
*
* 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( ;; )
{
/* 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 );
if( prvCheckOtherTasksAreStillRunning() != pdPASS )
{
/* An error has been detected in one of the tasks - flash faster. */
xDelayPeriod = mainERROR_FLASH_PERIOD;
}
if( prvCheckOtherTasksAreStillRunning() != pdPASS )
{
/* 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 );
}
/* Toggle the LED before going back to wait for the next cycle. */
vParTestToggleLED( mainCHECK_LED );
}
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
/* Perform the hardware setup required. This is minimal as most of the
setup is managed by the settings in the project file. */
/* Perform the hardware setup required. This is minimal as most of the
* setup is managed by the settings in the project file. */
/* Configure the UART1 pins. All other pins remain at their default of 0. */
PINSEL0 |= mainTX_ENABLE;
PINSEL0 |= mainRX_ENABLE;
/* Configure the UART1 pins. All other pins remain at their default of 0. */
PINSEL0 |= mainTX_ENABLE;
PINSEL0 |= mainRX_ENABLE;
/* LED pins need to be output. */
IODIR1 = mainLED_TO_OUTPUT;
/* LED pins need to be output. */
IODIR1 = mainLED_TO_OUTPUT;
/* Setup the peripheral bus to be the same as the PLL output. */
VPBDIV = mainBUS_CLK_FULL;
/* Setup the peripheral bus to be the same as the PLL output. */
VPBDIV = mainBUS_CLK_FULL;
}
/*-----------------------------------------------------------*/
static long prvCheckOtherTasksAreStillRunning( void )
{
long lReturn = pdPASS;
long lReturn = pdPASS;
/* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none of them have detected
an error. */
if( xAreComTestTasksStillRunning() != pdPASS )
{
lReturn = pdFAIL;
}
/* Check all the demo tasks (other than the flash tasks) to ensure
* that they are all still running, and that none of them have detected
* an error. */
if( xAreComTestTasksStillRunning() != pdPASS )
{
lReturn = pdFAIL;
}
if( xArePollingQueuesStillRunning() != pdTRUE )
{
lReturn = pdFAIL;
}
if( xArePollingQueuesStillRunning() != pdTRUE )
{
lReturn = pdFAIL;
}
if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
lReturn = pdFAIL;
}
if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
lReturn = pdFAIL;
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
lReturn = pdFAIL;
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
lReturn = pdFAIL;
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
lReturn = pdFAIL;
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
lReturn = pdFAIL;
}
return lReturn;
return lReturn;
}
/*-----------------------------------------------------------*/

View file

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

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in
@ -26,7 +26,7 @@
#include "FreeRTOS.h"
#include "semphr.h"
#define isrCLEAR_EINT_1 2
#define isrCLEAR_EINT_1 2
/*
* Interrupt routine that simply wakes vButtonHandlerTask on each interrupt
@ -35,23 +35,23 @@
* the work. This work should not be done in the wrapper itself unless
* you are absolutely sure that no stack space is used.
*/
void vButtonISRWrapper( void ) __attribute__ ((naked));
void vButtonHandler( void ) __attribute__ ((noinline));
void vButtonISRWrapper( void ) __attribute__( ( naked ) );
void vButtonHandler( void ) __attribute__( ( noinline ) );
void vButtonHandler( void )
{
extern SemaphoreHandle_t xButtonSemaphore;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
extern SemaphoreHandle_t xButtonSemaphore;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );
xSemaphoreGiveFromISR( xButtonSemaphore, &xHigherPriorityTaskWoken );
if( xHigherPriorityTaskWoken )
{
/* We have woken a task. Calling "yield from ISR" here will ensure
the interrupt returns to the woken task if it has a priority higher
than the interrupted task. */
portYIELD_FROM_ISR();
}
if( xHigherPriorityTaskWoken )
{
/* We have woken a task. Calling "yield from ISR" here will ensure
* the interrupt returns to the woken task if it has a priority higher
* than the interrupted task. */
portYIELD_FROM_ISR();
}
EXTINT = isrCLEAR_EINT_1;
VICVectAddr = 0;
@ -60,17 +60,14 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
void vButtonISRWrapper( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* Call the handler to do the work. This must be a separate function to
the wrapper to ensure the correct stack frame is set up. */
__asm volatile( "bl vButtonHandler" );
/* Call the handler to do the work. This must be a separate function to
* the wrapper to ensure the correct stack frame is set up. */
__asm volatile ( "bl vButtonHandler" );
/* Restore the context of whichever task is going to run once the interrupt
completes. */
portRESTORE_CONTEXT();
/* Restore the context of whichever task is going to run once the interrupt
* completes. */
portRESTORE_CONTEXT();
}

View file

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

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/*
* 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
* 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.*/
/*! \file *********************************************************************
/* \file *********************************************************************
*
* \brief FreeRTOS Real Time Kernel example.
*
@ -79,56 +80,48 @@
#include "death.h"
#include "flop.h"
/*! \name Priority definitions for most of the tasks in the demo application.
/* Priority definitions for most of the tasks in the demo application.
* Some tasks just use the idle priority.
*/
//! @{
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
//! @}
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
//! Baud rate used by the serial port tasks.
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 57600 )
/* Baud rate used by the serial port tasks. */
#define mainCOM_TEST_BAUD_RATE ( ( unsigned long ) 57600 )
//! LED used by the serial port tasks. This is toggled on each character Tx,
//! and mainCOM_TEST_LED + 1 is toggled on each character Rx.
#define mainCOM_TEST_LED ( 3 )
/* LED used by the serial port tasks. This is toggled on each character Tx,
* and mainCOM_TEST_LED + 1 is toggled on each character Rx. */
#define mainCOM_TEST_LED ( 3 )
//! LED that is toggled by the check task. The check task periodically checks
//! that all the other tasks are operating without error. If no errors are found
//! the LED is toggled. If an error is found at any time the LED toggles faster.
#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.
/* LED that is toggled by the check task. The check task periodically checks
* that all the other tasks are operating without error. If no errors are found
* the LED is toggled. If an error is found at any time the LED toggles faster.
*/
//! @{
#define mainCOUNT_INITIAL_VALUE ( ( unsigned long ) 0 )
#define mainNO_TASK ( 0 )
//! @}
#define mainCHECK_TASK_LED ( 6 )
/*! \name 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 )
//! @}
/* 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 )
/* 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
* of the file.
*/
static void vErrorChecks( void *pvParameters );
static void vErrorChecks( void * pvParameters );
/*
* Checks that all the demo application tasks are still executing without error
@ -148,7 +141,7 @@ static portBASE_TYPE prvCheckOtherTasksAreStillRunning( void );
/*
* A task that exercises the memory allocator.
*/
static void vMemCheckTask( void *pvParameters );
static void vMemCheckTask( void * pvParameters );
/*
* Called by the check task following the detection of an error to set the
@ -160,305 +153,305 @@ static void prvIndicateError( void );
int main( void )
{
/* Start the crystal oscillator 0 and switch the main clock to it. */
pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP);
/* Start the crystal oscillator 0 and switch the main clock to it. */
pm_switch_to_osc0( &AVR32_PM, FOSC0, OSC0_STARTUP );
portDBG_TRACE("Starting the FreeRTOS AVR32 UC3 Demo...");
portDBG_TRACE( "Starting the FreeRTOS AVR32 UC3 Demo..." );
/* Setup the LED's for output. */
vParTestInitialise();
/* Setup the LED's for output. */
vParTestInitialise();
/* Start the standard demo tasks. See the WEB documentation for more
information. */
vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartMathTasks( tskIDLE_PRIORITY );
/* Start the standard demo tasks. See the WEB documentation for more
* information. */
vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartIntegerMathTasks( tskIDLE_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartDynamicPriorityTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartMathTasks( tskIDLE_PRIORITY );
/* Start the demo tasks defined within this file, specifically the check
task as described at the top of this file. */
xTaskCreate(
vErrorChecks
, "ErrCheck"
, configMINIMAL_STACK_SIZE
, NULL
, mainCHECK_TASK_PRIORITY
, NULL );
/* Start the demo tasks defined within this file, specifically the check
* task as described at the top of this file. */
xTaskCreate(
vErrorChecks
, "ErrCheck"
, configMINIMAL_STACK_SIZE
, NULL
, mainCHECK_TASK_PRIORITY
, NULL );
/* Start the scheduler. */
vTaskStartScheduler();
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle
task. */
/* Will only get here if there was insufficient memory to create the idle
* 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;
unsigned long ulMemCheckTaskRunningCount;
TaskHandle_t xCreatedTask;
portBASE_TYPE bSuicidalTask = 0;
static volatile unsigned long ulDummyVariable = 3UL;
unsigned long ulMemCheckTaskRunningCount;
TaskHandle_t xCreatedTask;
portBASE_TYPE bSuicidalTask = 0;
/* The parameters are not used. Prevent compiler warnings. */
( void ) pvParameters;
/* The parameters are not used. Prevent compiler warnings. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error.
/* Cycle for ever, delaying then checking all the other tasks are still
* operating without error.
*
* In addition to the standard tests the memory allocator is tested through
* the dynamic creation and deletion of a task each cycle. Each time the
* task is created memory must be allocated for its stack. When the task is
* deleted this memory is returned to the heap. If the task cannot be created
* then it is likely that the memory allocation failed. */
In addition to the standard tests the memory allocator is tested through
the dynamic creation and deletion of a task each cycle. Each time the
task is created memory must be allocated for its stack. When the task is
deleted this memory is returned to the heap. If the task cannot be created
then it is likely that the memory allocation failed. */
for( ; ; )
{
/* Do this only once. */
if( bSuicidalTask == 0 )
{
bSuicidalTask++;
for( ;; )
{
/* Do this only once. */
if( bSuicidalTask == 0 )
{
bSuicidalTask++;
/* This task has to be created last as it keeps account of the number of
* tasks it expects to see running. However its implementation expects
* to be called before vTaskStartScheduler(). We're in the case here where
* vTaskStartScheduler() has already been called (thus the hidden IDLE task
* has already been spawned). Since vCreateSuicidalTask() supposes that the
* IDLE task isn't included in the response from uxTaskGetNumberOfTasks(),
* let the MEM_CHECK task play that role. => this is why vCreateSuicidalTasks()
* is not called as the last task. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
}
/* This task has to be created last as it keeps account of the number of
tasks it expects to see running. However its implementation expects
to be called before vTaskStartScheduler(). We're in the case here where
vTaskStartScheduler() has already been called (thus the hidden IDLE task
has already been spawned). Since vCreateSuicidalTask() supposes that the
IDLE task isn't included in the response from uxTaskGetNumberOfTasks(),
let the MEM_CHECK task play that role. => this is why vCreateSuicidalTasks()
is not called as the last task. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
}
/* Reset xCreatedTask. This is modified by the task about to be
* created so we can tell if it is executing correctly or not. */
xCreatedTask = mainNO_TASK;
/* Reset xCreatedTask. This is modified by the task about to be
created so we can tell if it is executing correctly or not. */
xCreatedTask = mainNO_TASK;
/* Dynamically create a task - passing ulMemCheckTaskRunningCount as a
* parameter. */
ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;
/* Dynamically create a task - passing ulMemCheckTaskRunningCount as a
parameter. */
ulMemCheckTaskRunningCount = mainCOUNT_INITIAL_VALUE;
if( xTaskCreate( vMemCheckTask,
"MEM_CHECK",
configMINIMAL_STACK_SIZE,
( void * ) &ulMemCheckTaskRunningCount,
tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )
{
/* Could not create the task - we have probably run out of heap.
* Don't go any further and flash the LED faster to provide visual
* feedback of the error. */
prvIndicateError();
}
if( xTaskCreate( vMemCheckTask,
"MEM_CHECK",
configMINIMAL_STACK_SIZE,
( void * ) &ulMemCheckTaskRunningCount,
tskIDLE_PRIORITY, &xCreatedTask ) != pdPASS )
{
/* Could not create the task - we have probably run out of heap.
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. */
vTaskDelay( mainCHECK_PERIOD );
/* Delay until it is time to execute again. */
vTaskDelay( mainCHECK_PERIOD );
/* Delete the dynamically created task. */
if( xCreatedTask != mainNO_TASK )
{
vTaskDelete( xCreatedTask );
}
/* Delete the dynamically created task. */
if( xCreatedTask != mainNO_TASK )
{
vTaskDelete( xCreatedTask );
}
/* Perform a bit of 32bit maths to ensure the registers used by the
* integer tasks get some exercise. The result here is not important -
* see the demo application documentation for more info. */
ulDummyVariable *= 3;
/* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */
ulDummyVariable *= 3;
/* Check all other tasks are still operating without error.
Check that vMemCheckTask did increment the counter. */
if( ( prvCheckOtherTasksAreStillRunning() != pdFALSE )
|| ( ulMemCheckTaskRunningCount == mainCOUNT_INITIAL_VALUE ) )
{
/* An error has occurred in one of the tasks.
Don't go any further and flash the LED faster to give visual
feedback of the error. */
prvIndicateError();
}
else
{
/* Toggle the LED if everything is okay. */
vParTestToggleLED( mainCHECK_TASK_LED );
}
}
/* Check all other tasks are still operating without error.
* Check that vMemCheckTask did increment the counter. */
if( ( prvCheckOtherTasksAreStillRunning() != pdFALSE ) ||
( ulMemCheckTaskRunningCount == mainCOUNT_INITIAL_VALUE ) )
{
/* An error has occurred in one of the tasks.
* Don't go any further and flash the LED faster to give visual
* feedback of the error. */
prvIndicateError();
}
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 xErrorHasOccurred = pdFALSE;
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreComTestTasksStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreComTestTasksStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xArePollingQueuesStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xArePollingQueuesStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreMathsTaskStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreMathsTaskStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xIsCreateTaskStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xIsCreateTaskStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
return ( xErrorHasOccurred );
return( xErrorHasOccurred );
}
/*-----------------------------------------------------------*/
/*!
* \brief Dynamically created and deleted during each cycle of the vErrorChecks()
* task. This is done to check the operation of the memory allocator.
/*
* @brief Dynamically created and deleted during each cycle of the vErrorChecks()
* task. This is done to check the operation of the memory allocator.
* See the top of vErrorChecks for more details.
*
* \param *pvParameters Parameters for the task (can be of any kind)
* @param pvParameters Parameters for the task (can be of any kind)
*/
static void vMemCheckTask( void *pvParameters )
static void vMemCheckTask( void * pvParameters )
{
unsigned long *pulMemCheckTaskRunningCounter;
void *pvMem1, *pvMem2, *pvMem3;
static long lErrorOccurred = pdFALSE;
unsigned long * pulMemCheckTaskRunningCounter;
void * pvMem1, * pvMem2, * pvMem3;
static long lErrorOccurred = pdFALSE;
/* This task is dynamically created then deleted during each cycle of the
vErrorChecks task to check the operation of the memory allocator. Each time
the task is created memory is allocated for the stack and TCB. Each time
the task is deleted this memory is returned to the heap. This task itself
exercises the allocator by allocating and freeing blocks.
/* This task is dynamically created then deleted during each cycle of the
* vErrorChecks task to check the operation of the memory allocator. Each time
* the task is created memory is allocated for the stack and TCB. Each time
* the task is deleted this memory is returned to the heap. This task itself
* exercises the allocator by allocating and freeing blocks.
*
* The task executes at the idle priority so does not require a delay.
*
* pulMemCheckTaskRunningCounter is incremented each cycle to indicate to the
* vErrorChecks() task that this task is still executing without error. */
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
vErrorChecks() task that this task is still executing without error. */
for( ; ; )
{
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( ;; )
{
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;
}
vTaskSuspendAll();
{
pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );
/* 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. */
if( pvMem1 == NULL )
{
lErrorOccurred = pdTRUE;
}
else
{
memset( pvMem1, 0xaa, mainMEM_CHECK_SIZE_1 );
vPortFree( pvMem1 );
}
}
xTaskResumeAll();
vTaskSuspendAll();
{
pvMem1 = pvPortMalloc( mainMEM_CHECK_SIZE_1 );
/* Again - with a different size block. */
vTaskSuspendAll();
{
pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 );
if( pvMem1 == NULL )
{
lErrorOccurred = pdTRUE;
}
else
{
memset( pvMem1, 0xaa, mainMEM_CHECK_SIZE_1 );
vPortFree( pvMem1 );
}
}
xTaskResumeAll();
if( pvMem2 == NULL )
{
lErrorOccurred = pdTRUE;
}
else
{
memset( pvMem2, 0xaa, mainMEM_CHECK_SIZE_2 );
vPortFree( pvMem2 );
}
}
xTaskResumeAll();
/* Again - with a different size block. */
vTaskSuspendAll();
{
pvMem2 = pvPortMalloc( mainMEM_CHECK_SIZE_2 );
/* Again - with a different size block. */
vTaskSuspendAll();
{
pvMem3 = pvPortMalloc( mainMEM_CHECK_SIZE_3 );
if( pvMem2 == NULL )
{
lErrorOccurred = pdTRUE;
}
else
{
memset( pvMem2, 0xaa, mainMEM_CHECK_SIZE_2 );
vPortFree( pvMem2 );
}
}
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();
}
if( pvMem3 == NULL )
{
lErrorOccurred = pdTRUE;
}
else
{
memset( pvMem3, 0xaa, mainMEM_CHECK_SIZE_3 );
vPortFree( pvMem3 );
}
}
xTaskResumeAll();
}
}
/*-----------------------------------------------------------*/
static void prvIndicateError( void )
{
/* The check task has found an error in one of the other tasks.
Set the LEDs to a state that indicates this. */
vParTestSetLED(mainERROR_LED,pdTRUE);
/* The check task has found an error in one of the other tasks.
* Set the LEDs to a state that indicates this. */
vParTestSetLED( mainERROR_LED, pdTRUE );
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
* 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
* this software and associated documentation files (the "Software"), to deal in
@ -44,45 +44,45 @@
*/
/*
Changes from V1.2.0
+ Changed the baud rate for the serial test from 19200 to 57600.
Changes from V1.2.3
+ The integer and comtest tasks are now used when the cooperative scheduler
is being used. Previously they were only used with the preemptive
scheduler.
Changes from V1.2.5
+ Set the baud rate to 38400. This has a smaller error percentage with an
8MHz clock (according to the manual).
Changes from V2.0.0
+ Delay periods are now specified using variables and constants of
TickType_t rather than unsigned long.
Changes from V2.2.0
+ File can now be built using either the IAR or WinAVR compiler.
Changes from V2.6.1
+ The IAR and WinAVR AVR ports are now maintained separately.
Changes from V4.0.5
+ Modified to demonstrate the use of co-routines.
*/
* Changes from V1.2.0
*
+ Changed the baud rate for the serial test from 19200 to 57600.
+
+ Changes from V1.2.3
+
+ The integer and comtest tasks are now used when the cooperative scheduler
+ is being used. Previously they were only used with the preemptive
+ scheduler.
+
+ Changes from V1.2.5
+
+ Set the baud rate to 38400. This has a smaller error percentage with an
+ 8MHz clock (according to the manual).
+
+ Changes from V2.0.0
+
+ Delay periods are now specified using variables and constants of
+ TickType_t rather than unsigned long.
+
+ Changes from V2.2.0
+
+ File can now be built using either the IAR or WinAVR compiler.
+
+ Changes from V2.6.1
+
+ The IAR and WinAVR AVR ports are now maintained separately.
+
+ Changes from V4.0.5
+
+ Modified to demonstrate the use of co-routines.
*/
#include <stdlib.h>
#include <string.h>
#ifdef GCC_MEGA_AVR
/* EEPROM routines used only with the WinAVR compiler. */
#include <avr/eeprom.h>
/* EEPROM routines used only with the WinAVR compiler. */
#include <avr/eeprom.h>
#endif
/* Scheduler include files. */
@ -101,39 +101,39 @@ Changes from V4.0.5
#include "regtest.h"
/* Priority definitions for most of the tasks in the demo application. Some
tasks just use the idle priority. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
* tasks just use the idle priority. */
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
/* 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,
and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 4 )
* and mainCOM_TEST_LED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED ( 4 )
/* LED that is toggled by the check task. The check task periodically checks
that all the other tasks are operating without error. If no errors are found
the LED is toggled. If an error is found at any time the LED is never toggles
again. */
#define mainCHECK_TASK_LED ( 7 )
* that all the other tasks are operating without error. If no errors are found
* the LED is toggled. If an error is found at any time the LED is never toggles
* again. */
#define mainCHECK_TASK_LED ( 7 )
/* The period between executions of the check task. */
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
#define mainCHECK_PERIOD ( ( TickType_t ) 3000 / portTICK_PERIOD_MS )
/* An address in the EEPROM used to count resets. This is used to check that
the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 )
* the demo application is not unexpectedly resetting. */
#define mainRESET_COUNT_ADDRESS ( ( void * ) 0x50 )
/* The number of coroutines to create. */
#define mainNUM_FLASH_COROUTINES ( 3 )
#define mainNUM_FLASH_COROUTINES ( 3 )
/*
* 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.
@ -154,120 +154,121 @@ void vApplicationIdleHook( void );
short main( void )
{
prvIncrementResetCount();
prvIncrementResetCount();
/* Setup the LED's for output. */
vParTestInitialise();
/* Setup the LED's for output. */
vParTestInitialise();
/* Create the standard demo tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartRegTestTasks();
/* Create the standard demo tasks. */
vStartIntegerMathTasks( tskIDLE_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartRegTestTasks();
/* Create the tasks defined within this file. */
xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* 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. */
vStartFlashCoRoutines( mainNUM_FLASH_COROUTINES );
/* 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();
/* 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;
return 0;
}
/*-----------------------------------------------------------*/
static void vErrorChecks( void *pvParameters )
static void vErrorChecks( void * pvParameters )
{
static volatile unsigned long ulDummyVariable = 3UL;
static volatile unsigned long ulDummyVariable = 3UL;
/* The parameters are not used. */
( void ) pvParameters;
/* The parameters are not used. */
( void ) pvParameters;
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */
for( ;; )
{
vTaskDelay( mainCHECK_PERIOD );
/* Cycle for ever, delaying then checking all the other tasks are still
* operating without error. */
for( ; ; )
{
vTaskDelay( mainCHECK_PERIOD );
/* Perform a bit of 32bit maths to ensure the registers used by the
integer tasks get some exercise. The result here is not important -
see the demo application documentation for more info. */
ulDummyVariable *= 3;
/* Perform a bit of 32bit maths to ensure the registers used by the
* integer tasks get some exercise. The result here is not important -
* see the demo application documentation for more info. */
ulDummyVariable *= 3;
prvCheckOtherTasksAreStillRunning();
}
prvCheckOtherTasksAreStillRunning();
}
}
/*-----------------------------------------------------------*/
static void prvCheckOtherTasksAreStillRunning( void )
{
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
static portBASE_TYPE xErrorHasOccurred = pdFALSE;
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreComTestTasksStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreComTestTasksStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xArePollingQueuesStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xArePollingQueuesStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreRegTestTasksStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xAreRegTestTasksStillRunning() != pdTRUE )
{
xErrorHasOccurred = pdTRUE;
}
if( xErrorHasOccurred == pdFALSE )
{
/* Toggle the LED if everything is okay so we know if an error occurs even if not
using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED );
}
if( xErrorHasOccurred == pdFALSE )
{
/* Toggle the LED if everything is okay so we know if an error occurs even if not
* using console IO. */
vParTestToggleLED( mainCHECK_TASK_LED );
}
}
/*-----------------------------------------------------------*/
static void prvIncrementResetCount( void )
{
unsigned char ucCount;
const unsigned char ucReadBit = ( unsigned char ) 0x01;
const unsigned char ucWrite1 = ( unsigned char ) 0x04;
const unsigned char ucWrite2 = ( unsigned char ) 0x02;
unsigned char ucCount;
const unsigned char ucReadBit = ( unsigned char ) 0x01;
const unsigned char ucWrite1 = ( unsigned char ) 0x04;
const unsigned char ucWrite2 = ( unsigned char ) 0x02;
/* Increment the EEPROM value at 0x00.
/* Increment the EEPROM value at 0x00.
*
* Setup the EEPROM address. */
EEARH = 0x00;
EEARL = 0x00;
Setup the EEPROM address. */
EEARH = 0x00;
EEARL = 0x00;
/* Set the read enable bit. */
EECR |= ucReadBit;
/* Set the read enable bit. */
EECR |= ucReadBit;
/* Wait for the read. */
while( EECR & ucReadBit )
{
}
/* Wait for the read. */
while( EECR & ucReadBit );
/* The byte is ready. */
ucCount = EEDR;
/* The byte is ready. */
ucCount = EEDR;
/* Increment the reset count, then write the byte back. */
ucCount++;
EEDR = ucCount;
EECR = ucWrite1;
EECR = ( ucWrite1 | ucWrite2 );
/* Increment the reset count, then write the byte back. */
ucCount++;
EEDR = ucCount;
EECR = ucWrite1;
EECR = ( ucWrite1 | ucWrite2 );
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
vCoRoutineSchedule();
vCoRoutineSchedule();
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/*
* 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
* 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
tick hook). */
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
* tick hook). */
#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
/* The LCD task uses the sprintf function so requires a little more stack too. */
#define mainLCD_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 )
#define mainLCD_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 )
/* Task priorities. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainINTEGER_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
time. */
#define mainLCD_QUEUE_SIZE ( 3 )
* time. */
#define mainLCD_QUEUE_SIZE ( 3 )
/* Constants used by the comtest tasks. There isn't a spare LED so an invalid
LED is specified. */
#define mainBAUD_RATE ( 115200 )
#define mainCOM_TEST_LED ( 10 )
* LED is specified. */
#define mainBAUD_RATE ( 115200 )
#define mainCOM_TEST_LED ( 10 )
/*-----------------------------------------------------------*/
@ -118,13 +118,14 @@ static void prvSetupHardware( void );
* The LCD gatekeeper task. Tasks wishing to write to the LCD do not access
* the LCD directly, but instead send the message to the LCD gatekeeper task.
*/
static void prvLCDTask( void *pvParameters );
static void prvLCDTask( void * pvParameters );
/*
* Hook functions that can get called by the kernel. The 'check' functionality
* is implemented within the tick hook.
*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName );
/*
* The tick hook function as described in the comments at the top of this file.
@ -144,149 +145,154 @@ static QueueHandle_t xLCDQueue;
int main( void )
{
/* Prepare the hardware. */
prvSetupHardware();
/* Prepare the hardware. */
prvSetupHardware();
/* Create the queue used by the LCD task. Messages for display on the LCD
are received via this queue. */
xLCDQueue = xQueueCreate( mainLCD_QUEUE_SIZE, sizeof( xLCDMessage ) );
/* Create the queue used by the LCD task. Messages for display on the LCD
* are received via this queue. */
xLCDQueue = xQueueCreate( mainLCD_QUEUE_SIZE, sizeof( xLCDMessage ) );
/* Start the standard demo tasks. These do nothing other than test the
port and provide some APU usage examples. */
/* Start the standard demo tasks. These do nothing other than test the
* port and provide some APU usage examples. */
vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
vStartRecursiveMutexTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartQueuePeekTasks();
vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainBAUD_RATE, mainCOM_TEST_LED );
vStartRecursiveMutexTasks();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vCreateBlockTimeTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartQueuePeekTasks();
vStartLEDFlashTasks( mainLED_TASK_PRIORITY );
vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainBAUD_RATE, mainCOM_TEST_LED );
/* Start the tasks defined within this file/specific to this demo. */
xTaskCreate( prvLCDTask, "LCD", mainLCD_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
/* Start the tasks defined within this file/specific to this demo. */
xTaskCreate( prvLCDTask, "LCD", mainLCD_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
/* Start the scheduler. */
vTaskStartScheduler();
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle
task. */
return 0;
* task. */
return 0;
}
/*-----------------------------------------------------------*/
void prvSetupHardware( void )
{
/* Initialise the port used for the LED outputs. */
vParTestInitialise();
/* Initialise the port used for the LED outputs. */
vParTestInitialise();
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
static xLCDMessage xMessage = { "PASS" };
static unsigned long ulTicksSinceLastDisplay = 0;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
static xLCDMessage xMessage = { "PASS" };
static unsigned long ulTicksSinceLastDisplay = 0;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* Called from every tick interrupt. Have enough ticks passed to make it
time to perform our health status check again? */
ulTicksSinceLastDisplay++;
if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
{
ulTicksSinceLastDisplay = 0;
/* Called from every tick interrupt. Have enough ticks passed to make it
* time to perform our health status check again? */
ulTicksSinceLastDisplay++;
/* Has an error been found in any task? */
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
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";
}
if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
{
ulTicksSinceLastDisplay = 0;
/* Send the message to the LCD gatekeeper for display. */
xHigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR( xLCDQueue, &xMessage, &xHigherPriorityTaskWoken );
}
/* Has an error been found in any task? */
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
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 ) pcTaskName;
( void ) pxTask;
( void ) pcTaskName;
/* If the parameters have been corrupted then inspect pxCurrentTCB to
identify which task has overflowed its stack. */
for( ;; );
/* If the parameters have been corrupted then inspect pxCurrentTCB to
* identify which task has overflowed its stack. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvLCDTask( void *pvParameters )
static void prvLCDTask( void * pvParameters )
{
xLCDMessage xMessage;
unsigned long ulY = 0;
const unsigned long ulX = 5;
const unsigned long ulMaxY = 250, ulYIncrement = 22, ulWidth = 250, ulHeight = 20;;
xLCDMessage xMessage;
unsigned long ulY = 0;
const unsigned long ulX = 5;
const unsigned long ulMaxY = 250, ulYIncrement = 22, ulWidth = 250, ulHeight = 20;
/* Initialize LCD. */
LCDD_Initialize();
LCDD_Start();
LCDD_Fill( ( void * ) BOARD_LCD_BASE, COLOR_WHITE );
LCDD_DrawString( ( void * ) BOARD_LCD_BASE, 1, ulY + 3, " www.FreeRTOS.org", COLOR_BLACK );
LCDD_Fill( ( void * ) BOARD_LCD_BASE, COLOR_WHITE );
LCDD_DrawString( ( void * ) BOARD_LCD_BASE, 1, ulY + 3, " www.FreeRTOS.org", COLOR_BLACK );
for( ;; )
{
/* Wait for a message from the check function (which is executed in
the tick hook). */
xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY );
for( ; ; )
{
/* Wait for a message from the check function (which is executed in
* the tick hook). */
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 );
/* Increment to the next drawing position. */
ulY += ulYIncrement;
/* Increment to the next drawing position. */
ulY += ulYIncrement;
/* Have the Y position moved past the end of the LCD? */
if( ulY >= ulMaxY )
{
ulY = 0;
}
/* Have the Y position moved past the end of the LCD? */
if( ulY >= ulMaxY )
{
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 );
/* Write the message. */
/* Write the message. */
LCDD_DrawString( ( void * ) BOARD_LCD_BASE, ulX, ulY + 3, xMessage.pcMessage, COLOR_BLACK );
}
}
}

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in
@ -95,43 +95,43 @@
#include "DriverLib.h"
/* 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. */
#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. */
#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. */
#define mainLCD_QUEUE_LEN ( 3 )
#define mainLCD_QUEUE_LEN ( 3 )
/* The priority of the co-routine used to initiate the transmission of the
string on UART 0. */
#define mainTX_CO_ROUTINE_PRIORITY ( 1 )
#define mainADC_CO_ROUTINE_PRIORITY ( 2 )
* string on UART 0. */
#define mainTX_CO_ROUTINE_PRIORITY ( 1 )
#define mainADC_CO_ROUTINE_PRIORITY ( 2 )
/* Only one of each co-routine is created so its index is not important. */
#define mainTX_CO_ROUTINE_INDEX ( 0 )
#define mainADC_CO_ROUTINE_INDEX ( 0 )
#define mainTX_CO_ROUTINE_INDEX ( 0 )
#define mainADC_CO_ROUTINE_INDEX ( 0 )
/* The task priorities. */
#define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainMSG_TASK_PRIORITY ( mainLCD_TASK_PRIORITY - 1 )
#define mainCOMMS_RX_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainMSG_TASK_PRIORITY ( mainLCD_TASK_PRIORITY - 1 )
#define mainCOMMS_RX_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The LCD had two rows. */
#define mainTOP_ROW 0
#define mainBOTTOM_ROW 1
#define mainTOP_ROW 0
#define mainBOTTOM_ROW 1
/* 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
co-routines. */
#define mainFAIL_LED ( 7 )
* co-routines. */
#define mainFAIL_LED ( 7 )
/*-----------------------------------------------------------*/
@ -149,7 +149,8 @@ static void prvLCDMessageTask( void * pvParameters );
* The co-routine that reads the ADC and sends messages for display on the
* bottom row of the LCD.
*/
static void prvADCCoRoutine( CoRoutineHandle_t xHandle, unsigned portBASE_TYPE uxIndex );
static void prvADCCoRoutine( CoRoutineHandle_t xHandle,
unsigned portBASE_TYPE uxIndex );
/*
* Function to simply set a known value into the general purpose registers
@ -166,7 +167,8 @@ void vSetErrorLED( void );
/*
* Thread safe write to the PDC.
*/
static void prvPDCWrite( char cAddress, char cData );
static void prvPDCWrite( char cAddress,
char cData );
/*
* Sets up the hardware used by the demo.
@ -179,12 +181,12 @@ static void prvSetupHardware( void );
/* The structure that is passed on the LCD message queue. */
typedef struct
{
char **ppcMessageToDisplay; /*<< Points to a char* pointing to the message to display. */
portBASE_TYPE xRow; /*<< The row on which the message should be displayed. */
char ** ppcMessageToDisplay; /*<< Points to a char* pointing to the message to display. */
portBASE_TYPE xRow; /*<< The row on which the message should be displayed. */
} xLCDMessage;
/* Error flag set to pdFAIL if an error is encountered in the tasks/co-routines
defined within this file. */
* defined within this file. */
unsigned portBASE_TYPE uxErrorStatus = pdPASS;
/* The queue used to transmit messages to the LCD task. */
@ -197,242 +199,250 @@ static QueueHandle_t xLCDQueue;
*/
void main( void )
{
/* Create the queue used by tasks wanting to write to the LCD. */
xLCDQueue = xQueueCreate( mainLCD_QUEUE_LEN, sizeof( xLCDMessage ) );
/* Create the queue used by tasks wanting to write to the LCD. */
xLCDQueue = xQueueCreate( mainLCD_QUEUE_LEN, sizeof( xLCDMessage ) );
/* Setup the ports used by the demo and the clock. */
prvSetupHardware();
/* Setup the ports used by the demo and the clock. */
prvSetupHardware();
/* Create the co-routines that flash the LED's. */
vStartFlashCoRoutines( mainNUM_FLASH_CO_ROUTINES );
/* Create the co-routines that flash the LED's. */
vStartFlashCoRoutines( mainNUM_FLASH_CO_ROUTINES );
/* Create the co-routine that initiates the transmission of characters
on the UART and the task that receives them, as described at the top of
this file. */
xCoRoutineCreate( vSerialTxCoRoutine, mainTX_CO_ROUTINE_PRIORITY, mainTX_CO_ROUTINE_INDEX );
xTaskCreate( vCommsRxTask, "CMS", configMINIMAL_STACK_SIZE, NULL, mainCOMMS_RX_TASK_PRIORITY, NULL );
/* Create the co-routine that initiates the transmission of characters
* on the UART and the task that receives them, as described at the top of
* this file. */
xCoRoutineCreate( vSerialTxCoRoutine, mainTX_CO_ROUTINE_PRIORITY, mainTX_CO_ROUTINE_INDEX );
xTaskCreate( vCommsRxTask, "CMS", configMINIMAL_STACK_SIZE, NULL, mainCOMMS_RX_TASK_PRIORITY, NULL );
/* Create the task that waits for messages to display on the LCD, plus the
task and co-routine that send messages for display (as described at the top
of this file. */
xTaskCreate( prvLCDTask, "LCD", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainLCD_TASK_PRIORITY, NULL );
xTaskCreate( prvLCDMessageTask, "MSG", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainMSG_TASK_PRIORITY, NULL );
xCoRoutineCreate( prvADCCoRoutine, mainADC_CO_ROUTINE_PRIORITY, mainADC_CO_ROUTINE_INDEX );
/* Create the task that waits for messages to display on the LCD, plus the
* task and co-routine that send messages for display (as described at the top
* of this file. */
xTaskCreate( prvLCDTask, "LCD", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainLCD_TASK_PRIORITY, NULL );
xTaskCreate( prvLCDMessageTask, "MSG", configMINIMAL_STACK_SIZE, ( void * ) &xLCDQueue, mainMSG_TASK_PRIORITY, NULL );
xCoRoutineCreate( prvADCCoRoutine, mainADC_CO_ROUTINE_PRIORITY, mainADC_CO_ROUTINE_INDEX );
/* Start the scheduler running the tasks and co-routines just created. */
vTaskStartScheduler();
/* Start the scheduler running the tasks and co-routines just created. */
vTaskStartScheduler();
/* Should not get here unless we did not have enough memory to start the
scheduler. */
for( ;; );
/* Should not get here unless we did not have enough memory to start the
* scheduler. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvLCDMessageTask( void * pvParameters )
{
/* The strings that are written to the LCD. */
char *pcStringsToDisplay[] = {
"IAR ",
"Stellaris ",
"Demo ",
"www.FreeRTOS.org",
""
};
char * pcStringsToDisplay[] =
{
"IAR ",
"Stellaris ",
"Demo ",
"www.FreeRTOS.org",
""
};
QueueHandle_t *pxLCDQueue;
xLCDMessage xMessageToSend;
portBASE_TYPE xIndex = 0;
QueueHandle_t * pxLCDQueue;
xLCDMessage xMessageToSend;
portBASE_TYPE xIndex = 0;
/* To test the parameter passing mechanism, the queue on which messages are
posted is passed in as a parameter even though it is available as a file
scope variable anyway. */
pxLCDQueue = ( QueueHandle_t * ) pvParameters;
/* To test the parameter passing mechanism, the queue on which messages are
* posted is passed in as a parameter even though it is available as a file
* scope variable anyway. */
pxLCDQueue = ( QueueHandle_t * ) pvParameters;
for( ;; )
{
/* Wait until it is time to move onto the next string. */
vTaskDelay( mainSTRING_WRITE_DELAY );
for( ; ; )
{
/* Wait until it is time to move onto the next string. */
vTaskDelay( mainSTRING_WRITE_DELAY );
/* Create the message object to send to the LCD task. */
xMessageToSend.ppcMessageToDisplay = &pcStringsToDisplay[ xIndex ];
xMessageToSend.xRow = mainTOP_ROW;
/* 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;
}
/* 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;
/* Move onto the next message, wrapping when necessary. */
xIndex++;
/* Delay longer before going back to the start of the messages. */
vTaskDelay( mainSTRING_WRITE_DELAY * 2 );
}
}
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 )
{
unsigned portBASE_TYPE uxIndex;
QueueHandle_t *pxLCDQueue;
xLCDMessage xReceivedMessage;
char *pcString;
const unsigned char ucCFGData[] = {
0x30, /* Set data bus to 8-bits. */
0x30,
0x30,
0x3C, /* Number of lines/font. */
0x08, /* Display off. */
0x01, /* Display clear. */
0x06, /* Entry mode [cursor dir][shift]. */
0x0C /* Display on [display on][curson on][blinking on]. */
};
unsigned portBASE_TYPE uxIndex;
QueueHandle_t * pxLCDQueue;
xLCDMessage xReceivedMessage;
char * pcString;
const unsigned char ucCFGData[] =
{
0x30, /* Set data bus to 8-bits. */
0x30,
0x30,
0x3C, /* Number of lines/font. */
0x08, /* Display off. */
0x01, /* Display clear. */
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
received is passed in as a parameter even though it is available as a file
scope variable anyway. */
pxLCDQueue = ( QueueHandle_t * ) pvParameters;
/* To test the parameter passing mechanism, the queue on which messages are
* received is passed in as a parameter even though it is available as a file
* scope variable anyway. */
pxLCDQueue = ( QueueHandle_t * ) pvParameters;
/* Configure the LCD. */
uxIndex = 0;
while( uxIndex < sizeof( ucCFGData ) )
{
prvPDCWrite( PDC_LCD_CSR, ucCFGData[ uxIndex ] );
uxIndex++;
vTaskDelay( mainCHAR_WRITE_DELAY );
}
/* Configure the LCD. */
uxIndex = 0;
/* Turn the LCD Backlight on. */
prvPDCWrite( PDC_CSR, 0x01 );
while( uxIndex < sizeof( ucCFGData ) )
{
prvPDCWrite( PDC_LCD_CSR, ucCFGData[ uxIndex ] );
uxIndex++;
vTaskDelay( mainCHAR_WRITE_DELAY );
}
/* Clear display. */
vTaskDelay( mainCHAR_WRITE_DELAY );
prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR );
/* Turn the LCD Backlight on. */
prvPDCWrite( PDC_CSR, 0x01 );
uxIndex = 0;
for( ;; )
{
/* 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 );
/* Clear display. */
vTaskDelay( mainCHAR_WRITE_DELAY );
prvPDCWrite( PDC_LCD_CSR, LCD_CLEAR );
/* Where is the string we are going to display? */
pcString = *xReceivedMessage.ppcMessageToDisplay;
uxIndex = 0;
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++;
}
}
}
for( ; ; )
{
/* 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? */
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 char cMessageBuffer[ mainMAX_ADC_STRING_LEN ];
static char *pcMessage;
static xLCDMessage xMessageToSend;
static unsigned long ulADCValue;
static char cMessageBuffer[ mainMAX_ADC_STRING_LEN ];
static char * pcMessage;
static xLCDMessage xMessageToSend;
/* Co-routines MUST start with a call to crSTART(). */
crSTART( xHandle );
/* Co-routines MUST start with a call to crSTART(). */
crSTART( xHandle );
for( ;; )
{
/* Start an ADC conversion. */
ADCProcessorTrigger( ADC_BASE, 0 );
for( ; ; )
{
/* Start an ADC conversion. */
ADCProcessorTrigger( ADC_BASE, 0 );
/* Simply delay - when we unblock the result should be available */
crDELAY( xHandle, mainADC_DELAY );
/* Simply delay - when we unblock the result should be available */
crDELAY( xHandle, mainADC_DELAY );
/* Get the ADC result. */
ADCSequenceDataGet( ADC_BASE, 0, &ulADCValue );
/* Get the ADC result. */
ADCSequenceDataGet( ADC_BASE, 0, &ulADCValue );
/* Create a string with the result. */
sprintf( cMessageBuffer, "ADC = %d ", ulADCValue );
pcMessage = cMessageBuffer;
/* Create a string with the result. */
sprintf( cMessageBuffer, "ADC = %d ", ulADCValue );
pcMessage = cMessageBuffer;
/* Configure the message we are going to send for display. */
xMessageToSend.ppcMessageToDisplay = ( char** ) &pcMessage;
xMessageToSend.xRow = mainBOTTOM_ROW;
/* Configure the message we are going to send for display. */
xMessageToSend.ppcMessageToDisplay = ( char ** ) &pcMessage;
xMessageToSend.xRow = mainBOTTOM_ROW;
/* Send the string to the LCD task for display. We are sending
on a task queue so do not have the option to block. */
if( !xQueueSend( xLCDQueue, ( void * ) &xMessageToSend, 0 ) )
{
uxErrorStatus = pdFAIL;
}
}
/* 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();
/* Co-routines MUST end with a call to crEND(). */
crEND();
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
/* Setup the PLL. */
SysCtlClockSet( SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ );
/* Setup the PLL. */
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();
/* 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. */
SysCtlPeripheralEnable( SYSCTL_PERIPH_ADC );
ADCSequenceConfigure( ADC_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);
/* 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 );
ADCSequenceEnable( ADC_BASE, 0 );
}
/*-----------------------------------------------------------*/
static void prvPDCWrite( char cAddress, char cData )
static void prvPDCWrite( char cAddress,
char cData )
{
vTaskSuspendAll();
{
PDCWrite( cAddress, cData );
}
xTaskResumeAll();
vTaskSuspendAll();
{
PDCWrite( cAddress, cData );
}
xTaskResumeAll();
}
/*-----------------------------------------------------------*/
void vSetErrorLED( void )
{
vParTestSetLED( mainFAIL_LED, pdTRUE );
vParTestSetLED( mainFAIL_LED, pdTRUE );
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* The co-routines are executed in the idle task using the idle task
hook. */
for( ;; )
{
/* Schedule the co-routines. */
vCoRoutineSchedule();
/* The co-routines are executed in the idle task using the idle task
* hook. */
for( ; ; )
{
/* Schedule the co-routines. */
vCoRoutineSchedule();
/* Run the register check function between each co-routine. */
vSetAndCheckRegisters();
/* Run the register check function between each co-routine. */
vSetAndCheckRegisters();
/* See if the comms task and co-routine has found any errors. */
if( uxGetCommsStatus() != pdPASS )
{
vParTestSetLED( mainFAIL_LED, pdTRUE );
}
}
/* See if the comms task and co-routine has found any errors. */
if( uxGetCommsStatus() != pdPASS )
{
vParTestSetLED( mainFAIL_LED, pdTRUE );
}
}
}
/*-----------------------------------------------------------*/

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in

View file

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

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in
@ -85,24 +85,24 @@
#include "QueueOverwrite.h"
/* Priorities for the demo application tasks. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* 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
have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
* have been reported by any of the standard demo tasks. ms are converted to the
* equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
* reported in one of the standard demo tasks. ms are converted to the equivalent
* in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/*-----------------------------------------------------------*/
@ -116,144 +116,147 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer );
* of the FPU registers, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly file.
*/
extern void vRegTest1Task( void *pvParameters );
extern void vRegTest2Task( void *pvParameters );
extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void * pvParameters );
/*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */
* register check tasks to the check software timer. If the variables keep
* incrementing, then the register check tasks have not discovered any errors. If
* a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/
void main_full( void )
{
TimerHandle_t xCheckTimer = NULL;
TimerHandle_t xCheckTimer = NULL;
/* Start all the other standard demo/test tasks. The have not particular
functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */
vStartQueueSetTasks();
vStartQueueOverwriteTask( tskIDLE_PRIORITY );
vStartDynamicPriorityTasks();
vCreateBlockTimeTasks();
vStartGenericQueueTasks( tskIDLE_PRIORITY );
vStartRecursiveMutexTasks();
vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* Start all the other standard demo/test tasks. The have not particular
* functionality, but do demonstrate how to use the FreeRTOS API and test the
* kernel port. */
vStartQueueSetTasks();
vStartQueueOverwriteTask( tskIDLE_PRIORITY );
vStartDynamicPriorityTasks();
vCreateBlockTimeTasks();
vStartGenericQueueTasks( tskIDLE_PRIORITY );
vStartRecursiveMutexTasks();
vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* Create the register check tasks, as described at the top of this
file */
xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the register check tasks, as described at the top of this
* file */
xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( 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. */
);
/* Create the software timer that performs the 'check' functionality,
* as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( 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. */
);
if( xCheckTimer != NULL )
{
xTimerStart( xCheckTimer, mainDONT_BLOCK );
}
if( xCheckTimer != NULL )
{
xTimerStart( xCheckTimer, mainDONT_BLOCK );
}
/* Start the scheduler. */
vTaskStartScheduler();
/* Start the scheduler. */
vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site
for more details. */
for( ;; );
/* If all is well, the scheduler will now be running, and the following line
* will never be reached. If the following line does execute, then there was
* insufficient FreeRTOS heap memory available for the idle and/or timer tasks
* to be created. See the memory management section on the FreeRTOS web site
* for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
/* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */
/* 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. */
if( xAreMathsTaskStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreMathsTaskStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreQueueSetTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreQueueSetTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xIsQueueOverwriteTaskStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xIsQueueOverwriteTaskStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
/* Check that the register test 1 task is still running. */
if( ulLastRegTest1Value == ulRegTest1LoopCounter )
{
ulErrorFound = pdTRUE;
}
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 1 task is still running. */
if( ulLastRegTest1Value == ulRegTest1LoopCounter )
{
ulErrorFound = pdTRUE;
}
/* Check that the register test 2 task is still running. */
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
{
ulErrorFound = pdTRUE;
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */
configTOGGLE_LED();
/* Check that the register test 2 task is still running. */
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
{
ulErrorFound = pdTRUE;
}
/* 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;
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* 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 );
}
}
/* Toggle the check LED to give an indication of the system status. If
* the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
* everything is ok. A faster toggle indicates an error. */
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
* 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
* this software and associated documentation files (the "Software"), to deal in
@ -55,8 +55,8 @@
#include "task.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
* or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/
@ -76,111 +76,118 @@ extern void main_full( void );
int main( void )
{
/* Prepare the hardware to run this demo. */
prvSetupHardware();
/* Prepare the hardware to run this demo. */
prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
{
main_blinky();
}
#else
{
main_full();
}
#endif
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
* of this file. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
{
main_blinky();
}
#else
{
main_full();
}
#endif
return 0;
return 0;
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
configCONFIGURE_LED();
configCONFIGURE_LED();
/* Ensure all priority bits are assigned as preemption priority bits. */
NVIC_SetPriorityGrouping( 0 );
/* Ensure all priority bits are assigned as preemption priority bits. */
NVIC_SetPriorityGrouping( 0 );
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
/* vApplicationMallocFailedHook() will only be called if
* configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
* function that will get called if a call to pvPortMalloc() fails.
* pvPortMalloc() is called internally by the kernel whenever a task, queue,
* timer or semaphore is created. It is also called by various parts of the
* demo application. If heap_1.c or heap_2.c are used, then the size of the
* heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
* FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
* to query the size of free heap space that remains (although it does not
* provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS();
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
* to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
* task. It is essential that code added to this hook function never attempts
* to block in any way (for example, call xQueueReceive() with a block time
* specified, or call vTaskDelay()). If the application makes use of the
* vTaskDelete() API function (as this demo application does) then it is also
* important that vApplicationIdleHook() is permitted to return to its calling
* function, because it is the responsibility of the idle task to clean up
* memory allocated by the kernel to any task that has since been deleted. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
/* Run time stack overflow checking is performed if
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
/* This function will be called by each tick interrupt if
* configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
* added here, but the tick hook is called from an interrupt context, so
* code must not attempt to block, and only the interrupt safe FreeRTOS API
* functions can be used (those that end in FromISR()). */
}
/*-----------------------------------------------------------*/
#ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void)
{
long lHigherPriorityTaskWoken = pdFALSE;
void Dummy_IRQHandler( void )
{
long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit();
/* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* This interrupt does nothing more than demonstrate how to synchronise a
* task with an interrupt. A semaphore is used for this purpose. Note
* lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* If there was a task that was blocked on the semaphore, and giving the
semaphore caused the task to unblock, and the unblocked task has a priority
higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
/* If there was a task that was blocked on the semaphore, and giving the
* semaphore caused the task to unblock, and the unblocked task has a priority
* higher than the current Running state task (the task that this interrupt
* interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
* internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
* portEND_SWITCHING_ISR() macro will result in a context switch being pended to
* ensure this interrupt returns directly to the unblocked, higher priority,
* task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
#endif /* JUST_AN_EXAMPLE_ISR */

View file

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

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in
@ -83,24 +83,24 @@
#include "recmutex.h"
/* Priorities for the demo application tasks. */
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* 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
have been reported by any of the standard demo tasks. ms are converted to the
equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
* have been reported by any of the standard demo tasks. ms are converted to the
* equivalent in ticks using the portTICK_PERIOD_MS constant. */
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, if an error has been
reported in one of the standard demo tasks. ms are converted to the equivalent
in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
* reported in one of the standard demo tasks. ms are converted to the equivalent
* in ticks using the portTICK_PERIOD_MS constant. */
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_PERIOD_MS )
/*-----------------------------------------------------------*/
@ -114,139 +114,142 @@ static void prvCheckTimerCallback( TimerHandle_t xTimer );
* of the FPU registers, as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly file.
*/
extern void vRegTest1Task( void *pvParameters );
extern void vRegTest2Task( void *pvParameters );
extern void vRegTest1Task( void * pvParameters );
extern void vRegTest2Task( void * pvParameters );
/*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the
register check tasks to the check software timer. If the variables keep
incrementing, then the register check tasks have not discovered any errors. If
a variable stops incrementing, then an error has been found. */
* register check tasks to the check software timer. If the variables keep
* incrementing, then the register check tasks have not discovered any errors. If
* a variable stops incrementing, then an error has been found. */
volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/
void main_full( void )
{
TimerHandle_t xCheckTimer = NULL;
TimerHandle_t xCheckTimer = NULL;
/* Start all the other standard demo/test tasks. The have not particular
functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */
vStartDynamicPriorityTasks();
vCreateBlockTimeTasks();
vStartCountingSemaphoreTasks();
vStartGenericQueueTasks( tskIDLE_PRIORITY );
vStartRecursiveMutexTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* Start all the other standard demo/test tasks. The have not particular
* functionality, but do demonstrate how to use the FreeRTOS API and test the
* kernel port. */
vStartDynamicPriorityTasks();
vCreateBlockTimeTasks();
vStartCountingSemaphoreTasks();
vStartGenericQueueTasks( tskIDLE_PRIORITY );
vStartRecursiveMutexTasks();
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartMathTasks( mainFLOP_TASK_PRIORITY );
/* Create the register check tasks, as described at the top of this
file */
xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the register check tasks, as described at the top of this
* file */
xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
/* Create the software timer that performs the 'check' functionality,
as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( 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. */
);
/* Create the software timer that performs the 'check' functionality,
* as described at the top of this file. */
xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
( 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. */
);
if( xCheckTimer != NULL )
{
xTimerStart( xCheckTimer, mainDONT_BLOCK );
}
if( xCheckTimer != NULL )
{
xTimerStart( xCheckTimer, mainDONT_BLOCK );
}
/* Start the scheduler. */
vTaskStartScheduler();
/* Start the scheduler. */
vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site
for more details. */
for( ;; );
/* If all is well, the scheduler will now be running, and the following line
* will never be reached. If the following line does execute, then there was
* insufficient FreeRTOS heap memory available for the idle and/or timer tasks
* to be created. See the memory management section on the FreeRTOS web site
* for more details. */
for( ; ; )
{
}
}
/*-----------------------------------------------------------*/
static void prvCheckTimerCallback( TimerHandle_t xTimer )
{
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
static long lChangedTimerPeriodAlready = pdFALSE;
static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
unsigned long ulErrorFound = pdFALSE;
/* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */
/* 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. */
if( xAreMathsTaskStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreMathsTaskStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
ulErrorFound = pdTRUE;
}
/* Check that the register test 1 task is still running. */
if( ulLastRegTest1Value == ulRegTest1LoopCounter )
{
ulErrorFound = pdTRUE;
}
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 1 task is still running. */
if( ulLastRegTest1Value == ulRegTest1LoopCounter )
{
ulErrorFound = pdTRUE;
}
/* Check that the register test 2 task is still running. */
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
{
ulErrorFound = pdTRUE;
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Toggle the check LED to give an indication of the system status. If
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
everything is ok. A faster toggle indicates an error. */
configTOGGLE_LED();
/* Check that the register test 2 task is still running. */
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
{
ulErrorFound = pdTRUE;
}
/* 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;
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* 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 );
}
}
/* Toggle the check LED to give an indication of the system status. If
* the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
* everything is ok. A faster toggle indicates an error. */
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
* 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
* this software and associated documentation files (the "Software"), to deal in
@ -68,8 +68,8 @@
#include "QueueOverwrite.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
* or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
/*-----------------------------------------------------------*/
@ -89,128 +89,131 @@ extern void main_full( void );
int main( void )
{
/* Prepare the hardware to run this demo. */
prvSetupHardware();
/* Prepare the hardware to run this demo. */
prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
{
main_blinky();
}
#else
{
main_full();
}
#endif
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
* of this file. */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
{
main_blinky();
}
#else
{
main_full();
}
#endif
return 0;
return 0;
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
configCONFIGURE_LED();
configCONFIGURE_LED();
/* Ensure all priority bits are assigned as preemption priority bits. */
NVIC_SetPriorityGrouping( 0 );
/* Ensure all priority bits are assigned as preemption priority bits. */
NVIC_SetPriorityGrouping( 0 );
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; )
{
__asm volatile( "NOP" );
};
/* vApplicationMallocFailedHook() will only be called if
* configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
* function that will get called if a call to pvPortMalloc() fails.
* pvPortMalloc() is called internally by the kernel whenever a task, queue,
* timer or semaphore is created. It is also called by various parts of the
* demo application. If heap_1.c or heap_2.c are used, then the size of the
* heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
* FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
* to query the size of free heap space that remains (although it does not
* provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS();
for( ; ; )
{
__asm volatile ( "NOP" );
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
* to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
* task. It is essential that code added to this hook function never attempts
* to block in any way (for example, call xQueueReceive() with a block time
* specified, or call vTaskDelay()). If the application makes use of the
* vTaskDelete() API function (as this demo application does) then it is also
* important that vApplicationIdleHook() is permitted to return to its calling
* function, because it is the responsibility of the idle task to clean up
* memory allocated by the kernel to any task that has since been deleted. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
void vApplicationStackOverflowHook( TaskHandle_t pxTask,
char * pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; )
{
__asm volatile( "NOP" );
}
/* Run time stack overflow checking is performed if
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ; ; )
{
__asm volatile ( "NOP" );
}
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
/* This function will be called by each tick interrupt if
* configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
* added here, but the tick hook is called from an interrupt context, so
* code must not attempt to block, and only the interrupt safe FreeRTOS API
* functions can be used (those that end in FromISR()). */
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{
/* Write to a queue that is in use as part of the queue set demo to
demonstrate using queue sets from an ISR. */
vQueueSetAccessQueueSetFromISR();
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0
{
/* Write to a queue that is in use as part of the queue set demo to
* demonstrate using queue sets from an ISR. */
vQueueSetAccessQueueSetFromISR();
/* Test the ISR safe queue overwrite functions. */
vQueueOverwritePeriodicISRDemo();
}
#endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */
/* Test the ISR safe queue overwrite functions. */
vQueueOverwritePeriodicISRDemo();
}
#endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */
}
/*-----------------------------------------------------------*/
#ifdef JUST_AN_EXAMPLE_ISR
void Dummy_IRQHandler(void)
{
long lHigherPriorityTaskWoken = pdFALSE;
void Dummy_IRQHandler( void )
{
long lHigherPriorityTaskWoken = pdFALSE;
/* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit();
/* Clear the interrupt if necessary. */
Dummy_ClearITPendingBit();
/* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt. A semaphore is used for this purpose. Note
lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* This interrupt does nothing more than demonstrate how to synchronise a
* task with an interrupt. A semaphore is used for this purpose. Note
* lHigherPriorityTaskWoken is initialised to zero. */
xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken );
/* If there was a task that was blocked on the semaphore, and giving the
semaphore caused the task to unblock, and the unblocked task has a priority
higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority,
task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
/* If there was a task that was blocked on the semaphore, and giving the
* semaphore caused the task to unblock, and the unblocked task has a priority
* higher than the current Running state task (the task that this interrupt
* interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
* internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the
* portEND_SWITCHING_ISR() macro will result in a context switch being pended to
* ensure this interrupt returns directly to the unblocked, higher priority,
* task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
}
#endif /* JUST_AN_EXAMPLE_ISR */

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in
@ -70,8 +70,8 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask,
void vApplicationMallocFailedHook( void )
{
/* If configUSE_MALLOC_FAILED_HOOK is set to 1 then this function will
* be called automatically if a call to pvPortMalloc() fails. pvPortMalloc()
* is called automatically when a task, queue or semaphore is created. */
* be called automatically if a call to pvPortMalloc() fails. pvPortMalloc()
* is called automatically when a task, queue or semaphore is created. */
printf( "Application Malloc Failed Hook called\n" );
for( ; ; )

View file

@ -1,6 +1,6 @@
/*
* 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
* this software and associated documentation files (the "Software"), to deal in

View file

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

View file

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

View file

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

View file

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

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