/* * FreeRTOS V202212.00 * 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 * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * https://www.FreeRTOS.org * https://github.com/FreeRTOS * */ /****************************************************************************** * This project provides two demo applications. A simple blinky style project * that demonstrates low power tickless functionality, and a more comprehensive * test and demo application. The configCREATE_LOW_POWER_DEMO setting, which is * defined in FreeRTOSConfig.h, is used to select between the two. The simply * blinky low power demo is implemented and described in main_low_power.c. The * more comprehensive test and demo application is implemented and described in * main_full.c. * * This file implements the code that is not demo specific, including the * hardware setup and standard FreeRTOS hook functions. * * ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON * THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO * APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT! * */ /* Scheduler include files. */ #include "FreeRTOS.h" #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 /*-----------------------------------------------------------*/ /* * Configure the hardware as necessary to run this demo. */ 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 ) extern void main_low_power( void ); #else 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 ); #endif /* #if configCREATE_LOW_POWER_DEMO == 1 */ /* Prototypes for the standard FreeRTOS callback/hook functions implemented * within this file. */ void vApplicationMallocFailedHook( void ); void vApplicationIdleHook( void ); 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). */ volatile uint32_t ulLED = 0; /*-----------------------------------------------------------*/ int main( void ) { /* 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 /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ static void prvSetupHardware( void ) { /* 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; /* 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; } /*-----------------------------------------------------------*/ 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. */ /* Force an assert. */ configASSERT( ( volatile void * ) NULL ); } /*-----------------------------------------------------------*/ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char * pcTaskName ) { ( void ) pcTaskName; ( void ) pxTask; /* Run time stack overflow checking is performed if * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook * function is called if a stack overflow is detected. */ /* Force an assert. */ configASSERT( ( volatile void * ) NULL ); } /*-----------------------------------------------------------*/ void vApplicationIdleHook( void ) { 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(); /* 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 } /*-----------------------------------------------------------*/ /* 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 ) { /* 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 ]; /* 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 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 ) { /* 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 ]; /* 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 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; }