From 6eb8fc5f51dadc0772e0771d19516875777bbad0 Mon Sep 17 00:00:00 2001 From: chinglee-iot <61685396+chinglee-iot@users.noreply.github.com> Date: Mon, 24 Jul 2023 21:17:17 +0800 Subject: [PATCH] Merge SMP demos from FreeRTOS-SMP-Demos (#1046) * Merge RP2040 and XMOS AICORE SMP demos to main branch from FreeRTOS-SMP-Demos * Update the common test for SMP demos * Update the kernel submodule --- FreeRTOS/Demo/Common/Minimal/BlockQ.c | 25 +- FreeRTOS/Demo/Common/Minimal/IntQueue.c | 20 +- FreeRTOS/Demo/Common/Minimal/dynamic.c | 11 +- .../CORTEX_M0+_RP2040/CMakeLists.txt | 5 +- .../OnEitherCore/FreeRTOSConfig.h | 2 +- .../CORTEX_M0+_RP2040/OnEitherCore/main.c | 2 +- .../Standard/FreeRTOSConfig.h | 2 +- .../CORTEX_M0+_RP2040/Standard/main.c | 2 +- .../CORTEX_M0+_RP2040/Standard/main.h | 4 +- .../Standard_smp/CMakeLists.txt | 73 ++ .../Standard_smp/FreeRTOSConfig.h | 138 +++ .../Standard_smp/FreeRTOS_Kernel_import.cmake | 62 ++ .../Standard_smp/IntQueueTimer.c | 102 ++ .../Standard_smp/IntQueueTimer.h | 35 + .../CORTEX_M0+_RP2040/Standard_smp/RegTest.s | 186 ++++ .../CORTEX_M0+_RP2040/Standard_smp/main.c | 223 +++++ .../CORTEX_M0+_RP2040/Standard_smp/main.h | 59 ++ .../Standard_smp/main_blinky.c | 194 ++++ .../Standard_smp/main_full.c | 481 ++++++++++ .../Standard_smp/pico_sdk_import.cmake | 62 ++ .../UsingCMSIS/FreeRTOSConfig.h | 2 +- .../XCORE.AI_xClang/.gitignore | 23 + .../XCORE.AI_xClang/README.md | 155 +++ .../XCORE.AI_xClang/RTOSDemo/.cproject | 884 ++++++++++++++++++ .../XCORE.AI_xClang/RTOSDemo/.gitignore | 3 + .../XCORE.AI_xClang/RTOSDemo/.project | 54 ++ .../XCORE.AI_xClang/RTOSDemo/Makefile | 116 +++ .../RTOSDemo/src/FreeRTOSConfig.h | 106 +++ .../src/IntQueueTimer/IntQueueTimer.c | 69 ++ .../src/IntQueueTimer/IntQueueTimer.h | 8 + .../RTOSDemo/src/XCORE-AI-EXPLORER.xn | 81 ++ .../RTOSDemo/src/config.xscope | 26 + .../XCORE.AI_xClang/RTOSDemo/src/main.xc | 51 + .../RTOSDemo/src/partest/mab_led_driver.xc | 16 + .../RTOSDemo/src/partest/partest.c | 115 +++ .../src/regtest/prvRegisterCheck_asm1.S | 104 +++ .../src/regtest/prvRegisterCheck_asm2.S | 136 +++ .../RTOSDemo/src/regtest/regtest.c | 74 ++ .../RTOSDemo/src/regtest/regtest.h | 15 + .../XCORE.AI_xClang/RTOSDemo/src/test.c | 759 +++++++++++++++ .../RTOSDemo/src/testing_main.h | 92 ++ .../lib_rtos_support/.cproject | 874 +++++++++++++++++ .../XCORE.AI_xClang/lib_rtos_support/.project | 44 + .../lib_rtos_support/api/rtos_cores.h | 54 ++ .../lib_rtos_support/api/rtos_interrupt.h | 225 +++++ .../lib_rtos_support/api/rtos_irq.h | 84 ++ .../lib_rtos_support/api/rtos_locks.h | 76 ++ .../lib_rtos_support/api/rtos_macros.h | 39 + .../lib_rtos_support/api/rtos_printf.h | 122 +++ .../lib_rtos_support/api/rtos_support.h | 22 + .../lib_rtos_support/api/rtos_time.h | 72 ++ .../lib_rtos_support/module_build_info | 13 + .../lib_rtos_support/src/rtos_cores.c | 75 ++ .../lib_rtos_support/src/rtos_interrupt.c | 14 + .../src/rtos_interrupt_impl.h | 100 ++ .../lib_rtos_support/src/rtos_irq.c | 215 +++++ .../lib_rtos_support/src/rtos_locks.c | 38 + .../lib_rtos_support/src/rtos_printf.c | 504 ++++++++++ .../lib_rtos_support/src/rtos_time.c | 49 + FreeRTOS/Source | 2 +- manifest.yml | 2 +- 61 files changed, 7180 insertions(+), 21 deletions(-) create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/CMakeLists.txt create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/FreeRTOSConfig.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/FreeRTOS_Kernel_import.cmake create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/IntQueueTimer.c create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/IntQueueTimer.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/RegTest.s create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main.c create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main_blinky.c create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main_full.c create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/pico_sdk_import.cmake create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/.gitignore create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/README.md create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/.cproject create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/.gitignore create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/.project create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/Makefile create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/FreeRTOSConfig.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/IntQueueTimer/IntQueueTimer.c create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/IntQueueTimer/IntQueueTimer.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/XCORE-AI-EXPLORER.xn create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/config.xscope create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/main.xc create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/partest/mab_led_driver.xc create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/partest/partest.c create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/prvRegisterCheck_asm1.S create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/prvRegisterCheck_asm2.S create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/regtest.c create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/regtest.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/test.c create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/testing_main.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/.cproject create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/.project create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_cores.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_interrupt.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_irq.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_locks.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_macros.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_printf.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_support.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_time.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/module_build_info create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_cores.c create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_interrupt.c create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_interrupt_impl.h create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_irq.c create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_locks.c create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_printf.c create mode 100644 FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_time.c diff --git a/FreeRTOS/Demo/Common/Minimal/BlockQ.c b/FreeRTOS/Demo/Common/Minimal/BlockQ.c index e03dd1c4a..3744e0a7c 100644 --- a/FreeRTOS/Demo/Common/Minimal/BlockQ.c +++ b/FreeRTOS/Demo/Common/Minimal/BlockQ.c @@ -61,6 +61,7 @@ #define blckqSTACK_SIZE configMINIMAL_STACK_SIZE #define blckqNUM_TASK_SETS ( 3 ) +#define blckqSHORT_DELAY ( 5 ) #if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) #error This example cannot be used if dynamic allocation is not allowed. #endif @@ -200,9 +201,18 @@ static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters ) * consumer will expect the numbers to follow in numerical order. */ ++usValue; - #if configUSE_PREEMPTION == 0 + #if ( configNUMBER_OF_CORES > 1 ) + { + if( pxQueueParameters->xBlockTime == 0 ) + { + vTaskDelay( blckqSHORT_DELAY ); + } + } + #elif configUSE_PREEMPTION == 0 + { taskYIELD(); - #endif + } + #endif /* if ( configNUMBER_OF_CORES > 1 ) */ } } } @@ -241,14 +251,21 @@ static portTASK_FUNCTION( vBlockingQueueConsumer, pvParameters ) ++usExpectedValue; } - #if configUSE_PREEMPTION == 0 + #if ( configNUMBER_OF_CORES > 1 ) + { + if( pxQueueParameters->xBlockTime == 0 ) + { + vTaskDelay( blckqSHORT_DELAY ); + } + } + #elif configUSE_PREEMPTION == 0 { if( pxQueueParameters->xBlockTime == 0 ) { taskYIELD(); } } - #endif + #endif /* if ( configNUMBER_OF_CORES > 1 ) */ } } } diff --git a/FreeRTOS/Demo/Common/Minimal/IntQueue.c b/FreeRTOS/Demo/Common/Minimal/IntQueue.c index f60ef58c3..2c0d59525 100644 --- a/FreeRTOS/Demo/Common/Minimal/IntQueue.c +++ b/FreeRTOS/Demo/Common/Minimal/IntQueue.c @@ -97,7 +97,7 @@ if( xQueueIsQueueFullFromISR( xNormallyEmptyQueue ) != pdTRUE ) \ { \ UBaseType_t uxSavedInterruptStatus; \ - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \ + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \ { \ uxValueForNormallyEmptyQueue++; \ if( xQueueSendFromISR( xNormallyEmptyQueue, ( void * ) &uxValueForNormallyEmptyQueue, &xHigherPriorityTaskWoken ) != pdPASS ) \ @@ -105,7 +105,7 @@ uxValueForNormallyEmptyQueue--; \ } \ } \ - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); \ } \ @@ -115,7 +115,7 @@ if( xQueueIsQueueFullFromISR( xNormallyFullQueue ) != pdTRUE ) \ { \ UBaseType_t uxSavedInterruptStatus; \ - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \ + uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \ { \ uxValueForNormallyFullQueue++; \ if( xQueueSendFromISR( xNormallyFullQueue, ( void * ) &uxValueForNormallyFullQueue, &xHigherPriorityTaskWoken ) != pdPASS ) \ @@ -123,7 +123,7 @@ uxValueForNormallyFullQueue--; \ } \ } \ - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); \ } \ @@ -376,7 +376,11 @@ static void prvHigherPriorityNormallyEmptyTask( void * pvParameters ) memset( ucNormallyEmptyReceivedValues, 0x00, sizeof( ucNormallyEmptyReceivedValues ) ); uxHighPriorityLoops1++; - uxValueForNormallyEmptyQueue = 0; + portENTER_CRITICAL(); + { + uxValueForNormallyEmptyQueue = 0; + } + portEXIT_CRITICAL(); /* Suspend ourselves, allowing the lower priority task to * actually receive something from the queue. Until now it @@ -528,7 +532,11 @@ static void prv1stHigherPriorityNormallyFullTask( void * pvParameters ) memset( ucNormallyFullReceivedValues, 0x00, sizeof( ucNormallyFullReceivedValues ) ); uxHighPriorityLoops2++; - uxValueForNormallyFullQueue = 0; + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue = 0; + } + portEXIT_CRITICAL(); /* Suspend ourselves, allowing the lower priority task to * actually receive something from the queue. Until now it diff --git a/FreeRTOS/Demo/Common/Minimal/dynamic.c b/FreeRTOS/Demo/Common/Minimal/dynamic.c index 6a08944d5..64cc13e82 100644 --- a/FreeRTOS/Demo/Common/Minimal/dynamic.c +++ b/FreeRTOS/Demo/Common/Minimal/dynamic.c @@ -279,7 +279,16 @@ static portTASK_FUNCTION( vCounterControlTask, pvParameters ) #if ( INCLUDE_eTaskGetState == 1 ) { - configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eReady ); + #if ( configNUMBER_OF_CORES > 1 ) + { + eTaskState eState = eTaskGetState( xContinuousIncrementHandle ); + configASSERT( ( eState == eReady ) || ( eState == eRunning ) ); + } + #else + { + configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eReady ); + } + #endif } #endif /* INCLUDE_eTaskGetState */ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/CMakeLists.txt b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/CMakeLists.txt index a50c07117..3b2e598fb 100644 --- a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/CMakeLists.txt +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/CMakeLists.txt @@ -8,6 +8,9 @@ include(pico_sdk_import.cmake) PROJECT(examples) +set( FREERTOS_KERNEL_PATH "../../../../../Source" ) + add_subdirectory(OnEitherCore) add_subdirectory(Standard) -add_subdirectory(UsingCMSIS) \ No newline at end of file +add_subdirectory(UsingCMSIS) +add_subdirectory(Standard_smp) diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/OnEitherCore/FreeRTOSConfig.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/OnEitherCore/FreeRTOSConfig.h index 25ea19de6..fdbe2eb47 100644 --- a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/OnEitherCore/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/OnEitherCore/FreeRTOSConfig.h @@ -101,7 +101,7 @@ */ /* SMP port only */ -#define configNUM_CORES 1 +#define configNUMBER_OF_CORES 1 #define configTICK_CORE 1 #define configRUN_MULTIPLE_PRIORITIES 1 diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/OnEitherCore/main.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/OnEitherCore/main.c index ff3f860a0..c356bdf78 100644 --- a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/OnEitherCore/main.c +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/OnEitherCore/main.c @@ -95,7 +95,7 @@ static volatile uint32_t ulCountOfSDKSemaphoreAcquires = 0; #include "pico/mutex.h" #include "pico/sem.h" -#if configNUM_CORES > 1 +#if ( configNUMBER_OF_CORES > 1 ) #error Require only one core configured for FreeRTOS #endif diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard/FreeRTOSConfig.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard/FreeRTOSConfig.h index e7843e291..374a5886f 100644 --- a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard/FreeRTOSConfig.h @@ -101,7 +101,7 @@ */ /* SMP port only */ -#define configNUM_CORES 2 +#define configNUMBER_OF_CORES 1 #define configTICK_CORE 0 #define configRUN_MULTIPLE_PRIORITIES 0 diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard/main.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard/main.c index 59c8c107e..37f842c9b 100644 --- a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard/main.c +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard/main.c @@ -117,7 +117,7 @@ int main( void ) rtos_name = "FreeRTOS"; #endif -#if ( portSUPPORT_SMP == 1 ) && ( configNUM_CORES == 2 ) +#if ( portSUPPORT_SMP == 1 ) && ( configNUMBER_OF_CORES == 2 ) printf("%s on both cores:\n", rtos_name); vLaunch(); #endif diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard/main.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard/main.h index a8045ba06..4d89befc7 100644 --- a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard/main.h +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard/main.h @@ -44,7 +44,7 @@ #define mainENABLE_SEMAPHORE 1 #define mainENABLE_TASK_NOTIFY 1 -#if configNUM_CORES != 2 || configRUN_MULTIPLE_PRIORITIES == 0 +#if ( configNUMBER_OF_CORES != 2 ) || ( configRUN_MULTIPLE_PRIORITIES == 0 ) /* These tests assume that a higher priority task will block a lower priority tax from running */ #define mainENABLE_BLOCK_TIME 1 @@ -56,7 +56,7 @@ #define mainENABLE_TIMER_DEMO 1 #endif -#if configNUM_CORES != 2 +#if ( configNUM_CORES != 2 ) /* This test just expects two tasks not to run concurrently */ #define mainENABLE_DYNAMIC_PRIORITY 1 #endif diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/CMakeLists.txt b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/CMakeLists.txt new file mode 100644 index 000000000..27795e972 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/CMakeLists.txt @@ -0,0 +1,73 @@ +cmake_minimum_required(VERSION 3.13) + +# Pull in SDK (must be before project) +include(pico_sdk_import.cmake) + +# Pull in FreeRTOS +include(FreeRTOS_Kernel_import.cmake) + +project(example C CXX ASM) +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) + +pico_sdk_init() + +add_executable(main_full_smp + main.c + main_full.c + IntQueueTimer.c + RegTest.s + ../../../../Common/Minimal/blocktim.c + ../../../../Common/Minimal/countsem.c + ../../../../Common/Minimal/dynamic.c + ../../../../Common/Minimal/recmutex.c + ../../../../Common/Minimal/QueueOverwrite.c + ../../../../Common/Minimal/EventGroupsDemo.c + ../../../../Common/Minimal/IntSemTest.c + ../../../../Common/Minimal/IntQueue.c + ../../../../Common/Minimal/TaskNotify.c + ../../../../Common/Minimal/TimerDemo.c + ../../../../Common/Minimal/GenQTest.c + ../../../../Common/Minimal/death.c + ../../../../Common/Minimal/semtest.c + ../../../../Common/Minimal/BlockQ.c + ../../../../Common/Minimal/flop.c + ) + +target_compile_definitions(main_full_smp PRIVATE + mainCREATE_SIMPLE_BLINKY_DEMO_ONLY=0 + ) + +target_include_directories(main_full_smp PRIVATE + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/../../../../Common/include) + +target_compile_definitions(main_full_smp PRIVATE + PICO_STDIO_STACK_BUFFER_SIZE=64 # use a small printf on stack buffer +) +target_link_libraries(main_full_smp pico_stdlib FreeRTOS-Kernel FreeRTOS-Kernel-Heap4) +pico_add_extra_outputs(main_full_smp) + +# Use USB uart +pico_enable_stdio_usb(main_full_smp 1) +pico_enable_stdio_uart(main_full_smp 1) + +add_executable(main_blinky_smp + main.c + main_blinky.c + ) + +target_compile_definitions(main_blinky_smp PRIVATE + mainCREATE_SIMPLE_BLINKY_DEMO_ONLY=1 + ) + +target_include_directories(main_blinky_smp PRIVATE + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/../../../../Common/include) + +target_link_libraries(main_blinky_smp pico_stdlib FreeRTOS-Kernel FreeRTOS-Kernel-Heap1) +pico_add_extra_outputs(main_blinky_smp) + +# Use USB uart +pico_enable_stdio_usb(main_blinky_smp 1) +pico_enable_stdio_uart(main_blinky_smp 1) diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/FreeRTOSConfig.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/FreeRTOSConfig.h new file mode 100644 index 000000000..e04111449 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/FreeRTOSConfig.h @@ -0,0 +1,138 @@ +/* + * 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 + * + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html + *----------------------------------------------------------*/ + +/* Scheduler Related */ +#define configUSE_PREEMPTION 1 +#define configUSE_TICKLESS_IDLE 0 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 1 +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMAX_PRIORITIES 32 +#define configMINIMAL_STACK_SIZE ( configSTACK_DEPTH_TYPE ) 256 +#define configUSE_16_BIT_TICKS 0 + +#define configIDLE_SHOULD_YIELD 1 + +/* Synchronization Related */ +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 8 +#define configUSE_QUEUE_SETS 1 +#define configUSE_TIME_SLICING 1 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 0 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 + +/* System */ +#define configSTACK_DEPTH_TYPE uint32_t +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t + +/* Memory allocation related definitions. */ +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configTOTAL_HEAP_SIZE (128*1024) +#define configAPPLICATION_ALLOCATED_HEAP 0 + +/* Hook function related definitions. */ +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 1 +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH 1024 + +/* Interrupt nesting behaviour configuration. */ +/* +#define configKERNEL_INTERRUPT_PRIORITY [dependent of processor] +#define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and application] +#define configMAX_API_CALL_INTERRUPT_PRIORITY [dependent on processor and application] +*/ + +/* SMP port only */ +#define configNUMBER_OF_CORES 2 +#define configTICK_CORE 0 +#define configRUN_MULTIPLE_PRIORITIES 0 + +/* RP2040 specific */ +#define configSUPPORT_PICO_SYNC_INTEROP 1 +#define configSUPPORT_PICO_TIME_INTEROP 1 + +#include +/* Define to trap errors during development. */ +#define configASSERT(x) assert(x) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_xTaskResumeFromISR 1 +#define INCLUDE_xQueueGetMutexHolder 1 + +/* A header file that defines trace macro can be included here. */ + +/* SMP Related config. */ +#define configUSE_MINIMAL_IDLE_HOOK 0 +#define portSUPPORT_SMP 1 + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/FreeRTOS_Kernel_import.cmake b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/FreeRTOS_Kernel_import.cmake new file mode 100644 index 000000000..3c50fcff5 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/FreeRTOS_Kernel_import.cmake @@ -0,0 +1,62 @@ +# This is a copy of /portable/ThirdParty/GCC/RP2040/FREERTOS_KERNEL_import.cmake + +# This can be dropped into an external project to help locate the FreeRTOS kernel +# It should be include()ed prior to project(). Alternatively this file may +# or the CMakeLists.txt in this directory may be included or added via add_subdirectory +# respectively. + +if (DEFINED ENV{FREERTOS_KERNEL_PATH} AND (NOT FREERTOS_KERNEL_PATH)) + set(FREERTOS_KERNEL_PATH $ENV{FREERTOS_KERNEL_PATH}) + message("Using FREERTOS_KERNEL_PATH from environment ('${FREERTOS_KERNEL_PATH}')") +endif () + +set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "portable/ThirdParty/GCC/RP2040") +# undo the above +set(FREERTOS_KERNEL_RP2040_BACK_PATH "../../../..") + +if (NOT FREERTOS_KERNEL_PATH) + # check if we are inside the FreeRTOS kernel tree (i.e. this file has been included directly) + get_filename_component(_ACTUAL_PATH ${CMAKE_CURRENT_LIST_DIR} REALPATH) + get_filename_component(_POSSIBLE_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} REALPATH) + if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) + get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) + endif() + if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) + get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) + message("Setting FREERTOS_KERNEL_PATH to ${FREERTOS_KERNEL_PATH} based on location of FreeRTOS-Kernel-import.cmake") + elseif (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../FreeRTOS-Kernel") + set(FREERTOS_KERNEL_PATH ${PICO_SDK_PATH}/../FreeRTOS-Kernel) + message("Defaulting FREERTOS_KERNEL_PATH as sibling of PICO_SDK_PATH: ${FREERTOS_KERNEL_PATH}") + endif() +endif () + +if (NOT FREERTOS_KERNEL_PATH) + foreach(POSSIBLE_SUFFIX Source FreeRTOS-Kernel FreeRTOS/Source) + # check if FreeRTOS-Kernel exists under directory that included us + set(SEARCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}}) + set(SEARCH_ROOT ../../../..) + get_filename_component(_POSSIBLE_PATH ${SEARCH_ROOT}/${POSSIBLE_SUFFIX} REALPATH) + if (EXISTS ${_POSSIBLE_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) + get_filename_component(FREERTOS_KERNEL_PATH ${_POSSIBLE_PATH} REALPATH) + message("Setting FREERTOS_KERNEL_PATH to '${FREERTOS_KERNEL_PATH}' found relative to enclosing project") + break() + endif() + endforeach() +endif() + +if (NOT FREERTOS_KERNEL_PATH) + message(FATAL_ERROR "FreeRTOS location was not specified. Please set FREERTOS_KERNEL_PATH.") +endif() + +set(FREERTOS_KERNEL_PATH "${FREERTOS_KERNEL_PATH}" CACHE PATH "Path to the FreeRTOS Kernel") + +get_filename_component(FREERTOS_KERNEL_PATH "${FREERTOS_KERNEL_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${FREERTOS_KERNEL_PATH}) + message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' not found") +endif() +if (NOT EXISTS ${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) + message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' does not contain an RP2040 port here: ${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}") +endif() +set(FREERTOS_KERNEL_PATH ${FREERTOS_KERNEL_PATH} CACHE PATH "Path to the FreeRTOS_KERNEL" FORCE) + +add_subdirectory(${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} FREERTOS_KERNEL) \ No newline at end of file diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/IntQueueTimer.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/IntQueueTimer.c new file mode 100644 index 000000000..8b4bf3504 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/IntQueueTimer.c @@ -0,0 +1,102 @@ +/* + * 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 + * + */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo includes. */ +#include "IntQueueTimer.h" +#include "IntQueue.h" + +/* SDK APIs.*/ +#include "pico/time.h" +#include "hardware/irq.h" + +/* The priorities for the two timers. Note that a priority of 0 is the highest +possible on Cortex-M devices. */ +#define tmrMAX_PRIORITY ( 0UL ) +#define trmSECOND_HIGHEST_PRIORITY ( tmrMAX_PRIORITY + 0x40 ) + +#define FIRST_TIMER_PERIOD_US 500 +#define SECOND_TIMER_PERIOD_US 487 + +void prvAlarm0Callback( uint timer ) +{ + UBaseType_t uxSavedInterruptState; + BaseType_t xHigherPriorityTaskWoken; + + configASSERT(timer == 0); + + uxSavedInterruptState = taskENTER_CRITICAL_FROM_ISR(); + { + xHigherPriorityTaskWoken = xFirstTimerHandler(); + hardware_alarm_set_target(0, make_timeout_time_us( FIRST_TIMER_PERIOD_US) ); + } + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptState ); + + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); +} + +void prvAlarm1Callback( uint timer ) +{ + UBaseType_t uxSavedInterruptState; + BaseType_t xHigherPriorityTaskWoken; + + configASSERT(timer == 1); + + uxSavedInterruptState = taskENTER_CRITICAL_FROM_ISR(); + { + xHigherPriorityTaskWoken = xSecondTimerHandler(); + hardware_alarm_set_target(1, make_timeout_time_us( SECOND_TIMER_PERIOD_US) ); + } + taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptState ); + + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); +} + +void vInitialiseTimerForIntQueueTest( void ) +{ + /* Use raw hardware alarms so we have nested interrupts */ + hardware_alarm_claim(0); + hardware_alarm_claim(1); + + /* Don't generate interrupts until the scheduler has been started. + Interrupts will be automatically enabled when the first task starts + running. */ + taskDISABLE_INTERRUPTS(); + + /* Initialize timers. */ + + /* Set the timer interrupts to be above the kernel. The interrupts are + assigned different priorities so they nest with each other. */ + irq_set_priority(TIMER_IRQ_0, tmrMAX_PRIORITY); + irq_set_priority(TIMER_IRQ_1, trmSECOND_HIGHEST_PRIORITY); + hardware_alarm_set_callback(0, prvAlarm0Callback); + hardware_alarm_set_callback(1, prvAlarm1Callback); + hardware_alarm_set_target(0, make_timeout_time_us( FIRST_TIMER_PERIOD_US) ); + hardware_alarm_set_target(1, make_timeout_time_us( SECOND_TIMER_PERIOD_US) ); +} diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/IntQueueTimer.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/IntQueueTimer.h new file mode 100644 index 000000000..36ddb82fb --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/IntQueueTimer.h @@ -0,0 +1,35 @@ +/* + * 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 + * + */ + +#ifndef INT_QUEUE_TIMER_H +#define INT_QUEUE_TIMER_H + +void vInitialiseTimerForIntQueueTest( void ); +portBASE_TYPE xTimer0Handler( void ); +portBASE_TYPE xTimer1Handler( void ); + +#endif + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/RegTest.s b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/RegTest.s new file mode 100644 index 000000000..328505f49 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/RegTest.s @@ -0,0 +1,186 @@ +/* + * 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 + * + */ + +.syntax unified +.cpu cortex-m0plus +.thumb + +.global vRegTest1Implementation +.global vRegTest2Implementation + +/*-----------------------------------------------------------*/ +vRegTest1Implementation: + + /* Fill the core registers with known values. This is only done once. */ + movs r1, #101 + movs r2, #102 + movs r3, #103 + movs r4, #104 + movs r5, #105 + movs r6, #106 + movs r7, #107 + movs r0, #108 + mov r8, r0 + movs r0, #109 + mov r9, r0 + movs r0, #110 + mov r10, r0 + movs r0, #111 + mov r11, r0 + movs r0, #112 + mov r12, r0 + movs r0, #100 + +reg1_loop: + /* Repeatedly check that each register still contains the value written to + it when the task started. */ + cmp r0, #100 + bne reg1_error_loop + cmp r1, #101 + bne reg1_error_loop + cmp r2, #102 + bne reg1_error_loop + cmp r3, #103 + bne reg1_error_loop + cmp r4, #104 + bne reg1_error_loop + cmp r5, #105 + bne reg1_error_loop + cmp r6, #106 + bne reg1_error_loop + cmp r7, #107 + bne reg1_error_loop + movs r0, #108 + cmp r8, r0 + bne reg1_error_loop + movs r0, #109 + cmp r9, r0 + bne reg1_error_loop + movs r0, #110 + cmp r10, r0 + bne reg1_error_loop + movs r0, #111 + cmp r11, r0 + bne reg1_error_loop + movs r0, #112 + cmp r12, r0 + bne reg1_error_loop + + /* Everything passed, increment the loop counter. */ + push { r1 } + ldr r0, =ulRegTest1LoopCounter + ldr r1, [r0] + adds r1, r1, #1 + str r1, [r0] + pop { r1 } + + /* Start again. */ + movs r0, #100 + b reg1_loop + +reg1_error_loop: + /* If this line is hit then there was an error in a core register value. + The loop ensures the loop counter stops incrementing. */ + b reg1_error_loop + nop + + + +vRegTest2Implementation: + + /* Fill the core registers with known values. This is only done once. */ + movs r1, #1 + movs r2, #2 + movs r3, #3 + movs r4, #4 + movs r5, #5 + movs r6, #6 + movs r7, #7 + movs r0, #8 + mov r8, r0 + movs r0, #9 + mov r9, r0 + movs r0, #10 + mov r10, r0 + movs r0, #11 + mov r11, r0 + movs r0, #12 + mov r12, r0 + movs r0, #10 + +reg2_loop: + /* Repeatedly check that each register still contains the value written to + it when the task started. */ + cmp r0, #10 + bne reg2_error_loop + cmp r1, #1 + bne reg2_error_loop + cmp r2, #2 + bne reg2_error_loop + cmp r3, #3 + bne reg2_error_loop + cmp r4, #4 + bne reg2_error_loop + cmp r5, #5 + bne reg2_error_loop + cmp r6, #6 + bne reg2_error_loop + cmp r7, #7 + bne reg2_error_loop + movs r0, #8 + cmp r8, r0 + bne reg2_error_loop + movs r0, #9 + cmp r9, r0 + bne reg2_error_loop + movs r0, #10 + cmp r10, r0 + bne reg2_error_loop + movs r0, #11 + cmp r11, r0 + bne reg2_error_loop + movs r0, #12 + cmp r12, r0 + bne reg2_error_loop + + /* Everything passed, increment the loop counter. */ + push { r1 } + ldr r0, =ulRegTest2LoopCounter + ldr r1, [r0] + adds r1, r1, #1 + str r1, [r0] + pop { r1 } + + /* Start again. */ + movs r0, #10 + b reg2_loop + +reg2_error_loop: + /* If this line is hit then there was an error in a core register value. + The loop ensures the loop counter stops incrementing. */ + b reg2_error_loop + nop + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main.c new file mode 100644 index 000000000..4ab751ca9 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main.c @@ -0,0 +1,223 @@ +/* + * 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, + * and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to + * select between the two. The simply blinky demo is implemented and described + * in main_blinky.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" +#include "semphr.h" + +/* Standard demo includes. */ +#include "TimerDemo.h" +#include "QueueOverwrite.h" +#include "EventGroupsDemo.h" +#include "IntSemTest.h" +#include "TaskNotify.h" + +#include "main.h" + +/* Library includes. */ +#include +#include "pico/stdlib.h" +#if ( mainRUN_ON_CORE == 1 ) +#include "pico/multicore.h" +#endif + +/* 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. */ + +/*-----------------------------------------------------------*/ + +/* + * Configure the hardware as necessary to run this demo. + */ +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 ); +#else +extern void main_full( void ); +#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ + +/* Prototypes for the standard FreeRTOS callback/hook functions implemented +within this file. */ +void vApplicationMallocFailedHook( void ); +void vApplicationIdleHook( void ); +void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); +void vApplicationTickHook( void ); + +/*-----------------------------------------------------------*/ + +void vLaunch( void) +{ + /* 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 +} + +int main( void ) +{ + /* Configure the hardware ready to run the demo. */ + prvSetupHardware(); + const char *rtos_name; +#if ( portSUPPORT_SMP == 1 ) + rtos_name = "FreeRTOS SMP"; +#else + rtos_name = "FreeRTOS"; +#endif + +#if ( portSUPPORT_SMP == 1 ) && ( configNUMBER_OF_CORES == 2 ) + printf("%s on both cores:\n", rtos_name); + vLaunch(); +#endif + +#if ( mainRUN_ON_CORE == 1 ) + printf("%s on core 1:\n", rtos_name); + multicore_launch_core1(vLaunch); + while (true); +#else + printf("%s on core 0:\n", rtos_name); + vLaunch(); +#endif + + return 0; +} +/*-----------------------------------------------------------*/ + +static void prvSetupHardware( void ) +{ + stdio_init_all(); + gpio_init(PICO_DEFAULT_LED_PIN); + gpio_set_dir(PICO_DEFAULT_LED_PIN, 1); + gpio_put(PICO_DEFAULT_LED_PIN, !PICO_DEFAULT_LED_PIN_INVERTED); +} +/*-----------------------------------------------------------*/ + +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 ) +{ +#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 + { + /* The full demo includes a software timer demo/test that requires + prodding periodically from the tick interrupt. */ + #if (mainENABLE_TIMER_DEMO == 1) + vTimerPeriodicISRTests(); + #endif + + /* Call the periodic queue overwrite from ISR demo. */ + #if (mainENABLE_QUEUE_OVERWRITE == 1) + vQueueOverwritePeriodicISRDemo(); + #endif + + /* Call the periodic event group from ISR demo. */ + #if (mainENABLE_EVENT_GROUP == 1) + vPeriodicEventGroupsProcessing(); + #endif + + /* Call the code that uses a mutex from an ISR. */ + #if (mainENABLE_INTERRUPT_SEMAPHORE == 1) + vInterruptSemaphorePeriodicTest(); + #endif + + /* Call the code that 'gives' a task notification from an ISR. */ + #if (mainENABLE_TASK_NOTIFY == 1) + xNotifyTaskFromISR(); + #endif + } +#endif +} diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main.h new file mode 100644 index 000000000..3c5bf0462 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main.h @@ -0,0 +1,59 @@ +/* + * 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 + * + */ + +#ifndef MAIN_H +#define MAIN_H + +#define mainRUN_ON_CORE 0 + + +/* These tests should work in all modes */ +#define mainENABLE_COUNTING_SEMAPHORE 1 +#define mainENABLE_DEATH 1 +#define mainENABLE_INTERRUPT_QUEUE 1 +#define mainENABLE_MATH 1 +#define mainENABLE_QUEUE_OVERWRITE 1 +#define mainENABLE_REG_TEST 1 +#define mainENABLE_SEMAPHORE 1 +#define mainENABLE_TASK_NOTIFY 1 + +#if ( configNUMBER_OF_CORES == 1 ) || ( configRUN_MULTIPLE_PRIORITIES == 0 ) + /* These tests assume that a higher priority task will block a lower priority task from running */ + #define mainENABLE_BLOCK_TIME 1 + #define mainENABLE_BLOCKING_QUEUE 1 + #define mainENABLE_GENERIC_QUEUE 1 + #define mainENABLE_INTERRUPT_SEMAPHORE 1 + #define mainENABLE_EVENT_GROUP 1 + #define mainENABLE_RECURSIVE_MUTEX 1 + #define mainENABLE_TIMER_DEMO 1 +#endif + +#if ( configNUMBER_OF_CORES == 1 ) + /* This test just expects two tasks not to run concurrently */ + #define mainENABLE_DYNAMIC_PRIORITY 1 +#endif + +#endif /* MAIN_H */ \ No newline at end of file diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main_blinky.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main_blinky.c new file mode 100644 index 000000000..dbde53c1a --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main_blinky.c @@ -0,0 +1,194 @@ +/* + * 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 + * + */ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky + * style project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the simply blinky style version. + * + * NOTE 2: This file only contains the source code that is specific to the + * basic demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware are defined in main.c. + ****************************************************************************** + * + * main_blinky() creates one queue, and two tasks. It then starts the + * scheduler. + * + * The Queue Send Task: + * The queue send task is implemented by the prvQueueSendTask() function in + * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly + * block for 200 milliseconds, before sending the value 100 to the queue that + * was created within main_blinky(). Once the value is sent, the task loops + * back around to block for another 200 milliseconds...and so on. + * + * The Queue Receive Task: + * The queue receive task is implemented by the prvQueueReceiveTask() function + * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly + * blocks on attempts to read data from the queue that was created within + * main_blinky(). When data is received, the task checks the value of the + * data, and if the value equals the expected 100, toggles an LED. The 'block + * time' parameter passed to the queue receive function specifies that the + * task should be held in the Blocked state indefinitely to wait for data to + * be available on the queue. The queue receive task will only leave the + * Blocked state when the queue send task writes to the queue. As the queue + * send task writes to the queue every 200 milliseconds, the queue receive + * task leaves the Blocked state every 200 milliseconds, and therefore toggles + * the LED every 200 milliseconds. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Library includes. */ +#include +#include "hardware/gpio.h" + +/* Priorities at which the tasks are created. */ +#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 ( 1000 / 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 ) + +/* The LED toggled by the Rx task. */ +#define mainTASK_LED ( PICO_DEFAULT_LED_PIN ) + +/*-----------------------------------------------------------*/ + +/* + * Called by main when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1 in + * main.c. + */ +void main_blinky( void ); + +/* + * The tasks as described in the comments at the top of this file. + */ +static void prvQueueReceiveTask( void *pvParameters ); +static void prvQueueSendTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* The queue used by both tasks. */ +static QueueHandle_t xQueue = NULL; + +/*-----------------------------------------------------------*/ + +void main_blinky( void ) +{ + printf(" Starting main_blinky.\n"); + + /* 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. */ + + xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); + + /* 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 on the FreeRTOS heap + http://www.freertos.org/a00111.html. */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +static void prvQueueSendTask( void *pvParameters ) +{ +TickType_t xNextWakeTime; +const unsigned long ulValueToSend = 100UL; + + /* Remove compiler warning about unused parameter. */ + ( void ) pvParameters; + + /* 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 ); + + /* 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 ) +{ +unsigned long ulReceivedValue; +const unsigned long ulExpectedValue = 100UL; + + /* 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 ); + + /* 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 ) + { + gpio_xor_mask( 1u << mainTASK_LED ); + ulReceivedValue = 0U; + } + } +} +/*-----------------------------------------------------------*/ + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main_full.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main_full.c new file mode 100644 index 000000000..adde5bdc0 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/main_full.c @@ -0,0 +1,481 @@ +/* + * 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 + * + */ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky style + * project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the comprehensive test and demo version. + * + * NOTE 2: This file only contains the source code that is specific to the + * full demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware, are defined in main.c. + * + ****************************************************************************** + * + * main_full() creates all the demo application tasks and software timers, then + * starts the scheduler. The web documentation provides more details of the + * standard demo application tasks, which provide no particular functionality, + * but do provide a good example of how to use the FreeRTOS API. + * + * In addition to the standard demo tasks, the following tasks and tests are + * defined and/or created within this file: + * + * "Reg test" tasks - These fill both the core and floating point registers with + * known values, then check that each register maintains its expected value for + * the lifetime of the task. Each task uses a different set of values. The reg + * test tasks execute with a very low priority, so get preempted very + * frequently. A register containing an unexpected value is indicative of an + * error in the context switching mechanism. + * + * "Check" task - The check task period is initially set to three seconds. The + * task checks that all the standard demo tasks, and the register check tasks, + * are not only still executing, but are executing without reporting any errors. + * If the check task discovers that a task has either stalled, or reported an + * error, then it changes its own execution period from the initial three + * seconds, to just 200ms. The check task also toggles an LED each time it is + * called. This provides a visual indication of the system status: If the LED + * toggles every three seconds, then no issues have been discovered. If the LED + * toggles every 200ms, then an issue has been discovered with at least one + * task. + */ + +/* Standard includes. */ +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "semphr.h" + +/* SDK includes */ +#include "pico/stdlib.h" + +/* Standard demo application includes. */ +#include "flop.h" +#include "semtest.h" +#include "dynamic.h" +#include "BlockQ.h" +#include "blocktim.h" +#include "countsem.h" +#include "GenQTest.h" +#include "recmutex.h" +#include "death.h" +#include "partest.h" +#include "comtest2.h" +#include "serial.h" +#include "TimerDemo.h" +#include "QueueOverwrite.h" +#include "IntQueue.h" +#include "EventGroupsDemo.h" +#include "IntSemTest.h" +#include "TaskNotify.h" + +#include "main.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 mainCDC_COMMAND_CONSOLE_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2UL ) +#define mainCOM_TEST_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define mainQUEUE_OVERWRITE_PRIORITY ( tskIDLE_PRIORITY ) + +/* The initial priority used by the UART command console task. */ +#define mainUART_COMMAND_CONSOLE_TASK_PRIORITY ( configMAX_PRIORITIES - 2 ) + +/* The LED used by the check task. */ +#define mainCHECK_LED ( PICO_DEFAULT_LED_PIN ) + +/* A block time of zero simply means "don't block". */ +#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 ) + +/* 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 ) + +/* 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 ) + +/* The base period used by the timer test tasks. */ +#define mainTIMER_TEST_PERIOD ( 50 ) + +/*-----------------------------------------------------------*/ + +/* + * Called by main() to run the full demo (as opposed to the blinky demo) when + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. + */ +void main_full( void ); + +/* + * The check task, as described at the top of this file. + */ +static void prvCheckTask( void *pvParameters ); + +/* + * Register check tasks, and the tasks used to write over and check the contents + * 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, but the + * entry points are kept in the C file for the convenience of checking the task + * parameter. + */ +static void prvRegTestTaskEntry1( void *pvParameters ); +extern void vRegTest1Implementation( void ); +static void prvRegTestTaskEntry2( void *pvParameters ); +extern void vRegTest2Implementation( void ); + +/*-----------------------------------------------------------*/ + +/* 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. */ +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. */ + + puts(" Starting tests:"); +#if (mainENABLE_INTERRUPT_QUEUE == 1) + puts(" - Interrupt Queue"); + vStartInterruptQueueTasks(); +#endif +#if (mainENABLE_DYNAMIC_PRIORITY == 1) + puts(" - Dynamic Priority"); + vStartDynamicPriorityTasks(); +#endif +#if (mainENABLE_BLOCKING_QUEUE == 1) + puts(" - Blocking Queue"); + vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); +#endif +#if (mainENABLE_BLOCK_TIME == 1) + puts(" - Block Time"); + vCreateBlockTimeTasks(); +#endif +#if (mainENABLE_COUNTING_SEMAPHORE == 1) + puts(" - Counting Semaphore"); + vStartCountingSemaphoreTasks(); +#endif +#if (mainENABLE_GENERIC_QUEUE == 1) + puts(" - Generic Queue"); + vStartGenericQueueTasks( tskIDLE_PRIORITY ); +#endif +#if (mainENABLE_RECURSIVE_MUTEX == 1) + puts(" - Recursive Mutex"); + vStartRecursiveMutexTasks(); +#endif +#if (mainENABLE_SEMAPHORE == 1) + puts(" - Semaphore"); + vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); +#endif +#if (mainENABLE_MATH == 1) + puts(" - Math"); + vStartMathTasks( mainFLOP_TASK_PRIORITY ); +#endif +#if (mainENABLE_TIMER_DEMO == 1) + puts(" - Timer"); + vStartTimerDemoTask( mainTIMER_TEST_PERIOD ); +#endif +#if (mainENABLE_QUEUE_OVERWRITE == 1) + puts(" - Queue Overwrite"); + vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY ); +#endif +#if (mainENABLE_EVENT_GROUP == 1) + puts(" - Event Group"); + vStartEventGroupTasks(); +#endif +#if (mainENABLE_INTERRUPT_SEMAPHORE == 1) + puts(" - Interrupt Semaphore"); + vStartInterruptSemaphoreTasks(); +#endif +#if (mainENABLE_TASK_NOTIFY == 1) + puts(" - Task Notify"); + vStartTaskNotifyTask(); +#endif + +#if (mainENABLE_REG_TEST == 1) + puts(" - Register"); + /* 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 ); +#endif + + /* 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. */ +#if (mainENABLE_DEATH == 1) + vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); + puts(" - Death"); +#endif + + /* 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 on the FreeRTOS heap + http://www.freertos.org/a00111.html. */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +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; +unsigned long ulIterations = 0; + + /* Just to stop compiler warnings. */ + ( void ) pvParameters; + + /* 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 ); + + #if (mainENABLE_INTERRUPT_QUEUE == 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( xAreIntQueueTasksStillRunning() != pdTRUE ) + { + ulErrorFound |= 1UL << 0UL; + } + #endif + + #if (mainENABLE_MATH == 1) + if( xAreMathsTaskStillRunning() != pdTRUE ) + { + ulErrorFound |= 1UL << 1UL; + } + #endif + + #if (mainENABLE_DYNAMIC_PRIORITY == 1) + if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) + { + ulErrorFound |= 1UL << 2UL; + } + #endif + + #if (mainENABLE_BLOCKING_QUEUE == 1) + if( xAreBlockingQueuesStillRunning() != pdTRUE ) + { + ulErrorFound |= 1UL << 3UL; + } + #endif + + #if (mainENABLE_BLOCK_TIME == 1) + if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) + { + ulErrorFound |= 1UL << 4UL; + } + #endif + + #if (mainENABLE_GENERIC_QUEUE == 1) + if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) + { + ulErrorFound |= 1UL << 5UL; + } + #endif + + #if (mainENABLE_RECURSIVE_MUTEX == 1) + if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) + { + ulErrorFound |= 1UL << 6UL; + } + #endif + + #if (mainENABLE_DEATH == 1) + if( xIsCreateTaskStillRunning() != pdTRUE ) + { + ulErrorFound |= 1UL << 7UL; + } + #endif + + #if (mainENABLE_SEMAPHORE == 1) + if( xAreSemaphoreTasksStillRunning() != pdTRUE ) + { + ulErrorFound |= 1UL << 8UL; + } + #endif + + #if (mainENABLE_TIMER_DEMO == 1) + if( xAreTimerDemoTasksStillRunning( ( TickType_t ) xDelayPeriod ) != pdPASS ) + { + ulErrorFound |= 1UL << 9UL; + } + #endif + + #if (mainENABLE_COUNTING_SEMAPHORE == 1) + if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) + { + ulErrorFound |= 1UL << 10UL; + } + #endif + + #if (mainENABLE_QUEUE_OVERWRITE == 1) + if( xIsQueueOverwriteTaskStillRunning() != pdPASS ) + { + ulErrorFound |= 1UL << 11UL; + } + #endif + + #if (mainENABLE_EVENT_GROUP == 1) + if( xAreEventGroupTasksStillRunning() != pdPASS ) + { + ulErrorFound |= 1UL << 12UL; + } + #endif + + #if (mainENABLE_INTERRUPT_SEMAPHORE == 1) + if( xAreInterruptSemaphoreTasksStillRunning() != pdPASS ) + { + ulErrorFound |= 1UL << 13UL; + } + #endif + + #if (mainENABLE_TASK_NOTIFY == 1) + if( xAreTaskNotificationTasksStillRunning() != pdPASS ) + { + ulErrorFound |= 1UL << 14UL; + } + #endif + + #if (mainENABLE_REG_TEST == 1) + /* Check that the register test 1 task is still running. */ + if( ulLastRegTest1Value == ulRegTest1LoopCounter ) + { + ulErrorFound |= 1UL << 15UL; + } + ulLastRegTest1Value = ulRegTest1LoopCounter; + + /* Check that the register test 2 task is still running. */ + if( ulLastRegTest2Value == ulRegTest2LoopCounter ) + { + ulErrorFound |= 1UL << 16UL; + } + ulLastRegTest2Value = ulRegTest2LoopCounter; + #endif + + /* 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. */ + gpio_xor_mask( 1u << mainCHECK_LED ); + + ulIterations++; + if( ulErrorFound != pdFALSE ) + { + static uint32_t ulLastErrorFound; + if (ulErrorFound != ulLastErrorFound) { + printf("Iterations: %d; Errors now %08x\n", (int) ulIterations, (int) ulErrorFound); + ulLastErrorFound = ulErrorFound; + } + /* 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 ) +{ + /* 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 ) + { + /* 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 ); +} +/*-----------------------------------------------------------*/ + +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 ) + { + /* 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 ); +} +/*-----------------------------------------------------------*/ + + + + + + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/pico_sdk_import.cmake b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/pico_sdk_import.cmake new file mode 100644 index 000000000..05e884b18 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/Standard_smp/pico_sdk_import.cmake @@ -0,0 +1,62 @@ +# This is a copy of /external/pico_sdk_import.cmake + +# This can be dropped into an external project to help locate this SDK +# It should be include()ed prior to project() + +if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) + set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) + message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) + set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) + message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) + set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) + message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") +endif () + +set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") +set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") +set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") + +if (NOT PICO_SDK_PATH) + if (PICO_SDK_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_SDK_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG master + ) + if (NOT pico_sdk) + message("Downloading Raspberry Pi Pico SDK") + FetchContent_Populate(pico_sdk) + set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + message(FATAL_ERROR + "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." + ) + endif () +endif () + +get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_SDK_PATH}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") +endif () + +set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) +if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") +endif () + +set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) + +include(${PICO_SDK_INIT_CMAKE_FILE}) diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/UsingCMSIS/FreeRTOSConfig.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/UsingCMSIS/FreeRTOSConfig.h index 3003aa29d..bbfadfc34 100644 --- a/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/UsingCMSIS/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/CORTEX_M0+_RP2040/UsingCMSIS/FreeRTOSConfig.h @@ -101,7 +101,7 @@ */ /* SMP port only */ -#define configNUM_CORES 1 +#define configNUMBER_OF_CORES 1 #define configTICK_CORE 1 #define configRUN_MULTIPLE_PRIORITIES 1 diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/.gitignore b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/.gitignore new file mode 100644 index 000000000..13ce034a7 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/.gitignore @@ -0,0 +1,23 @@ +/.metadata/ + +**/.build*/* +**/bin/* +*.o +*.xe +*.vcd +*.s +*.xi +*.i +*.a +*.xmt +**/_build/ +**/run_*.log +**/pdf/* +**/html/* +**/.settings/* +*.pyc +**/test_results.csv +**/.venv/** +# systemview debug files +*.SVDAT + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/README.md b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/README.md new file mode 100644 index 000000000..b67b928d3 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/README.md @@ -0,0 +1,155 @@ +# FreeRTOS SMP Demo for XMOS XCORE.AI Explorer Board + +> **FreeRTOS-SMP Kernel is still being tested.** + +This page documents a demo that uses the [FreeRTOS symmetric multiprocessing (SMP) version](../../../SMP.md). +The demo targets the [XCORE.AI](https://www.xmos.ai/xcore-ai/), which has 16 +cores. The project uses [XMOS XTC Tools](https://www.xmos.ai/software-tools/) to +build the FreeRTOS XCOREAI port. This application demonstrates the [Symmetric +Multiprocessing (SMP)](https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/smp) +support in the FreeRTOS Kernel. + +---- + +## IMPORTANT! Notes on using the FreeRTOS XCORE.AI demo application + +Please read all the following points before using this RTOS port. + +1. [Source Code Organization](#source-code-organization) +1. [The Demo Application](#the-demo-application) +1. [Building and Running the RTOS Demo Application](#building-and-running-the-rtos-demo-application) +1. [RTOS Configuration and Usage Details](#rtos-configuration-and-usage-details) + +Also see the FAQ [My application does not run, what could be wrong](https://www.freertos.org/FAQHelp.html)? + +---- + +## Source Code Organization +The project files for this demo are located in the `FreeRTOS/Demo/XCORE.AI_xClang/RTOSDemo` +directory of the [FreeRTOS SMP Demo Git repository](https://github.com/FreeRTOS/FreeRTOS-SMP-Demos). +FreeRTOS Port files compiled in the project are in the +`FreeRTOS/Source/portable/ThirdParty/xClang/XCOREAI` directory. + +---- + +## The Demo Application +The constant `mainCREATE_SIMPLE_BLINKY_DEMO_ONLY`, which is defined at the top +of `testing_main.h`, is used to switch between a simple "blinky" style getting +started project and a more comprehensive test and demo application. + +### When mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1 +When `mainCREATE_SIMPLE_BLINKY_DEMO_ONLY` is set to 1, the demo application +creates two tasks, each of which periodically toggles an on-board LED (LED 0 by +one task and and LED 1 by the other). + +### When mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0 +When `mainCREATE_SIMPLE_BLINKY_DEMO_ONLY` is set to 0, the demo application +implements a comprehensive test and demo that, among other things, demonstrates +and/or tests: + +* [Message buffers](https://www.freertos.org/RTOS-stream-message-buffers.html) +* [Stream buffers](https://www.freertos.org/RTOS-stream-message-buffers.html) +* [Task notifications](https://www.freertos.org/RTOS-task-notifications.html) +* [Queues](https://www.freertos.org/Embedded-RTOS-Queues.html) +* [Semaphores](https://www.freertos.org/Embedded-RTOS-Binary-Semaphores.html) +* [Mutexes](https://www.freertos.org/Real-time-embedded-RTOS-mutexes.html) +* [Event groups](https://www.freertos.org/FreeRTOS-Event-Groups.html) +* [Software timers](https://www.freertos.org/RTOS-software-timer.html) + +The created tasks are from the set of [standard demo](https://www.freertos.org/a00102.html) +tasks. Standard demo tasks are used by all FreeRTOS port demo applications. They +have no specific functionality, and were created simply to demonstrate how to use +the FreeRTOS API, and test the RTOS port. + +Two "check" tasks are created to periodically inspect the standard demo tasks +(which contain self monitoring code) to ensure all the tasks are functioning as +expected. One check task monitors the demo tasks running on tile 0 and toggles +LED 0 each time it executes. The other check task monitors the demo tasks +running on tile 1 and toggles LED 1 each time it executes. This gives visual +feedback of the system health. **If both the LEDs toggle every 3 seconds, then the +check tasks have not discovered any problems. If any LED toggles every 200ms, +then the check task has discovered a problem in one or more tasks.** + +---- + +## Building and Running the RTOS Demo Application + +### Hardware setup +Plug the xTAG programmer into the evaluation board. Ensure both the xTAG and +evaluation board are connected to the computer via USB. + +### Toolchain installation +The development tools require a Linux host or a Linux style environment. + +1. Download the [XMOS XTC Tools](https://www.xmos.ai/software-tools/). +2. Uncompress the archive to your chosen installation directory. The example +below will install to your home directory: +```sh +$ tar -xf archive.tgz -C ~ +``` +3. Configure the default set of environment variables: +```sh +$ cd ~/XMOS/XTC/15.1.0 +$ source SetEnv +``` +4. Check that your tools environment has been setup correctly: +```sh +$ xcc --help +``` +5. Make the XTAG drivers accessible to all users. This step is only required +to be done once on a given development machine. +```sh +$ cd ~/XMOS/XTC/15.1.0/scripts +$ sudo ./setup_xmos_devices.sh +``` +6. Check that the XTAG devices are available and accessible: +```sh +$ cd ~/XMOS/XTC/15.1.0/scripts +$ ./check_xmos_devices.sh +Searching for xtag3 devices... +0 found +Searching for xtag4 devices... +1 found +Success: User is able to access all xtag4 devices +``` +7. Check that the device is available for debugging: +```sh +$ xrun -l +Available XMOS Devices +---------------------- + + ID Name Adapter ID Devices + -- ---- ---------- ------- + 0 XMOS XTAG-4 2W3T8RAG P[0] +``` + +### Build and Run the demo application +1. Go to the RTOSDemo directory: +```sh +$ cd FreeRTOS/Demo/XCORE.AI_xClang/RTOSDemo +``` +2. Build the demo: +```sh +$ make +``` +3. Run the demo: +```sh +$ make run +``` +---- + +## RTOS Configuration and Usage Details + +* Configuration items specific to this demo are contained in +`FreeRTOS/Demo/XCORE.AI_xClang/RTOSDemo/src/FreeRTOSConfig.h`. The +[constants defined in that file](https://www.freertos.org/a00110.html) can be +edited to suit your application. The following configuration options are +specific to the SMP support in the FreeRTOS Kernel: + * `configNUM_CORES` - Set the number of cores. + * `configRUN_MULTIPLE_PRIORITIES` - Enable/Disable simultaneously running tasks with multiple priorities. + * `configUSE_CORE_AFFINITY` - Enable/Disable setting a task's affinity to certain cores. +* `Source/Portable/MemMang/heap_4.c` is included in the project to provide the +memory allocation required by the RTOS kernel. Please refer to the +[Memory Management](https://www.freertos.org/a00111.html) section of the API +documentation for complete information. +* vPortEndScheduler() has not been implemented. diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/.cproject b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/.cproject new file mode 100644 index 000000000..d4fe938c8 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/.cproject @@ -0,0 +1,884 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + xmake + CONFIG=Default + all + true + true + true + + + xmake + CONFIG=Default + clean + true + true + true + + + + + + + + + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/.gitignore b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/.gitignore new file mode 100644 index 000000000..323ba8ee9 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/.gitignore @@ -0,0 +1,3 @@ +build +bin +*.d \ No newline at end of file diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/.project b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/.project new file mode 100644 index 000000000..8a1456ab5 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/.project @@ -0,0 +1,54 @@ + + + RTOSDemo + + + + + + com.xmos.cdt.core.ModulePathBuilder + + + + + com.xmos.cdt.core.ProjectInfoSyncBuilder + + + + + com.xmos.cdt.core.LegacyProjectCheckerBuilder + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + com.xmos.cdt.core.XdeProjectNature + + + + Common + 2 + $%7BPARENT-3-PROJECT_LOC%7D/Demo/Common + + + freertos + 2 + $%7BPARENT-3-PROJECT_LOC%7D/Source + + + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/Makefile b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/Makefile new file mode 100644 index 000000000..2d2cae62b --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/Makefile @@ -0,0 +1,116 @@ + +TARGET = XCORE-AI-EXPLORER + +APP_NAME = RTOSDemo + +BUILD_DIR = build +OUT_DIR = bin + +DEMO_ROOT = src +KERNEL_ROOT = ../../../../../Source +COMMON_DEMO_ROOT = ../../../../Common +MINIMAL_DEMO_ROOT = $(COMMON_DEMO_ROOT)/Minimal +PORTABLE_ROOT = $(KERNEL_ROOT)/portable +MEMMANG_ROOT = $(PORTABLE_ROOT)/MemMang +XCORE_PORT_ROOT = $(PORTABLE_ROOT)/ThirdParty/xClang/XCOREAI +RTOS_SUPPORT_ROOT = ../lib_rtos_support + +INCLUDE_DIRS = $(DEMO_ROOT) $(DEMO_ROOT)/IntQueueTimer $(DEMO_ROOT)/regtest \ + $(KERNEL_ROOT)/include $(XCORE_PORT_ROOT) \ + $(COMMON_DEMO_ROOT)/include \ + $(RTOS_SUPPORT_ROOT)/api $(RTOS_SUPPORT_ROOT)/src + +APP_SOURCES = $(DEMO_ROOT)/main.xc \ + $(DEMO_ROOT)/test.c \ + $(DEMO_ROOT)/IntQueueTimer/IntQueueTimer.c \ + $(DEMO_ROOT)/partest/mab_led_driver.xc \ + $(DEMO_ROOT)/partest/partest.c \ + $(DEMO_ROOT)/regtest/prvRegisterCheck_asm1.S \ + $(DEMO_ROOT)/regtest/prvRegisterCheck_asm2.S \ + $(DEMO_ROOT)/regtest/regtest.c + +COMMON_DEMO_SOURCES = $(MINIMAL_DEMO_ROOT)/AbortDelay.c \ + $(MINIMAL_DEMO_ROOT)/BlockQ.c \ + $(MINIMAL_DEMO_ROOT)/blocktim.c \ + $(MINIMAL_DEMO_ROOT)/countsem.c \ + $(MINIMAL_DEMO_ROOT)/death.c \ + $(MINIMAL_DEMO_ROOT)/dynamic.c \ + $(MINIMAL_DEMO_ROOT)/EventGroupsDemo.c \ + $(MINIMAL_DEMO_ROOT)/flop.c \ + $(MINIMAL_DEMO_ROOT)/GenQTest.c \ + $(MINIMAL_DEMO_ROOT)/integer.c \ + $(MINIMAL_DEMO_ROOT)/IntQueue.c \ + $(MINIMAL_DEMO_ROOT)/IntSemTest.c \ + $(MINIMAL_DEMO_ROOT)/MessageBufferDemo.c \ + $(MINIMAL_DEMO_ROOT)/PollQ.c \ + $(MINIMAL_DEMO_ROOT)/QPeek.c \ + $(MINIMAL_DEMO_ROOT)/QueueOverwrite.c \ + $(MINIMAL_DEMO_ROOT)/QueueSet.c \ + $(MINIMAL_DEMO_ROOT)/QueueSetPolling.c \ + $(MINIMAL_DEMO_ROOT)/recmutex.c \ + $(MINIMAL_DEMO_ROOT)/semtest.c \ + $(MINIMAL_DEMO_ROOT)/StreamBufferDemo.c \ + $(MINIMAL_DEMO_ROOT)/StreamBufferInterrupt.c \ + $(MINIMAL_DEMO_ROOT)/TaskNotify.c \ + $(MINIMAL_DEMO_ROOT)/TaskNotifyArray.c \ + $(MINIMAL_DEMO_ROOT)/TimerDemo.c + +RTOS_SUPPORT_SOURCES = $(RTOS_SUPPORT_ROOT)/src/rtos_cores.c \ + $(RTOS_SUPPORT_ROOT)/src/rtos_interrupt.c \ + $(RTOS_SUPPORT_ROOT)/src/rtos_irq.c \ + $(RTOS_SUPPORT_ROOT)/src/rtos_locks.c \ + $(RTOS_SUPPORT_ROOT)/src/rtos_printf.c \ + $(RTOS_SUPPORT_ROOT)/src/rtos_time.c + +KERNEL_SOURCES = $(KERNEL_ROOT)/event_groups.c \ + $(KERNEL_ROOT)/list.c \ + $(KERNEL_ROOT)/queue.c \ + $(KERNEL_ROOT)/stream_buffer.c \ + $(KERNEL_ROOT)/tasks.c \ + $(KERNEL_ROOT)/timers.c \ + $(MEMMANG_ROOT)/heap_4.c \ + $(XCORE_PORT_ROOT)/port.c \ + $(XCORE_PORT_ROOT)/port.xc \ + $(XCORE_PORT_ROOT)/portasm.S + +SOURCES = $(APP_SOURCES) $(COMMON_DEMO_SOURCES) $(RTOS_SUPPORT_SOURCES) $(KERNEL_SOURCES) + +OBJS = $(addprefix $(BUILD_DIR)/,$(notdir $(addsuffix .o,$(SOURCES)))) + +ROOT_DIRS = $(DEMO_ROOT) $(DEMO_ROOT)/IntQueueTimer $(DEMO_ROOT)/partest \ + $(DEMO_ROOT)/regtest $(DEMO_ROOT)/TimerDemoISR \ + $(MINIMAL_DEMO_ROOT) $(KERNEL_ROOT) $(MEMMANG_ROOT) \ + $(XCORE_PORT_ROOT) $(RTOS_SUPPORT_ROOT)/src + +vpath %.c $(ROOT_DIRS) +vpath %.xc $(ROOT_DIRS) +vpath %.S $(ROOT_DIRS) + +FLAGS = -Wall -O2 -g -report -fxscope \ + $(DEMO_ROOT)/$(TARGET).xn \ + $(DEMO_ROOT)/config.xscope \ + $(addprefix -I,$(INCLUDE_DIRS)) + +XCLANG = xcc + +.PHONY: all clean run + +all: $(OUT_DIR)/$(APP_NAME).xe + +# Include the header file dependencies for all the sources +-include $(patsubst %.o,%.d,$(OBJS)) + +$(BUILD_DIR)/%.o: % + @"mkdir" -p $(@D) + $(XCLANG) -c -MT"$@" -MMD -MP -MF"$(patsubst %.o,%.d,$@)" -MT"$(patsubst %.o,%.d,$@)" -o $@ $< $(FLAGS) + +$(OUT_DIR)/$(APP_NAME).xe: $(OBJS) + @"mkdir" -p $(@D) + $(XCLANG) -o $@ $^ $(FLAGS) + +clean: + $(RM) -r $(OUT_DIR) $(BUILD_DIR) + +run: $(OUT_DIR)/$(APP_NAME).xe + xrun --xscope $(OUT_DIR)/$(APP_NAME).xe + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/FreeRTOSConfig.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/FreeRTOSConfig.h new file mode 100644 index 000000000..49656420f --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/FreeRTOSConfig.h @@ -0,0 +1,106 @@ +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/* Here is a good place to include header files that are required across +your application. */ +#ifndef __XC__ +#include +#endif + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configUSE_TICKLESS_IDLE 0 +#define configCPU_CLOCK_HZ 100000000 +#define configNUMBER_OF_CORES 7 +#define configTICK_RATE_HZ 1000 +#define configMAX_PRIORITIES 32 +#define configRUN_MULTIPLE_PRIORITIES 0 +#define configUSE_CORE_AFFINITY 0 +#define configMINIMAL_STACK_SIZE ( configSTACK_DEPTH_TYPE ) 256 +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */ +#define configQUEUE_REGISTRY_SIZE 10 +#define configUSE_QUEUE_SETS 1 +#define configUSE_TIME_SLICING 1 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 0 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 +#define configSTACK_DEPTH_TYPE uint32_t +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t + +/* Memory allocation related definitions. */ +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configTOTAL_HEAP_SIZE 128*1024 +#define configAPPLICATION_ALLOCATED_HEAP 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 1 +#define configUSE_MINIMAL_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 1 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 1 +#define configUSE_TRACE_FACILITY 1 +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 +#define confSTAT_TYPE uint64_t + +/* Co-routine related definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 1 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH portTASK_STACK_DEPTH(prvTimerTask) + +/* Interrupt nesting behaviour configuration. */ +/* +#define configKERNEL_INTERRUPT_PRIORITY [dependent of processor] +#define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and application] +#define configMAX_API_CALL_INTERRUPT_PRIORITY [dependent on processor and application] +*/ + +/* Define to trap errors during development. */ +#define configASSERT(x) xassert(x) + +/* Define to enable debug_printf() */ +#define configENABLE_DEBUG_PRINTF 1 + +/* FreeRTOS MPU specific definitions. */ +#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_xResumeFromISR 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xEventGroupSetBitFromISR 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_xTaskResumeFromISR 1 +#define INCLUDE_xQueueGetMutexHolder 1 + +/* A header file that defines trace macro can be included here. */ + +#endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/IntQueueTimer/IntQueueTimer.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/IntQueueTimer/IntQueueTimer.c new file mode 100644 index 000000000..49261e7c9 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/IntQueueTimer/IntQueueTimer.c @@ -0,0 +1,69 @@ +// Copyright (c) 2020, XMOS Ltd, All rights reserved + +#include "FreeRTOS.h" +#include "task.h" + +#include +#include + +#include "IntQueue.h" + +DEFINE_RTOS_INTERRUPT_CALLBACK( pxIntQueueTimerISR, pvData ) +{ + static int xCount0, xCount1; + hwtimer_t xTimer = ( hwtimer_t ) pvData; + uint32_t ulNow; + int xYieldRequired; + + ulNow = hwtimer_get_time( xTimer ); + ulNow = hwtimer_get_trigger_time( xTimer ); + ulNow += configCPU_CLOCK_HZ / 50; + + if( ++xCount0 == 2 ) + { + xCount0 = 0; + taskENTER_CRITICAL_FROM_ISR(); + if( xFirstTimerHandler() != pdFALSE ) + { + xYieldRequired = pdTRUE; + } + taskEXIT_CRITICAL_FROM_ISR( 0 ); + } + + if( ++xCount1 == 3 ) + { + xCount1 = 0; + taskENTER_CRITICAL_FROM_ISR(); + if( xSecondTimerHandler() != pdFALSE ) + { + xYieldRequired = pdTRUE; + } + taskEXIT_CRITICAL_FROM_ISR( 0 ); + } + + hwtimer_change_trigger_time( xTimer, ulNow ); + + portYIELD_FROM_ISR( xYieldRequired ); +} + +void vInitialiseTimerForIntQueueTest( void ) +{ +uint32_t ulNow; +uint32_t ulState; +hwtimer_t xIntQueueTimer; + + /* + * Disable interrupts here so we stay on the same core + */ + ulState = portDISABLE_INTERRUPTS(); + { + xIntQueueTimer = hwtimer_alloc(); + ulNow = hwtimer_get_time( xIntQueueTimer ); + ulNow += configCPU_CLOCK_HZ / 50; + triggerable_setup_interrupt_callback( xIntQueueTimer, ( void * ) xIntQueueTimer, RTOS_INTERRUPT_CALLBACK( pxIntQueueTimerISR ) ); + hwtimer_set_trigger_time( xIntQueueTimer, ulNow ); + triggerable_enable_trigger( xIntQueueTimer ); + } + portRESTORE_INTERRUPTS( ulState ); +} + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/IntQueueTimer/IntQueueTimer.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/IntQueueTimer/IntQueueTimer.h new file mode 100644 index 000000000..c89754d29 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/IntQueueTimer/IntQueueTimer.h @@ -0,0 +1,8 @@ +// Copyright (c) 2020, XMOS Ltd, All rights reserved + +#ifndef INTQUEUETIMER_H_ +#define INTQUEUETIMER_H_ + +void vInitialiseTimerForIntQueueTest( void ); + +#endif /* INTQUEUETIMER_H_ */ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/XCORE-AI-EXPLORER.xn b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/XCORE-AI-EXPLORER.xn new file mode 100644 index 000000000..4c73b31fd --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/XCORE-AI-EXPLORER.xn @@ -0,0 +1,81 @@ + + + Board + xcore.ai Explorer Kit + + + tileref tile[2] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/config.xscope b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/config.xscope new file mode 100644 index 000000000..68b1a460d --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/config.xscope @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/main.xc b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/main.xc new file mode 100644 index 000000000..c39e5d2aa --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/main.xc @@ -0,0 +1,51 @@ +// Copyright (c) 2019, XMOS Ltd, All rights reserved + +#include + +#include "rtos_printf.h" +#include "testing_main.h" + +extern "C" { +int c_main( int tile, chanend xTile0Chan, chanend xTile1Chan, chanend xTile2Chan, chanend xTile3Chan ); +} + +void xctask1(void) +{ + rtos_printf("xc task 1 on core %u\n", get_logical_core_id()); + for (;;); +} + +void xctask2(void) +{ + rtos_printf("xc task 2 on core %u\n", get_logical_core_id()); + for (;;); +} + +int main(void) +{ + chan c_t0_t1; + + par { + on tile[0]: + { + par { +#if ( testingmainENABLE_XC_TASKS == 1 ) + xctask1(); +#endif + c_main( 0, null, c_t0_t1, null, null ); + } + } +#if ( testingmainNUM_TILES > 1 ) + on tile[1]: + { + par { +#if ( testingmainENABLE_XC_TASKS == 1 ) + xctask2(); +#endif + c_main( 1, c_t0_t1, null, null, null ); + } + } +#endif + } + return 0; +} diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/partest/mab_led_driver.xc b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/partest/mab_led_driver.xc new file mode 100644 index 000000000..6611e77b6 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/partest/mab_led_driver.xc @@ -0,0 +1,16 @@ +// Copyright (c) 2020, XMOS Ltd, All rights reserved + +#include +#include + +out port p_led_0_4 = PORT_LEDS; + +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +#define LED_COUNT 4 + +void led_driver(uint16_t led_value) +{ + p_led_0_4 <: 0; + p_led_0_4 <: (unsigned)( led_value & 0x000F ); +} diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/partest/partest.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/partest/partest.c new file mode 100644 index 000000000..2fa62b97c --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/partest/partest.c @@ -0,0 +1,115 @@ +// Copyright (c) 2020, XMOS Ltd, All rights reserved + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "portable.h" +#include +#include + +/* Demo application include files. */ +#include "partest.h" + +void led_driver(uint16_t led_value); + +static chanend_t c_write; +static chanend_t c_read; +static int this_tile; +static uint16_t led_bitmap = 0xFFFF; + +typedef enum { + LED_OFF = pdFALSE, + LED_ON = pdTRUE, + LED_TOGGLE +} led_value_t; + +typedef union { + struct { + uint32_t tile : 8; + uint32_t led : 8; + led_value_t value : 8; + uint32_t reserved : 8; + }; + uint32_t raw; +} led_cmd_t; + +DEFINE_RTOS_INTERRUPT_CALLBACK( pxLEDUpdateISR, pvData ) +{ + led_cmd_t xCmd; + uint16_t mask; + + (void) pvData; + + //debug_printf("led isr\n"); + xCmd.raw = chanend_in_word( c_read ); + chanend_check_end_token( c_read ); + + //debug_printf("Received LED update from tile %x\n", xCmd.tile); + + mask = 1 << xCmd.led; + if (xCmd.value == LED_ON) + { + led_bitmap |= mask; + } + else if (xCmd.value == LED_OFF) + { + led_bitmap &= mask; + } + else if (xCmd.value == LED_TOGGLE) + { + led_bitmap ^= mask; + } + + led_driver( led_bitmap ); +} + +/* ParTest contains FreeRTOS standard parallel port IO routines. */ + +void vParTestInitialiseXCORE( int tile, chanend_t xTile0Chan, chanend_t xTile1Chan, chanend_t xTile2Chan, chanend_t xTile3Chan ) +{ + this_tile = tile; + + if( tile == 0 ) + { + c_read = chanend_alloc(); + chanend_out_word(xTile1Chan, c_read); + + c_write = chanend_alloc(); + + triggerable_setup_interrupt_callback( c_read, NULL, RTOS_INTERRUPT_CALLBACK( pxLEDUpdateISR ) ); + triggerable_enable_trigger( c_read ); + } + else + { + c_read = chanend_in_word(xTile0Chan); + c_write = chanend_alloc(); + } + + chanend_set_dest(c_write, c_read); +} + +/*-----------------------------------------------------------*/ + +void vParTestSetLED( UBaseType_t uxLED, BaseType_t xValue ) +{ + uint32_t ulState; + + //debug_printf("tile %d sending led\n", this_tile); + + led_cmd_t xCmd; + + xCmd.led = uxLED; + xCmd.value = xValue; + xCmd.tile = this_tile; + + ulState = portDISABLE_INTERRUPTS(); + chanend_out_word( c_write, xCmd.raw ); + chanend_out_end_token( c_write ); + portRESTORE_INTERRUPTS(ulState); +} + +/*-----------------------------------------------------------*/ + +void vParTestToggleLED( UBaseType_t uxLED ) +{ + vParTestSetLED( uxLED, LED_TOGGLE ); +} diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/prvRegisterCheck_asm1.S b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/prvRegisterCheck_asm1.S new file mode 100644 index 000000000..65dd6f4f3 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/prvRegisterCheck_asm1.S @@ -0,0 +1,104 @@ +// Copyright (c) 2019, XMOS Ltd, All rights reserved + + .text + .issue_mode single + .globl prvRegisterCheck_asm1 + .align 4 + .type prvRegisterCheck_asm1,@function + .cc_top prvRegisterCheck_asm1.function,prvRegisterCheck_asm1 + + #define NSTACKWORDS 9 + +/* +void prvRegisterCheck_asm1( void ); +*/ +prvRegisterCheck_asm1: + ENTSP_lu6 NSTACKWORDS + + stw r4, sp[1] + stw r5, sp[2] + stw r6, sp[3] + stw r7, sp[4] + stw r8, sp[5] + stw r9, sp[6] + stw r10, sp[7] + stw r11, sp[8] + + /* Load known values */ + /* Since eq can only do immediates 0-11, load values 0-11*/ + ldc r0, 9 + ldc r1, 3 + ldc r2, 2 + ldc r3, 11 + ldc r4, 4 + ldc r5, 6 + ldc r6, 10 + ldc r7, 8 + ldc r8, 7 + ldc r9, 1 + ldc r10, 0 + ldc r11, 5 + +forever: + /* Verify values are unchanged */ + /* Since we cannot compare without clobbering, we will use r11 for + all comparisons and restore its value */ + + eq r11, r0, 9 + bf r11, failure + eq r11, r1, 3 + bf r11, failure + eq r11, r2, 2 + bf r11, failure + eq r11, r3, 11 + bf r11, failure + eq r11, r4, 4 + bf r11, failure + eq r11, r5, 6 + bf r11, failure + eq r11, r6, 10 + bf r11, failure + eq r11, r7, 8 + bf r11, failure + eq r11, r8, 7 + bf r11, failure + eq r11, r9, 1 + bf r11, failure + eq r11, r10, 0 + bf r11, failure + + /* r11 should equal 1; therefore, adding 4 to it should + make it 5, the expected value, for this final comparison */ + add r11, r11, 4 + eq r11, r11, 5 + bf r11, failure + + /* Repeat */ + bu forever + +failure: + ldw r4, sp[1] + ldw r5, sp[2] + ldw r6, sp[3] + ldw r7, sp[4] + ldw r8, sp[5] + ldw r9, sp[6] + ldw r10, sp[7] + ldw r11, sp[8] + + retsp NSTACKWORDS + + // RETURN_REG_HOLDER + .cc_bottom prvRegisterCheck_asm1.function + .set prvRegisterCheck_asm1.nstackwords,NSTACKWORDS + .globl prvRegisterCheck_asm1.nstackwords + .set prvRegisterCheck_asm1.maxcores,1 + .globl prvRegisterCheck_asm1.maxcores + .set prvRegisterCheck_asm1.maxtimers,0 + .globl prvRegisterCheck_asm1.maxtimers + .set prvRegisterCheck_asm1.maxchanends,0 + .globl prvRegisterCheck_asm1.maxchanends +.Ltmp0: + .size prvRegisterCheck_asm1, .Ltmp0-prvRegisterCheck_asm1 + + .issue_mode single diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/prvRegisterCheck_asm2.S b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/prvRegisterCheck_asm2.S new file mode 100644 index 000000000..785faec17 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/prvRegisterCheck_asm2.S @@ -0,0 +1,136 @@ +// Copyright (c) 2019, XMOS Ltd, All rights reserved + + .text + .issue_mode single + .globl prvRegisterCheck_asm2 + .align 4 + .type prvRegisterCheck_asm2,@function + .cc_top prvRegisterCheck_asm2.function,prvRegisterCheck_asm2 + + #define NSTACKWORDS 9 + +/* +void prvRegisterCheck_asm2( void ); +*/ +prvRegisterCheck_asm2: + ENTSP_lu6 NSTACKWORDS + + stw r4, sp[1] + stw r5, sp[2] + stw r6, sp[3] + stw r7, sp[4] + stw r8, sp[5] + stw r9, sp[6] + stw r10, sp[7] + stw r11, sp[8] + + /* load known values */ + ldc r0, 0 + mkmsk r1, 1 + mkmsk r2, 2 + mkmsk r3, 3 + mkmsk r4, 4 + mkmsk r5, 5 + mkmsk r6, 6 + mkmsk r7, 7 + mkmsk r8, 8 + mkmsk r9, 16 + mkmsk r10, 24 + mkmsk r11, 32 + +forever: + /* verify values are unchanged */ + /* Since we cannot compare without clobbering, we will use r0 for + all comparisons and restore its value */ + + mkmsk r0, 1 + eq r0, r0, r1 + bt r0, .L0 + bu failure +.L0: + mkmsk r0, 2 + eq r0, r0, r2 + bt r0, .L1 + bu failure +.L1: + mkmsk r0, 3 + eq r0, r0, r3 + bt r0, .L2 + bu failure +.L2: + mkmsk r0, 4 + eq r0, r0, r4 + bt r0, .L3 + bu failure +.L3: + mkmsk r0, 5 + eq r0, r0, r5 + bt r0, .L4 + bu failure +.L4: + mkmsk r0, 6 + eq r0, r0, r6 + bt r0, .L5 + bu failure +.L5: + mkmsk r0, 7 + eq r0, r0, r7 + bt r0, .L6 + bu failure +.L6: + mkmsk r0, 8 + eq r0, r0, r8 + bt r0, .L7 + bu failure +.L7: + mkmsk r0, 16 + eq r0, r0, r9 + bt r0, .L8 + bu failure +.L8: + mkmsk r0, 24 + eq r0, r0, r10 + bt r0, .L9 + bu failure +.L9: + mkmsk r0, 32 + eq r0, r0, r11 + bt r0, .L10 + bu failure +.L10: + /* r0 should equal 1; therefore, subtracting 1 to it should + make it 0, the expected value, for this final comparison */ + sub r0, r0, 1 + eq r0, r0, 0 + bt r0, .L11 + bu failure +.L11: + /* repeat */ + bu forever + +failure: + ldw r4, sp[1] + ldw r5, sp[2] + ldw r6, sp[3] + ldw r7, sp[4] + ldw r8, sp[5] + ldw r9, sp[6] + ldw r10, sp[7] + ldw r11, sp[8] + + retsp NSTACKWORDS + + // RETURN_REG_HOLDER + .cc_bottom prvRegisterCheck_asm2.function + .set prvRegisterCheck_asm2.nstackwords,NSTACKWORDS + .globl prvRegisterCheck_asm2.nstackwords + .set prvRegisterCheck_asm2.maxcores,1 + .globl prvRegisterCheck_asm2.maxcores + .set prvRegisterCheck_asm2.maxtimers,0 + .globl prvRegisterCheck_asm2.maxtimers + .set prvRegisterCheck_asm2.maxchanends,0 + .globl prvRegisterCheck_asm2.maxchanends +.Ltmp0: + .size prvRegisterCheck_asm2, .Ltmp0-prvRegisterCheck_asm2 + + .issue_mode single diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/regtest.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/regtest.c new file mode 100644 index 000000000..53e8b3844 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/regtest.c @@ -0,0 +1,74 @@ +// Copyright (c) 2020, XMOS Ltd, All rights reserved + +/* + * "Reg test" tasks - These fill the registers with known values, then check + * that each register maintains its expected value for the lifetime of the + * task. Each task uses a different set of values. The reg test tasks execute + * with a very low priority, so they get preempted very frequently. A register + * containing an unexpected value is indicative of an error in the context + * switching mechanism. + */ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo file headers. */ +#include "regtest.h" + +/* + * Test tasks that sets registers to known values, then checks to ensure the + * values remain as expected. Test 1 and test 2 use different values. + */ +static void prvRegisterCheck1( void *pvParameters ); +static void prvRegisterCheck2( void *pvParameters ); + +/* Set to a non zero value should an error be found. */ +BaseType_t xRegTestError = pdFALSE; + +/*-----------------------------------------------------------*/ + +void vStartRegTestTasks( UBaseType_t uxPriority ) +{ + xTaskCreate( prvRegisterCheck1, "Reg1", configMINIMAL_STACK_SIZE, NULL, uxPriority, NULL ); + xTaskCreate( prvRegisterCheck2, "Reg2", configMINIMAL_STACK_SIZE, NULL, uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreRegTestTasksStillRunning( void ) +{ +BaseType_t xReturn; + + /* If a register was found to contain an unexpected value then the + xRegTestError variable would have been set to a non zero value. */ + if( xRegTestError == pdFALSE ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvRegisterCheck1( void *pvParameters ) +{ + ( void ) pvParameters; + prvRegisterCheck_asm1(); + xRegTestError = pdTRUE; + for(;;); + /* If we get here, then the check has failed */ +} + +static void prvRegisterCheck2( void *pvParameters ) +{ + ( void ) pvParameters; + prvRegisterCheck_asm2(); + xRegTestError = pdTRUE; + for(;;); + /* If we get here, then the check has failed */ +} + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/regtest.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/regtest.h new file mode 100644 index 000000000..216d9051c --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/regtest/regtest.h @@ -0,0 +1,15 @@ +// Copyright (c) 2020, XMOS Ltd, All rights reserved + +#ifndef REGTEST_H_ +#define REGTEST_H_ + +void vStartRegTestTasks( UBaseType_t uxPriority ); +BaseType_t xAreRegTestTasksStillRunning( void ); + +/* These functions load known values into all general purpose registers +and verify that their integrity remains intact. +If this function ever returns, register values were unexpectedly changed */ +void prvRegisterCheck_asm1( void ); +void prvRegisterCheck_asm2( void ); + +#endif /* REGTEST_H_ */ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/test.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/test.c new file mode 100644 index 000000000..850135233 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/test.c @@ -0,0 +1,759 @@ +// Copyright (c) 2019, XMOS Ltd, All rights reserved + +#include + +#include "FreeRTOS.h" +#include "task.h" +#include + +#include "limits.h" +#include "testing_main.h" + +/* Includes for actual tests */ +#include "AbortDelay.h" +#include "BlockQ.h" +#include "dynamic.h" +#include "countsem.h" +#include "blocktim.h" +#include "death.h" +#include "EventGroupsDemo.h" +#include "flop.h" +#include "GenQTest.h" +#include "integer.h" +#include "IntQueue.h" +#include "IntSemTest.h" +#include "MessageBufferDemo.h" +#include "partest.h" +#include "PollQ.h" +#include "QPeek.h" +#include "QueueOverwrite.h" +#include "QueueSet.h" +#include "QueueSetPolling.h" +#include "recmutex.h" +#include "semtest.h" +#include "StreamBufferDemo.h" +#include "StreamBufferInterrupt.h" +#include "TaskNotify.h" +#include "TaskNotifyArray.h" +#include "TimerDemo.h" +#include "regtest.h" + +void vParTestInitialiseXCORE( int tile, chanend_t xTile0Chan, chanend_t xTile1Chan, chanend_t xTile2Chan, chanend_t xTile3Chan ); +#define vParTestInitialise vParTestInitialiseXCORE + +/* Flag for errors occuring locally */ +static BaseType_t xMallocError = pdFALSE; +static BaseType_t xIdleError = pdFALSE; +static BaseType_t xStackOverflowError = pdFALSE; + +/* The xcore tile this instance is running on */ +static int tile_g; + +/* Idle hook counter */ +static unsigned long ulCnt = 0; + +#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) + /* + * The 'Check' task function. Which verifies that no errors are present. + */ + static void vErrorChecks( void *pvParameters ); +#endif + +#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) + /* + * The task that implements the Blinky demo. + */ + static void vBlinkyDemo( void *pvParameters ); +#endif + +/* + * The idle task hook - in which the integer task is implemented. See the + * explanation at the top of the file. + */ +void vApplicationIdleHook( void ); + +#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) + /* + * Checks the unique counts of other tasks to ensure they are still operational. + */ + static uint32_t prvCheckTasks( int tile, uint32_t ulErrorFound ); +#endif + +/* + * Setup the hardware. + */ +static void prvSetupHardware( int tile, chanend_t xTile0Chan, chanend_t xTile1Chan, chanend_t xTile2Chan, chanend_t xTile3Chan ); + +/*-----------------------------------------------------------*/ + +void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, + StackType_t **ppxIdleTaskStackBuffer, + uint32_t *pulIdleTaskStackSize ) +{ + static StaticTask_t xIdleTaskTCB; + static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; +} + +/*-----------------------------------------------------------*/ + +void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, + StackType_t **ppxTimerTaskStackBuffer, + uint32_t *pulTimerTaskStackSize ) +{ + static StaticTask_t xTimerTaskTCB; + static StackType_t uxTimerTaskStack[ configMINIMAL_STACK_SIZE ]; + + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + + *pulTimerTaskStackSize = configMINIMAL_STACK_SIZE; +} + +/*-----------------------------------------------------------*/ + +int c_main( int tile, chanend_t xTile0Chan, chanend_t xTile1Chan, chanend_t xTile2Chan, chanend_t xTile3Chan ) +{ + prvSetupHardware( tile, xTile0Chan, xTile1Chan, xTile2Chan, xTile3Chan ); + + tile_g = tile; + + #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) + { + switch( tile ) + { + case 0: + xTaskCreate( vBlinkyDemo, "Blinky", portTASK_STACK_DEPTH( vBlinkyDemo ), &tile, tskIDLE_PRIORITY, NULL ); + break; + case 1: + xTaskCreate( vBlinkyDemo, "Blinky", portTASK_STACK_DEPTH( vBlinkyDemo ), &tile, tskIDLE_PRIORITY + 1, NULL ); + break; + default: + _Exit(0); /* Invalid tile */ + break; + } + } + #else + { + /* Create the standard demo tasks */ + switch( tile ) + { + case 0: + /* Tasks to only run on tile 0 go here */ + #if( testingmainENABLE_ABORT_DELAY_TASKS == 1 ) + vCreateAbortDelayTasks(); + #endif + + #if( testingmainENABLE_BLOCKING_QUEUE_TASKS == 1 ) + vStartBlockingQueueTasks( mainBLOCKING_Q_TASKS_PRIORITY ); + #endif + + #if( testingmainENABLE_BLOCK_TIME_TASKS == 1 ) + vCreateBlockTimeTasks(); + #endif + + #if( testingmainENABLE_COUNT_SEMAPHORE_TASKS == 1 ) + vStartCountingSemaphoreTasks(); + #endif + + #if( testingmainENABLE_DYNAMIC_PRIORITY_TASKS == 1 ) + vStartDynamicPriorityTasks(); + #endif + + #if( testingmainENABLE_EVENT_GROUP_TASKS == 1 ) + vStartEventGroupTasks(); + #endif + + #if( testingmainENABLE_INTERRUPT_QUEUE_TASKS == 1 ) + vStartInterruptQueueTasks(); + #endif + + #if( testingmainENABLE_FLOP_MATH_TASKS == 1 ) + vStartMathTasks( mainFLOP_TASKS_PRIORITY ); + #endif + + #if( testingmainENABLE_INT_MATH_TASKS == 1 ) + vStartIntegerMathTasks( mainINT_MATH_PRIORITY ); + #endif + /* End tile 0 tasks */ + #if ( testingmainNUM_TILES > 1 ) + break; + case 1: + #endif + /* Tasks to only run on tile 1 go here, + but will run on tile 0 if tiles < 2 */ + + #if( testingmainENABLE_GENERIC_QUEUE_TASKS == 1 ) + vStartGenericQueueTasks( mainGENERIC_Q_TASKS_PRIORITY ); + #endif + + #if( testingmainENABLE_INTERRUPT_SEMAPHORE_TASKS == 1 ) + vStartInterruptSemaphoreTasks(); + #endif + + #if( testingmainENABLE_MESSAGE_BUFFER_TASKS == 1 ) + vStartMessageBufferTasks( mainMESSAGE_BUFFER_STACK_SIZE ); + #endif + + #if( testingmainENABLE_POLLED_QUEUE_TASKS == 1 ) + vStartPolledQueueTasks( mainPOLLED_QUEUE_TASKS_PRIORITY ); + #endif + + #if( testingmainENABLE_QUEUE_PEEK_TASKS == 1 ) + vStartQueuePeekTasks(); + #endif + + #if( testingmainENABLE_QUEUE_OVERWRITE_TASKS == 1 ) + vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_TASKS_PRIORITY ); + #endif + + #if( testingmainENABLE_QUEUE_SET_TASKS == 1 ) + vStartQueueSetTasks(); + #endif + + #if( testingmainENABLE_QUEUE_SET_POLLING_TASKS == 1 ) + vStartQueueSetPollingTask(); + #endif + + #if( testingmainENABLE_RECURSIVE_MUTEX_TASKS == 1 ) + vStartRecursiveMutexTasks(); + #endif + + #if( testingmainENABLE_SEMAPHORE_TASKS == 1 ) + vStartSemaphoreTasks( mainSEMAPHORE_TASKS_PRIORITY ); + #endif + + #if( testingmainENABLE_STREAMBUFFER_TASKS == 1 ) + vStartStreamBufferTasks(); + #endif + + #if( testingmainENABLE_STREAMBUFFER_INTERRUPT_TASKS == 1 ) + vStartStreamBufferInterruptDemo(); + #endif + + #if( testingmainENABLE_TASK_NOTIFY_TASKS == 1 ) + vStartTaskNotifyTask(); + #endif + + #if( testingmainENABLE_TASK_NOTIFY_ARRAY_TASKS == 1 ) + vStartTaskNotifyArrayTask(); + #endif + + #if( testingmainENABLE_TIMER_DEMO_TASKS == 1 ) + vStartTimerDemoTask( mainTIMER_DEMO_TASK_FREQ ); + #endif + + /* End tile 1 tasks */ + break; + default: + _Exit(0); /* Invalid tile */ + break; + } + + /* Tasks below here should be run on every tile */ + #if( testingmainENABLE_REG_TEST_TASKS == 1 ) + vStartRegTestTasks( mainREGTEST_PRIORITY ); + #endif + + /* Start the locally defined tasks. There is also a task implemented as + the idle hook. */ + xTaskCreate( vErrorChecks, "Check", portTASK_STACK_DEPTH( vErrorChecks ), &tile, mainCHECK_TASK_PRIORITY, NULL ); + + /* Must be the last demo created. */ + #if( testingmainENABLE_DEATH_TASKS == 1 ) + vCreateSuicidalTasks( mainDEATH_PRIORITY ); + #endif + } + #endif /* #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) */ + + /* All the tasks have been created - start the scheduler. */ + rtos_printf( "Starting Scheduler\n" ); + vTaskStartScheduler(); + + /* Should not reach here! */ + for( ;; ); +} + +/*-----------------------------------------------------------*/ + +#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) + static void vBlinkyDemo( void *pvParameters ) + { + int tile = ( ( int * ) pvParameters )[0]; + + for( ;; ) + { + /* Wait for a second. */ + vTaskDelay( pdMS_TO_TICKS( 1000 )); + + /* Toggle the LED each cycle round. */ + vParTestToggleLED( tile ); + } + } +#endif + +/*-----------------------------------------------------------*/ + +#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) + static void vErrorChecks( void *pvParameters ) + { + TickType_t xDelayPeriod = mainCHECK_PERIOD; + TickType_t xLastExecutionTime; + uint32_t ulErrorFound = 0, ulLastErrorFound = 0; + int tile = ( ( int * ) pvParameters )[0]; + int i = 0; + + xLastExecutionTime = xTaskGetTickCount(); + + for( ;; ) + { + /* Delay until it is time to execute again. The delay period is + shorter following an error. */ + vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod ); + + if( xDelayPeriod == mainERROR_CHECK_PERIOD ) + { + i++; + if( i == mainCHECK_PERIOD / mainERROR_CHECK_PERIOD ) + { + i = 0; + } + } + + if( i == 0) + { + /* Check all the demo application tasks are executing without + error. If an error is found the delay period is shortened - this + has the effect of increasing the flash rate of the 'check' task + LED. */ + ulErrorFound = prvCheckTasks( tile, ulErrorFound ); + if( ulLastErrorFound != ulErrorFound ) + { + /* An error has been detected in one of the tasks - flash faster. */ + xDelayPeriod = mainERROR_CHECK_PERIOD; + rtos_printf("An Error has occured on tile %d - %08x\n", tile, ulErrorFound); + ulLastErrorFound = ulErrorFound; + } + } + + /* Toggle the LED each cycle round. */ + vParTestToggleLED( tile ); + } + } +#endif +/*-----------------------------------------------------------*/ + +/* Setup any hardware specific to tests here */ +static void prvSetupHardware( int tile, chanend_t xTile0Chan, chanend_t xTile1Chan, chanend_t xTile2Chan, chanend_t xTile3Chan ) +{ + vParTestInitialise( tile, xTile0Chan, xTile1Chan, xTile2Chan, xTile3Chan ); +} + +/*-----------------------------------------------------------*/ + +#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) + static uint32_t prvCheckTasks( int tile, uint32_t ulErrorFound ) + { + switch( tile ) + { + case 0: + /* Checks to only run on tile 0 go here */ + #if( testingmainENABLE_ABORT_DELAY_TASKS == 1 ) + if( xAreAbortDelayTestTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Abort delay task failed\n" ); + ulErrorFound |= 1UL << 0UL; + } + #endif + + #if( testingmainENABLE_BLOCKING_QUEUE_TASKS == 1 ) + if( xAreBlockingQueuesStillRunning() != pdTRUE ) + { + rtos_printf( "Blocking queues task failed\n" ); + ulErrorFound |= 1UL << 1UL; + } + #endif + + #if( testingmainENABLE_BLOCK_TIME_TASKS == 1 ) + if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Block time task failed\n" ); + ulErrorFound |= 1UL << 2UL; + } + #endif + + #if( testingmainENABLE_COUNT_SEMAPHORE_TASKS == 1 ) + if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Counting semaphore task failed\n" ); + ulErrorFound |= 1UL << 3UL; + } + #endif + + #if( testingmainENABLE_DYNAMIC_PRIORITY_TASKS == 1 ) + if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Dynamic priority task failed\n" ); + ulErrorFound |= 1UL << 4UL; + } + #endif + + #if( testingmainENABLE_EVENT_GROUP_TASKS == 1 ) + if( xAreEventGroupTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Event groups task failed\n" ); + ulErrorFound |= 1UL << 5UL; + } + #endif + + #if( testingmainENABLE_INTERRUPT_QUEUE_TASKS == 1 ) + if( xAreIntQueueTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Interrupt queue task failed\n" ); + ulErrorFound |= 1UL << 6UL; + } + #endif + + #if( testingmainENABLE_FLOP_MATH_TASKS == 1 ) + if( xAreMathsTaskStillRunning() != pdTRUE ) + { + rtos_printf( "Float math task failed\n" ); + ulErrorFound |= 1UL << 21UL; + } + #endif + + #if( testingmainENABLE_INT_MATH_TASKS == 1 ) + if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) + { + rtos_printf( "Integer math task failed\n" ); + ulErrorFound |= 1UL << 22UL; + } + #endif + /* End tile 0 checks */ + #if ( testingmainNUM_TILES > 1 ) + break; + case 1: + #endif + /* Checks to only run on tile 1 go here, + but will run on tile 0 if tiles < 2 */ + #if( testingmainENABLE_GENERIC_QUEUE_TASKS == 1 ) + if( xAreGenericQueueTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Generic queue task failed\n" ); + ulErrorFound |= 1UL << 7UL; + } + #endif + + #if( testingmainENABLE_INTERRUPT_SEMAPHORE_TASKS == 1 ) + if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Interrupt semaphore task failed\n" ); + ulErrorFound |= 1UL << 8UL; + } + #endif + + #if( testingmainENABLE_MESSAGE_BUFFER_TASKS == 1 ) + if( xAreMessageBufferTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Message buffer task failed\n" ); + ulErrorFound |= 1UL << 9UL; + } + #endif + + #if( testingmainENABLE_POLLED_QUEUE_TASKS == 1 ) + if( xArePollingQueuesStillRunning() != pdTRUE ) + { + rtos_printf( "Polling queues task failed\n" ); + ulErrorFound |= 1UL << 10UL; + } + #endif + + #if( testingmainENABLE_QUEUE_PEEK_TASKS == 1 ) + if( xAreQueuePeekTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Queue peek task failed\n" ); + ulErrorFound |= 1UL << 11UL; + } + #endif + + #if( testingmainENABLE_QUEUE_OVERWRITE_TASKS == 1 ) + if( xIsQueueOverwriteTaskStillRunning() != pdTRUE ) + { + rtos_printf( "Queue overwrite task failed\n" ); + ulErrorFound |= 1UL << 12UL; + } + #endif + + #if( testingmainENABLE_QUEUE_SET_TASKS == 1 ) + if( xAreQueueSetTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Queue set task failed\n" ); + ulErrorFound |= 1UL << 13UL; + } + #endif + + #if( testingmainENABLE_QUEUE_SET_POLLING_TASKS == 1 ) + if( xAreQueueSetPollTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Queue set poll task failed\n" ); + ulErrorFound |= 1UL << 14UL; + } + #endif + + #if( testingmainENABLE_RECURSIVE_MUTEX_TASKS == 1 ) + if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Recursive mutex task failed\n" ); + ulErrorFound |= 1UL << 15UL; + } + #endif + + #if( testingmainENABLE_SEMAPHORE_TASKS == 1 ) + if( xAreSemaphoreTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Semaphore task failed\n" ); + ulErrorFound |= 1UL << 16UL; + } + #endif + + #if( testingmainENABLE_STREAMBUFFER_TASKS == 1 ) + if( xAreStreamBufferTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Streambuffer task failed\n" ); + ulErrorFound |= 1UL << 17UL; + } + #endif + + #if( testingmainENABLE_STREAMBUFFER_INTERRUPT_TASKS == 1 ) + if( xIsInterruptStreamBufferDemoStillRunning() != pdTRUE ) + { + rtos_printf( "ISR Streambuffer task failed\n" ); + ulErrorFound |= 1UL << 18UL; + } + #endif + + #if( testingmainENABLE_TASK_NOTIFY_TASKS == 1 ) + if( xAreTaskNotificationTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Task notification task failed\n" ); + ulErrorFound |= 1UL << 19UL; + } + #endif + + #if( testingmainENABLE_TASK_NOTIFY_ARRAY_TASKS == 1 ) + if( xAreTaskNotificationArrayTasksStillRunning() != pdTRUE ) + { + rtos_printf( "Task notification array task failed\n" ); + ulErrorFound |= 1UL << 28UL; + } + #endif + + #if( testingmainENABLE_TIMER_DEMO_TASKS == 1 ) + if( xAreTimerDemoTasksStillRunning( mainTIMER_DEMO_TASK_FREQ ) != pdTRUE ) + { + rtos_printf( "Timer demo task failed\n" ); + ulErrorFound |= 1UL << 20UL; + } + #endif + + /* End tile 1 checks */ + break; + default: + _Exit(0); /* Invalid tile */ + break; + } + + /* Tasks below here should be run on every tile */ + #if( testingmainENABLE_DEATH_TASKS == 1 ) + if( xIsCreateTaskStillRunning() != pdTRUE ) + { + ulErrorFound |= 1UL << 23UL; + rtos_printf( "Death task failed\n" ); + } + #endif + + #if( testingmainENABLE_REG_TEST_TASKS == 1 ) + if( xAreRegTestTasksStillRunning() != pdTRUE ) + { + ulErrorFound |= 1UL << 24UL; + rtos_printf( "Regtest task failed\n" ); + } + #endif + + if( xMallocError != pdFALSE ) + { + ulErrorFound |= 1UL << 25UL; + rtos_printf( "Malloc failed\n" ); + } + + if( xStackOverflowError != pdFALSE ) + { + ulErrorFound |= 1UL << 26UL; + rtos_printf( "Stack overflow detected\n" ); + } + + if( xIdleError != pdFALSE ) + { + ulErrorFound |= 1UL << 27UL; + rtos_printf( "Idle task math failed\n" ); + } + + return ulErrorFound; + } +#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. 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). */ + + rtos_printf( "Malloc Failed\n" ); + uint32_t ulState = portDISABLE_INTERRUPTS(); + xMallocError = pdTRUE; + portRESTORE_INTERRUPTS( ulState ); + for( ;; ); +} + +/*-----------------------------------------------------------*/ + +void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *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. */ + + rtos_printf("Stack Overflow %s\n", pcTaskName ); + uint32_t ulState = portDISABLE_INTERRUPTS(); + xStackOverflowError = pdTRUE; + portRESTORE_INTERRUPTS( ulState ); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationMinimalIdleHook( void ) +{ + //TaskStatus_t status; + //vTaskGetInfo(NULL, &status, pdTRUE, eInvalid); + //rtos_printf("%s on Core %u\n", status.pcTaskName, portGET_CORE_ID()); +} + +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ +volatile BaseType_t xValue; +uint32_t ulState; + + xValue = intCONST1; + xValue += intCONST2; + xValue *= intCONST3; + xValue /= intCONST4; + + if( xValue != intEXPECTED_ANSWER ) + { + rtos_printf("Error Occured at Idle Count: %u\n", ulCnt); + xIdleError = pdTRUE; + } + + #if( configUSE_PREEMPTION == 0 ) + { + taskYIELD(); + } + #endif + + ulState = portDISABLE_INTERRUPTS(); + ulCnt++; + portRESTORE_INTERRUPTS(ulState); +} + +/*-----------------------------------------------------------*/ + +void vApplicationTickHook( void ) +{ + #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) + { + switch (tile_g) + { + case 0: + #if( testingmainENABLE_EVENT_GROUP_TASKS == 1 ) + /* Call the periodic event group from ISR demo. */ + vPeriodicEventGroupsProcessing(); + #endif + + #if ( testingmainNUM_TILES > 1 ) + break; + case 1: + #endif + #if( testingmainENABLE_QUEUE_OVERWRITE_TASKS == 1 ) + /* Call the periodic queue overwrite from ISR demo. */ + vQueueOverwritePeriodicISRDemo(); + #endif + + #if( testingmainENABLE_INTERRUPT_SEMAPHORE_TASKS == 1 ) + /* Use mutexes from interrupts. */ + vInterruptSemaphorePeriodicTest(); + #endif + + #if( testingmainENABLE_QUEUE_SET_TASKS == 1 ) + /* Use queue sets from interrupts. */ + vQueueSetAccessQueueSetFromISR(); + #endif + + #if( testingmainENABLE_QUEUE_SET_POLLING_TASKS == 1 ) + /* Use queue sets from interrupts. */ + vQueueSetPollingInterruptAccess(); + #endif + + #if( testingmainENABLE_TIMER_DEMO_TASKS == 1 ) + /* The full demo includes a software timer demo/test that requires + prodding periodically from the tick interrupt. */ + vTimerPeriodicISRTests(); + #endif + + #if( testingmainENABLE_TASK_NOTIFY_TASKS == 1 ) + /* Use task notifications from an interrupt. */ + xNotifyTaskFromISR(); + #endif + + #if( testingmainENABLE_TASK_NOTIFY_ARRAY_TASKS == 1 ) + /* Use task notifications from an interrupt. */ + xNotifyArrayTaskFromISR(); + #endif + + #if( testingmainENABLE_STREAMBUFFER_TASKS == 1 ) + /* Writes to stream buffer byte by byte to test the stream buffer trigger + level functionality. */ + vPeriodicStreamBufferProcessing(); + #endif + + #if( testingmainENABLE_STREAMBUFFER_INTERRUPT_TASKS == 1 ) + /* Writes a string to a string buffer four bytes at a time to demonstrate + a stream being sent from an interrupt to a task. */ + vBasicStreamBufferSendFromISR(); + #endif + + break; + } + } + #endif /* #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 ) */ +} + +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/testing_main.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/testing_main.h new file mode 100644 index 000000000..dc07e61f1 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/RTOSDemo/src/testing_main.h @@ -0,0 +1,92 @@ +// Copyright (c) 2019, XMOS Ltd, All rights reserved + +#ifndef TESTING_MAIN_H_ +#define TESTING_MAIN_H_ + +/* Controls whether to create blinky demo or the full demo. */ +#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 + +#define testingmainNUM_TILES 2 +#define testingmainENABLE_XC_TASKS 1 + +/* TODO: Update to be package specific check */ +#if ( testingmainNUM_TILES > 2 ) +#error Tiles must be less than 3. +#endif + +/* Tests to be run */ + +/*** These tests run on all tiles ***/ +#define testingmainENABLE_REG_TEST_TASKS 1 + +/* Death cannot be run with any demo that creates or destroys tasks */ +#define testingmainENABLE_DEATH_TASKS 1 + +/*** These tests run on tile 0 ***/ +#define testingmainENABLE_ABORT_DELAY_TASKS 1 +#define testingmainENABLE_BLOCKING_QUEUE_TASKS 1 +#define testingmainENABLE_BLOCK_TIME_TASKS 1 +#define testingmainENABLE_COUNT_SEMAPHORE_TASKS 1 +#define testingmainENABLE_DYNAMIC_PRIORITY_TASKS 1 +#define testingmainENABLE_EVENT_GROUP_TASKS 1 +#define testingmainENABLE_INTERRUPT_QUEUE_TASKS 1 +#define testingmainENABLE_FLOP_MATH_TASKS 1 +#define testingmainENABLE_INT_MATH_TASKS 1 + +/*** These tests run on tile 1 ***/ +#define testingmainENABLE_GENERIC_QUEUE_TASKS 1 +#define testingmainENABLE_INTERRUPT_SEMAPHORE_TASKS 1 +#define testingmainENABLE_MESSAGE_BUFFER_TASKS 1 +#define testingmainENABLE_POLLED_QUEUE_TASKS 1 +#define testingmainENABLE_QUEUE_PEEK_TASKS 1 +#define testingmainENABLE_QUEUE_OVERWRITE_TASKS 1 +#define testingmainENABLE_QUEUE_SET_TASKS 1 +#define testingmainENABLE_QUEUE_SET_POLLING_TASKS 1 +#define testingmainENABLE_RECURSIVE_MUTEX_TASKS 1 +#define testingmainENABLE_SEMAPHORE_TASKS 1 +#define testingmainENABLE_STREAMBUFFER_TASKS 1 +#define testingmainENABLE_STREAMBUFFER_INTERRUPT_TASKS 1 +#define testingmainENABLE_TASK_NOTIFY_TASKS 1 +#define testingmainENABLE_TASK_NOTIFY_ARRAY_TASKS 1 +#define testingmainENABLE_TIMER_DEMO_TASKS 1 + +/*** These tests run on all tiles ***/ +#define mainREGTEST_PRIORITY ( tskIDLE_PRIORITY + 0 ) + +/* Death cannot be run with any demo that creates or destroys tasks */ +#define mainDEATH_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* Priorities assigned to demo application tasks. */ +#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) + +/*** These tests run on tile 0 ***/ +#define mainBLOCKING_Q_TASKS_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainINT_MATH_PRIORITY ( tskIDLE_PRIORITY + 0 ) +#define mainFLOP_TASKS_PRIORITY ( tskIDLE_PRIORITY + 0 ) + +/*** These tests run on tile 1 ***/ +#define mainGENERIC_Q_TASKS_PRIORITY ( tskIDLE_PRIORITY + 0 ) +#define mainPOLLED_QUEUE_TASKS_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainQUEUE_OVERWRITE_TASKS_PRIORITY ( tskIDLE_PRIORITY + 0 ) +#define mainSEMAPHORE_TASKS_PRIORITY ( tskIDLE_PRIORITY + 2 ) + +/* Other demo application specific defines */ +#define mainMESSAGE_BUFFER_STACK_SIZE configMINIMAL_STACK_SIZE +#define mainTIMER_DEMO_TASK_FREQ ( ( TickType_t ) 10000 / configTICK_RATE_HZ ) +#define tmrTIMER_TEST_TASK_STACK_SIZE portTASK_STACK_DEPTH(prvTimerTestTask) + +/* The constants used in the idle task calculation. */ +#define intCONST1 ( ( BaseType_t ) 346 ) +#define intCONST2 ( ( BaseType_t ) 74324 ) +#define intCONST3 ( ( BaseType_t ) -2 ) +#define intCONST4 ( ( BaseType_t ) 9 ) +#define intEXPECTED_ANSWER ( ( BaseType_t ) ( ( intCONST1 + intCONST2 ) * intCONST3 ) / intCONST4 ) + +/* The check task periodically checks that all the other tasks +are operating without error. If no errors are found the LED +is toggled with mainCHECK_PERIOD frequency. If an error is found +then the toggle rate changes to mainERROR_CHECK_PERIOD. */ +#define mainCHECK_PERIOD pdMS_TO_TICKS(3000) +#define mainERROR_CHECK_PERIOD pdMS_TO_TICKS(200) + +#endif /* TESTING_MAIN_H_ */ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/.cproject b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/.cproject new file mode 100644 index 000000000..51427bf15 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/.cproject @@ -0,0 +1,874 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/.project b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/.project new file mode 100644 index 000000000..7ad551b18 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/.project @@ -0,0 +1,44 @@ + + + lib_rtos_support + + + lib_xcore_c + FreeRTOS + + + + com.xmos.cdt.core.ProjectInfoSyncBuilder + + + + + com.xmos.cdt.core.ModulePathBuilder + + + + + com.xmos.cdt.core.LegacyProjectCheckerBuilder + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + com.xmos.cdt.core.XdeProjectNature + + diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_cores.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_cores.h new file mode 100644 index 000000000..4ad8c8dc6 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_cores.h @@ -0,0 +1,54 @@ +// Copyright 2019-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef RTOS_CORES_H_ +#define RTOS_CORES_H_ + +/* The maximum number of cores an SMP RTOS may use */ +#define RTOS_MAX_CORE_COUNT 8 + +#if __XC__ +extern "C" { +#endif //__XC__ + +/** + * The RTOS must call this once for each core it + * starts its scheduler on. + * + * \returns the ID of the core it is called on + */ +int rtos_core_register(void); + +/** + * Returns the ID of the calling core. + * + * rtos_core_register() must have been previously + * called on the calling core. + * + * \returns the ID of the calling core. + */ +int rtos_core_id_get(void); + +/** + * Translates an RTOS core ID into the logical "xcore" + * core ID. + * + * \param core_id An RTOS core ID + * + * \returns the logical "xcore" core ID + */ +int rtos_logical_core_id_get(int core_id); + +/** + * Returns the number of cores the RTOS is currently + * running on. + * + * \returns the number of cores the RTOS is running on. + */ +int rtos_core_count(void); + +#ifdef __XC__ +} +#endif //__XC__ + +#endif /* RTOS_CORES_H_ */ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_interrupt.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_interrupt.h new file mode 100644 index 000000000..e9e6da6a7 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_interrupt.h @@ -0,0 +1,225 @@ +// Copyright 2019-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef RTOS_INTERRUPT_H_ +#define RTOS_INTERRUPT_H_ + +#include +#include + +#include "rtos_interrupt_impl.h" +#include "rtos_macros.h" + +/** Define the function that enters the RTOS kernel and begins the scheduler. + * This should only be used by the RTOS entry function that starts the scheduler. + * + * This macro will define two functions for you: + * - An ordinary function that may be called directly + * Its signature will be '*ret* *root_function* ( *...* )' + * - A function that will also reserve space for and set up a stack + * for handling RTOS interrupts. + * The function name is accessed using the RTOS_KERNEL_ENTRY() macro + * + * You would normally use this macro only on the definition of the RTOS entry + * function that starts the scheduler. + * + * The interrupt stack (kernel stack) is created on the core's stack with the + * ksp and sp being modified as necessary. When the function exits, neither the + * kernel stack nor ksp is valid. + * + * The kernel stack allocated has enough space for the interrupt_callback_t + * function (+callees) in the rtos_isr 'group'. The use of the 'group' identifier + * allows a kernel stack to be no larger than that required by its greediest member. + * + * **The kernel stack is not re-entrant so kernel mode must not be masked + * from within an interrupt_callback_t** + * + * Example usage: \code + * DEFINE_RTOS_KERNEL_ENTRY(void, vPortStartSchedulerOnCore, void) + * { + * // This is the body of 'void vPortStartSchedulerOnCore(void)' + * } + * \endcode + * + * \param ret the return type of the ordinary function + * \param root_function the name of the ordinary function + * \param ... the arguments of the ordinary function + */ +#define DEFINE_RTOS_KERNEL_ENTRY(ret, root_function, ...) \ + _DEFINE_RTOS_KERNEL_ENTRY(ret, root_function, __VA_ARGS__) + +/** Declare an RTOS interrupt permitting function + * + * Use this macro when you require a declaration of your RTOS kernel entry function. + * This should only be used by the RTOS entry function that starts the scheduler. + * + * Example usage: \code + * // In another file: + * // DEFINE_RTOS_KERNEL_ENTRY(void, vPortStartSchedulerOnCore, void) { ... } + * DECLARE_RTOS_KERNEL_ENTRY(void, vPortStartSchedulerOnCore, void); + * ... + * par { + * RTOS_KERNEL_ENTRY(vPortStartSchedulerOnCore)(); + * } + * \endcode + * + * \param ret the return type of the ordinary function + * \param root_function the name of the ordinary function + * \param ... the arguments of the ordinary function + */ +#define DECLARE_RTOS_KERNEL_ENTRY(ret, root_function, ...) \ + _XCORE_DECLARE_INTERRUPT_PERMITTED(ret, root_function, __VA_ARGS__) + +/** The name of the defined RTOS kernel entry function + * + * Use this macro for retriving the name of the declared RTOS kernel entry function. + * This is the name used to invoke the function. + * + * \return the name of the defined kernel entry function + */ +#define RTOS_KERNEL_ENTRY(root_function) _XCORE_INTERRUPT_PERMITTED(root_function) + + +/** Define an RTOS interrupt handling function + * + * This macro will define two functions for you: + * - An ordinary function that may be called directly + * Its signature will be 'void *intrpt* ( void\* *data* )' + * - An interrupt_callback_t function for passing to a res_setup_interrupt_callback function. + * The interrupt_callback_t function name is accessed using the RTOS_INTERRUPT_CALLBACK() macro + * + * **The kernel stack is not re-entrant so kernel mode must not be masked + * from within an interrupt_callback_t** + * + * Example usage: \code + * DEFINE_RTOS_INTERRUPT_CALLBACK(myfunc, arg) + * { + * // This is the body of 'void myfunc(void* arg)' + * } + * \endcode + * + * \param intrpt this is the name of the ordinary function + * \param data the name to use for the void* argument + */ +#define DEFINE_RTOS_INTERRUPT_CALLBACK(intrpt, data) \ + _DEFINE_RTOS_INTERRUPT_CALLBACK(intrpt, data) + +/** Declare an RTOS interrupt handling function + * + * Use this macro when you require a declaration of your interrupt function types + * + * Example usage: \code + * DECLARE_RTOS_INTERRUPT_CALLBACK(myfunc, arg); + * chanend_setup_interrupt_callback(c, 0 , RTOS_INTERRUPT_CALLBACK(myfunc)); + * \endcode + * + * \param intrpt this is the name of the ordinary function + * \param data the name to use for the void* argument + */ +#define DECLARE_RTOS_INTERRUPT_CALLBACK(intrpt, data) \ + _DECLARE_RTOS_INTERRUPT_CALLBACK(intrpt, data) + +/** The name of the defined 'interrupt_callback_t' function + * + * Use this macro for retriving the name of the declared RTOS interrupt callback function. + * This is the name that is passed to *res*_setup_interrupt_callback() for registration. + * + * \return the name of the defined interrupt_callback_t function + */ +#define RTOS_INTERRUPT_CALLBACK(intrpt) _XCORE_INTERRUPT_CALLBACK(intrpt) + + +/** + * This function gets the current interrupt mask. + * A non-zero mask value means that interrupts are enabled. + * + * \returns the current interrupt mask. + */ +inline uint32_t rtos_interrupt_mask_get(void) +{ + uint32_t mask; + + asm volatile( + "getsr r11," RTOS_STRINGIFY(XS1_SR_IEBLE_MASK) "\n" + "mov %0, r11" + : "=r"(mask) + : /* no inputs */ + : /* clobbers */ "r11" + ); + + return mask; +} + + /** + * This function masks (disables) all interrupts on the + * calling core. + * + * \returns the previous value of the interrupt mask. + * This value can be passed to rtos_interrupt_mask_set() + * to restore the interrupt mask to its previous state. + */ +inline uint32_t rtos_interrupt_mask_all(void) +{ + uint32_t mask; + + asm volatile( + "getsr r11," RTOS_STRINGIFY(XS1_SR_IEBLE_MASK) "\n" + "mov %0, r11\n" + "clrsr " RTOS_STRINGIFY(XS1_SR_IEBLE_MASK) + : "=r"(mask) + : /* no inputs */ + : /* clobbers */ "r11", "memory" + ); + + return mask; +} + +/** + * This function unmasks (enables) all interrupts on the + * calling core. + */ +inline void rtos_interrupt_unmask_all(void) +{ + asm volatile( + "setsr" RTOS_STRINGIFY(XS1_SR_IEBLE_MASK) + : /* no outputs */ + : /* no inputs */ + : /* clobbers */ "memory" + ); +} + +/** + * This function sets the interrupt mask. + * A non-zero mask value unmasks (enables) interrupts. + * + * \param mask The value to set the interrupt mask to. + */ +inline void rtos_interrupt_mask_set(uint32_t mask) +{ + if (mask != 0) { + rtos_interrupt_unmask_all(); + } +} + +/* + * This function checks to see if it is called from + * within an ISR. + * + * \returns non-zero when called from within an ISR or kcall. + */ +inline uint32_t rtos_isr_running(void) +{ + uint32_t kernel_mode; + + asm volatile( + "getsr r11," RTOS_STRINGIFY(XS1_SR_INK_MASK) "\n" + "mov %0, r11" + : "=r"(kernel_mode) + : /* no inputs */ + : /* clobbers */ "r11" + ); + + return kernel_mode; +} + +#endif /* RTOS_INTERRUPT_H_ */ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_irq.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_irq.h new file mode 100644 index 000000000..5b7c53f6e --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_irq.h @@ -0,0 +1,84 @@ +// Copyright 2019-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef RTOS_IRQ_H_ +#define RTOS_IRQ_H_ + +#include + +/** + * IRQ ISR callback function pointer type. + * + * ISRs registered with the RTOS IRQ system must be + * compatible with this type. + */ +typedef void (*rtos_irq_isr_t)( void *param ); + +/** + * This macro must precede the definition of ISRs that + * get registered with the RTOS IRQ system. + * + * It adds the function to the rtos_irq_isr function pointer + * group which allows the compiler to correctly calculate + * the stack size for ISRs. + */ +#define RTOS_IRQ_ISR_ATTR __attribute__((fptrgroup("rtos_irq_isr"))) + +/** + * This function sends an IRQ to an RTOS core. It may be called both by + * RTOS cores and non-RTOS cores. It must be called by a core on the + * same tile as the core being interrupted. + * + * \param core_id The core ID of the RTOS core to interrupt. The core must have + * previously called rtos_irq_enable. + * \param source_id The ID of source of the IRQ. When called by an RTOS core, + * this must be the core ID of the calling core. + * When called by a non-RTOS core then this must be an ID returned + * by rtos_irq_source_register(). + */ +void rtos_irq(int core_id, int source_id); + + +/** + * This function sends an IRQ to a peripheral on a non-RTOS core. + * It must be called by an RTOS core. The non-RTOS core does not + * need to be on the same tile as the RTOS core. + * + * \param dest_chanend The channel end used by the peripheral to receive + * the interrupt. + */ +void rtos_irq_peripheral(chanend_t dest_chanend); + +/** + * This function registers a non-RTOS IRQ source. The source ID + * returned must be passed to the non-RTOS peripheral that will be + * generating the IRQs. The peripheral can then subsequently send + * IRQs with rtos_irq(). + * + * \param isr The interrupt service routine to run when the IRQ is received. + * \param param A pointer to user data to pass to the ISR. + * \param source_chanend The channel end to use to send the IRQ. + * + * \returns the IRQ source ID that may be passed to rtos_irq() when the + * peripheral needs to send an IRQ. + */ + +int rtos_irq_register(rtos_irq_isr_t isr, void *data, chanend_t source_chanend); + +/** + * This function enables the calling core to receive RTOS IRQs. It + * should be called once during initialization by each RTOS core + * after calling rtos_core_register(). + * + * \param The total number of cores used by the RTOS. + */ +void rtos_irq_enable(int total_rtos_cores); + +/** + * This function checks to see if the IRQ system is ready. + * + * \returns true if all of the cores have enabled IRQs. Otherwise false. + */ +int rtos_irq_ready(void); + +#endif /* RTOS_IRQ_H_ */ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_locks.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_locks.h new file mode 100644 index 000000000..0c5b4539a --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_locks.h @@ -0,0 +1,76 @@ +// Copyright 2019-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef RTOS_LOCKS_H_ +#define RTOS_LOCKS_H_ + +#if !defined(__XC__) + +#include "rtos_support_rtos_config.h" +#include +#include + +#ifndef RTOS_LOCK_COUNT +#error You must define RTOS_LOCK_COUNT in rtos_support_rtos_config.h +#endif + +#if RTOS_LOCK_COUNT == 0 +/* If the RTOS does not need any locks + * that is fine, but the IRQ functions still + * need one. */ +#undef RTOS_LOCK_COUNT +#define RTOS_LOCK_COUNT 1 +#endif + +#if RTOS_LOCK_COUNT > 4 +#error XCORE does not support more than 4 hardware locks +#endif + +void rtos_locks_initialize(void); + +inline int rtos_lock_acquire(int lock_id) +{ + extern lock_t rtos_locks[RTOS_LOCK_COUNT]; + extern int rtos_lock_counters[RTOS_LOCK_COUNT]; + + xassert(lock_id >= 0 && lock_id < RTOS_LOCK_COUNT); + if (rtos_locks[lock_id] != -1) { + lock_acquire(rtos_locks[lock_id]); + rtos_lock_counters[lock_id]++; + } + + return rtos_lock_counters[lock_id]; +} + +/** + * + * \warning Be careful not to release a lock that the calling + * core does not own or else bad things will happen. + * Defining RTOS_LOCKS_SAFE to 1 will enable a check + * to see the lock is owned. If it is not it will + * throw an exception. + */ +inline int rtos_lock_release(int lock_id) +{ + extern lock_t rtos_locks[RTOS_LOCK_COUNT]; + extern int rtos_lock_counters[RTOS_LOCK_COUNT]; + int counter = 0; + + xassert(lock_id >= 0 && lock_id < RTOS_LOCK_COUNT); + if (rtos_locks[lock_id] != -1) { + #if RTOS_LOCKS_SAFE + lock_acquire(rtos_locks[lock_id]); + xassert(rtos_lock_counters[lock_id] > 0); + #endif + counter = --rtos_lock_counters[lock_id]; + if (counter == 0) { + lock_release(rtos_locks[lock_id]); + } + } + + return counter; +} + +#endif // !defined(__XC__) + +#endif /* RTOS_LOCKS_H_ */ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_macros.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_macros.h new file mode 100644 index 000000000..6bef15624 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_macros.h @@ -0,0 +1,39 @@ +// Copyright 2019-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef RTOS_MACROS_H_ +#define RTOS_MACROS_H_ + +#include "rtos_support_rtos_config.h" + +#define RTOS_STRINGIFY_I(...) #__VA_ARGS__ +#define RTOS_STRINGIFY(...) RTOS_STRINGIFY_I(__VA_ARGS__) + +/* + * Inserts a compile time memory barrier + */ +#define RTOS_MEMORY_BARRIER() asm volatile( "" ::: "memory" ) + +/* + * Returns the number of 32-bit stack words required by the given thread entry function. + * + * This will not just "work" if there is any recursion or function pointers in the thread. + * For function pointers the fptrgroup attribute may be used. For recursive functions, the + * "stackfunction" #pragma may be used. + * + * Example FreeRTOS usage: + * xTaskCreate( vTask, "task_name", RTOS_THREAD_STACK_SIZE(vTask), pvParameters, uxPriority, &pxTaskHandle ); + */ +#define RTOS_THREAD_STACK_SIZE(thread_entry) \ + ({ \ + uint32_t stack_size; \ + asm volatile ( \ + "ldc %0, " RTOS_STRINGIFY(thread_entry) ".nstackwords + " RTOS_STRINGIFY(RTOS_SUPPORT_INTERRUPT_STACK_GROWTH) "\n\t" \ + : "=r"(stack_size) /* output 0 is stack_size */ \ + : /* there are no inputs */ \ + : /* nothing gets clobbered */ \ + ); \ + stack_size; \ + }) + +#endif /* RTOS_MACROS_H_ */ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_printf.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_printf.h new file mode 100644 index 000000000..4f9d1c04c --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_printf.h @@ -0,0 +1,122 @@ +// Copyright 2019-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef _rtos_printf_h_ +#define _rtos_printf_h_ + +/** +Debug Printing Module +===================== + +This module provides a lightweight RTOS safe printf function that can +be enabled or disabled via configuration macros. Code can be declared +to be within a "debug unit" (usually a module) and prints can be +enabled/disabled per debug unit. + +This uses the same DEBUG macros as lib_logging to control "debug units", +but implements a slightly more capable and RTOS safe printf function. +It also provides sprintf and snprintf functions. + +**/ + +#include "rtos_support_rtos_config.h" + +#ifdef __rtos_support_conf_h_exists__ +#include "rtos_support_conf.h" +#endif + +#ifndef RTOS_DEBUG_PRINTF_REMAP +#define RTOS_DEBUG_PRINTF_REMAP 0 +#endif + +/* remap calls to debug_printf to rtos_printf */ +#if RTOS_DEBUG_PRINTF_REMAP + + #ifdef _debug_printf_h_ + #error Do not include debug_print.h when using rtos_printf + #endif + + /* Ensure that if debug_print.h is included later that it is ignored */ + #define _debug_printf_h_ + + #define debug_printf rtos_printf + +#endif /* RTOS_DEBUG_PRINTF_REMAP */ + +#ifndef DEBUG_UNIT +#define DEBUG_UNIT APPLICATION +#endif + +#ifndef DEBUG_PRINT_ENABLE_ALL +#define DEBUG_PRINT_ENABLE_ALL 0 +#endif + +#ifndef DEBUG_PRINT_ENABLE +#define DEBUG_PRINT_ENABLE 0 +#endif + +#if !defined(DEBUG_PRINT_ENABLE_APPLICATION) && !defined(DEBUG_PRINT_DISABLE_APPLICATION) +#define DEBUG_PRINT_ENABLE_APPLICATION DEBUG_PRINT_ENABLE +#endif + +#define DEBUG_UTILS_JOIN0(x,y) x ## y +#define DEBUG_UTILS_JOIN(x,y) DEBUG_UTILS_JOIN0(x,y) + +#if DEBUG_UTILS_JOIN(DEBUG_PRINT_ENABLE_,DEBUG_UNIT) +#define DEBUG_PRINT_ENABLE0 1 +#endif + +#if DEBUG_UTILS_JOIN(DEBUG_PRINT_DISABLE_,DEBUG_UNIT) +#define DEBUG_PRINT_ENABLE0 0 +#endif + +#if !defined(DEBUG_PRINT_ENABLE0) +#define DEBUG_PRINT_ENABLE0 DEBUG_PRINT_ENABLE_ALL +#endif + +#if defined(__cplusplus) || defined(__XC__) +extern "C" { +#endif + +#include +#include + +/** + * Just like snprintf, but not all of the + * standard C format control are supported. + */ +int rtos_snprintf(char *str, size_t size, const char *fmt, ...); + +/** + * Just like sprintf, but not all of the + * standard C format control are supported. + */ +int rtos_sprintf(char *str, const char *fmt, ...); + +/** + * Just like vprintf, but not all of the + * standard C format control are supported. + */ +#ifndef __XC__ +int rtos_vprintf(const char *fmt, va_list ap); +#endif + +/** + * Just like printf, but not all of the + * standard C format control are supported. + */ +int rtos_printf(const char *fmt, ...); + +#if defined(__cplusplus) || defined(__XC__) +} +#endif + +#if DEBUG_PRINT_ENABLE0 +#define rtos_vprintf(...) rtos_vprintf(__VA_ARGS__) +#define rtos_printf(...) rtos_printf(__VA_ARGS__) +#else +#define rtos_vprintf(...) +#define rtos_printf(...) +#endif + +#endif // _rtos_printf_h_ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_support.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_support.h new file mode 100644 index 000000000..6014624ba --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_support.h @@ -0,0 +1,22 @@ +// Copyright 2019-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef RTOS_SUPPORT_H_ +#define RTOS_SUPPORT_H_ + +/* Config file to be provided by the RTOS */ +#include "rtos_support_rtos_config.h" + +/* Library header files */ +#include "rtos_cores.h" +#include "rtos_interrupt.h" +#include "rtos_locks.h" +#include "rtos_time.h" +#include "rtos_macros.h" +#include "rtos_printf.h" + +#ifndef __XC__ +#include "rtos_irq.h" +#endif + +#endif /* RTOS_SUPPORT_H_ */ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_time.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_time.h new file mode 100644 index 000000000..e47f9f89c --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/api/rtos_time.h @@ -0,0 +1,72 @@ +// Copyright 2020-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef RTOS_TIME_H_ +#define RTOS_TIME_H_ + +#include + +/** + * \defgroup RTOS time standard periods + * + * These values represent the period of various + * standard interrupt frequencies that may be + * used as the parameter for rtos_time_increment(). + * @{ + */ +/** Period of 1000 Hz in microseconds in Q12 format */ +#define RTOS_TICK_PERIOD_1000_HZ 4096000 /* 1000000 / 1000 * 2^12 */ +/** Period of 100 Hz in microseconds in Q12 format */ +#define RTOS_TICK_PERIOD_100_HZ 40960000 /* 1000000 / 100 * 2^12 */ +/** Period of 32768 Hz in microseconds in Q12 format */ +#define RTOS_TICK_PERIOD_32768_HZ 125000 /* 1000000 / 32768 * 2^12 */ +/**@}*/ + +/** + * Converts a frequency in hertz to its period in + * microseconds in Q12 format that may be used as + * the parameter for rtos_time_increment(). + */ +#define RTOS_TICK_PERIOD(hz) ((uint32_t)(((uint64_t)1000000 << 12) / (hz))) + +/** + * Structure representing the time. + */ +typedef struct { + uint64_t seconds; /**< The number of seconds. */ + uint32_t microseconds; /**< The number of microseconds. */ +} rtos_time_t; + + +/** + * This function increments the current time by + * \p tick_period microseconds. + * + * It is intended to be called by a periodic + * interrupt, either the system tick interrupt + * or an RTC interrupt, at a frequency of 1 / + * \p tick_period. + * + * \param[in] tick_period The number of microseconds + * to increment the current time by. It must be + * formatted as a fixed point number with 12 + * fractional bits. + */ +void rtos_time_increment(uint32_t tick_period); + +/** + * This function sets the current time to \p new_time. + * + * \param[in] new_time The value to set the current time to. + * See rtos_time_t. + */ +void rtos_time_set(rtos_time_t new_time); + +/** + * This function returns the current time. + * + * \returns the current time. See rtos_time_t. + */ +rtos_time_t rtos_time_get(void); + +#endif /* RTOS_TIME_H_ */ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/module_build_info b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/module_build_info new file mode 100644 index 000000000..33e60a1fe --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/module_build_info @@ -0,0 +1,13 @@ +VERSION = 0.5.0 + +DEPENDENT_MODULES = + +MODULE_XCC_FLAGS = $(XCC_FLAGS) -Os + +OPTIONAL_HEADERS += rtos_support_conf.h + +EXPORT_INCLUDE_DIRS = api src + +INCLUDE_DIRS = $(EXPORT_INCLUDE_DIRS) + +SOURCE_DIRS = src diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_cores.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_cores.c new file mode 100644 index 000000000..667e9d3bf --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_cores.c @@ -0,0 +1,75 @@ +// Copyright 2019-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#include + +#include "rtos_support.h" + +/* + * This is indexed by the logical core ID + * returned by get_logical_core_id(). + * It returns the RTOS core ID which is + * guaranteed to be between 0 and the number of + * cores used by the RTOS - 1. + * + * Not static so that it can be accessed directly by + * RTOS functions written in assembly. + */ +int rtos_core_map[RTOS_MAX_CORE_COUNT] = {0}; + +/* + * This is indexed by the RTOS core ID + * which must be between 0 and the number of + * cores used by the RTOS - 1. + * It returns the logical core ID which is + * returned by get_logical_core_id(). + */ +static int rtos_core_map_reverse[RTOS_MAX_CORE_COUNT]; + +/* + * The number of RTOS cores that have been initialized. + * + * TODO: I don't think this needs to be volatile anymore + * since it is only read through rtos_core_count(), which + * should always read the value in memory. + */ +static /*volatile*/ int rtos_core_init_count; + +/* + * Registers a new RTOS core. Returns its core ID. + * Note this is not the necessarily the same as the + * ID returned by get_logical_core_id(). + */ +int rtos_core_register(void) +{ + int core_id; + + core_id = (int) get_logical_core_id(); + + rtos_lock_acquire(0); + { + rtos_core_map[core_id] = rtos_core_init_count; + rtos_core_map_reverse[rtos_core_init_count] = core_id; + core_id = rtos_core_init_count++; + } + rtos_lock_release(0); + + return core_id; +} + +/* Note, always returns 0 before the scheduler is started. */ +int rtos_core_id_get(void) +{ + return rtos_core_map[get_logical_core_id()]; +} + +int rtos_logical_core_id_get(int core_id) +{ + xassert(core_id < rtos_core_init_count); + return rtos_core_map_reverse[ core_id ]; +} + +int rtos_core_count(void) +{ + return rtos_core_init_count; +} diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_interrupt.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_interrupt.c new file mode 100644 index 000000000..216b6281a --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_interrupt.c @@ -0,0 +1,14 @@ +// Copyright 2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#include "rtos_support.h" + +/* + * Ensure that these normally inline functions exist + * when compiler optimizations are disabled. + */ +extern inline uint32_t rtos_interrupt_mask_get(void); +extern inline uint32_t rtos_interrupt_mask_all(void); +extern inline void rtos_interrupt_unmask_all(void); +extern inline void rtos_interrupt_mask_set(uint32_t mask); +extern inline uint32_t rtos_isr_running(void); diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_interrupt_impl.h b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_interrupt_impl.h new file mode 100644 index 000000000..ac79491ed --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_interrupt_impl.h @@ -0,0 +1,100 @@ +// Copyright 2019-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +/* + * This file extends the interrupt support in lib_xcore_c to support + * interrupts in an RTOS environment where thread context needs to + * be saved on the stack. + */ + +#ifndef RTOS_INTERRUPT_IMPL_H_ +#define RTOS_INTERRUPT_IMPL_H_ + +#include "rtos_support_rtos_config.h" +#include + +#define _DEFINE_RTOS_KERNEL_ENTRY_DEF(root_function) \ + .weak _fptrgroup.rtos_isr.nstackwords.group; \ + .max_reduce _fptrgroup.rtos_isr.nstackwords, _fptrgroup.rtos_isr.nstackwords.group, 0; \ + .set _kstack_words, _XCORE_STACK_ALIGN(_fptrgroup.rtos_isr.nstackwords); \ + .globl __xcore_interrupt_permitted_common; \ + .globl _XCORE_INTERRUPT_PERMITTED(root_function); \ + .align _XCORE_CODE_ALIGNMENT; \ + .type _XCORE_INTERRUPT_PERMITTED(root_function),@function; \ + .issue_mode single; \ + .cc_top _XCORE_INTERRUPT_PERMITTED(root_function).function,_XCORE_INTERRUPT_PERMITTED(root_function); \ + _XCORE_INTERRUPT_PERMITTED(root_function):; \ + _XCORE_ENTSP(_XCORE_STACK_ALIGN(5)); \ + /* Save CP into SP[4] */ \ + ldaw r11, cp[0]; \ + stw r11, sp[4]; \ + /* Save DP into SP[3] */ \ + ldaw r11, dp[0]; \ + stw r11, sp[3]; \ + stw r5, sp[2]; \ + stw r4, sp[1]; \ + ldc r4, _kstack_words; \ + ldap r11, root_function; \ + add r5, r11, 0; \ + ldap r11, __xcore_interrupt_permitted_common; \ + bau r11; \ + .cc_bottom _XCORE_INTERRUPT_PERMITTED(root_function).function; \ + /* The stack size for this function must be big enough for: */ \ + /* - This wrapper function: _XCORE_STACK_ALIGN(5) + __xcore_interrupt_permitted_common.nstackwords */ \ + /* - The size of the stack required by the root function: root_function.nstackwords */ \ + /* - The size of the stack required by the ISR group: _kstack_words */ \ + .set _XCORE_INTERRUPT_PERMITTED(root_function).nstackwords, _XCORE_STACK_ALIGN(5) + __xcore_interrupt_permitted_common.nstackwords + root_function.nstackwords + _kstack_words; \ + .globl _XCORE_INTERRUPT_PERMITTED(root_function).nstackwords; \ + .set _XCORE_INTERRUPT_PERMITTED(root_function).maxcores, 1 $M __xcore_interrupt_permitted_common.maxcores $M root_function.maxcores; \ + .globl _XCORE_INTERRUPT_PERMITTED(root_function).maxcores; \ + .set _XCORE_INTERRUPT_PERMITTED(root_function).maxtimers, 0 $M __xcore_interrupt_permitted_common.maxtimers $M root_function.maxtimers; \ + .globl _XCORE_INTERRUPT_PERMITTED(root_function).maxtimers; \ + .set _XCORE_INTERRUPT_PERMITTED(root_function).maxchanends, 0 $M _xcore_c_select_callback_common.maxchanends $M root_function.maxchanends; \ + .globl _XCORE_INTERRUPT_PERMITTED(root_function).maxchanends; \ + .size _XCORE_INTERRUPT_PERMITTED(root_function), . - _XCORE_INTERRUPT_PERMITTED(root_function); \ + +#define _DEFINE_RTOS_KERNEL_ENTRY(ret, root_function, ...) \ + asm(RTOS_STRINGIFY(_DEFINE_RTOS_KERNEL_ENTRY_DEF(root_function))); \ + _XCORE_DECLARE_INTERRUPT_PERMITTED(ret, root_function, __VA_ARGS__) + +#define _DECLARE_RTOS_INTERRUPT_CALLBACK(intrpt, data) \ + void _XCORE_INTERRUPT_CALLBACK(intrpt)(void);\ + void intrpt(void *data) + +#define _DEFINE_RTOS_INTERRUPT_CALLBACK_DEF(intrpt) \ + .weak _fptrgroup.rtos_isr.nstackwords.group; \ + .add_to_set _fptrgroup.rtos_isr.nstackwords.group, _XCORE_INTERRUPT_CALLBACK(intrpt).nstackwords, _XCORE_INTERRUPT_CALLBACK(intrpt); \ + .globl _XCORE_INTERRUPT_CALLBACK(intrpt); \ + .align _XCORE_CODE_ALIGNMENT; \ + .type _XCORE_INTERRUPT_CALLBACK(intrpt),@function; \ + .issue_mode dual; \ + .cc_top _XCORE_INTERRUPT_CALLBACK(intrpt).function,_XCORE_INTERRUPT_CALLBACK(intrpt); \ + _XCORE_INTERRUPT_CALLBACK(intrpt):; \ + /* Extend the stack by enough words to store the thread context. */ \ + extsp RTOS_SUPPORT_INTERRUPT_STACK_GROWTH; \ + /* We need to use R1 and R11 now so save them where the RTOS wants */ \ + /* them. The RTOS provided function rtos_interrupt_callback_common */ \ + /* will save the rest of the registers. */ \ + stw r1, sp[RTOS_SUPPORT_INTERRUPT_R1_STACK_OFFSET]; \ + stw r11, sp[RTOS_SUPPORT_INTERRUPT_R11_STACK_OFFSET]; \ + ldap r11, intrpt; \ + mov r1, r11; \ + ldap r11, rtos_interrupt_callback_common; \ + bau r11; \ + .cc_bottom _XCORE_INTERRUPT_CALLBACK(intrpt).function; \ + .set _XCORE_INTERRUPT_CALLBACK(intrpt).nstackwords, intrpt.nstackwords; \ + .globl _XCORE_INTERRUPT_CALLBACK(intrpt).nstackwords; \ + .set _XCORE_INTERRUPT_CALLBACK(intrpt).maxcores, 1 $M intrpt.maxcores; \ + .globl _XCORE_INTERRUPT_CALLBACK(intrpt).maxcores; \ + .set _XCORE_INTERRUPT_CALLBACK(intrpt).maxtimers, 0 $M intrpt.maxtimers; \ + .globl _XCORE_INTERRUPT_CALLBACK(intrpt).maxtimers; \ + .set _XCORE_INTERRUPT_CALLBACK(intrpt).maxchanends, 0 $M intrpt.maxchanends; \ + .globl _XCORE_INTERRUPT_CALLBACK(intrpt).maxchanends; \ + .size _XCORE_INTERRUPT_CALLBACK(intrpt), . - _XCORE_INTERRUPT_CALLBACK(intrpt); \ + +#define _DEFINE_RTOS_INTERRUPT_CALLBACK(intrpt, data) \ + asm(RTOS_STRINGIFY(_DEFINE_RTOS_INTERRUPT_CALLBACK_DEF(intrpt))); \ + _DECLARE_RTOS_INTERRUPT_CALLBACK(intrpt, data) + + +#endif /* RTOS_INTERRUPT_IMPL_H_ */ diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_irq.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_irq.c new file mode 100644 index 000000000..eace4648b --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_irq.c @@ -0,0 +1,215 @@ +// Copyright 2019-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#include +#include "rtos_support.h" + +/* + * Source IDs 0-7 are reserved for RTOS cores + * Source IDs 8-15 are allowed for other use + * + * (Assuming RTOS_MAX_CORE_COUNT == 8) + */ +#define RTOS_CORE_SOURCE_MASK ( ( 1 << RTOS_MAX_CORE_COUNT ) - 1) +#define MAX_ADDITIONAL_SOURCES 8 +#define MAX_SOURCE_ID ( RTOS_MAX_CORE_COUNT + MAX_ADDITIONAL_SOURCES - 1 ) + +/* + * The channel ends used by RTOS cores to send and receive IRQs. + */ +static chanend_t rtos_irq_chanend[ RTOS_MAX_CORE_COUNT ]; + +/* + * The channel ends used by peripherals to send IRQs. + */ +static chanend_t peripheral_irq_chanend[ MAX_ADDITIONAL_SOURCES ]; + +/* + * Flag set per core indicating which IRQ sources are pending + */ +static volatile uint32_t irq_pending[ RTOS_MAX_CORE_COUNT ]; + +static int peripheral_source_count; + +/* + * The IRQ enabled bitfield. Represents which cores have + * their IRQ enabled. + */ +static uint32_t irq_enable_bf; + +/* + * Set to 1 when all cores have enabled their IRQ. + */ +static int irq_ready; + +typedef struct { + RTOS_IRQ_ISR_ATTR rtos_irq_isr_t isr; + void *data; +} isr_info_t; + +static isr_info_t isr_info[MAX_ADDITIONAL_SOURCES]; + +DEFINE_RTOS_INTERRUPT_CALLBACK( rtos_irq_handler, data ) +{ + int core_id; + uint32_t pending; + + core_id = rtos_core_id_get(); + + xassert( irq_pending[ core_id ] ); + + chanend_check_end_token( rtos_irq_chanend[ core_id ] ); + + /* just ensure the channel read is done before clearing the pending flags. */ + RTOS_MEMORY_BARRIER(); + + /* grab a snapshot of the pending flags before clearing them. + After the clear, this core may be interrupted again. We will + handle all the interrupts at the time the snapshot is taken now, + and any more will be handled when this ISR is called again. */ + + rtos_lock_acquire(0); + { + pending = irq_pending[ core_id ]; + irq_pending[ core_id ] = 0; + } + rtos_lock_release(0); + + if (pending & RTOS_CORE_SOURCE_MASK ) + { + /* This core is being yielded by at least one other RTOS core. + Clear the pending flags from all of them and enter the scheduler. */ + + pending &= ~RTOS_CORE_SOURCE_MASK; + + RTOS_INTERCORE_INTERRUPT_ISR(); + } + + while ( pending != 0 ) + { + int source_id = 31UL - ( uint32_t ) __builtin_clz( pending ); + + xassert( source_id >= RTOS_MAX_CORE_COUNT && source_id <= MAX_SOURCE_ID ); + + pending &= ~( 1 << source_id ); + + source_id -= RTOS_MAX_CORE_COUNT; + if ( isr_info[ source_id ].isr != NULL ) + { + isr_info[ source_id ].isr( isr_info[ source_id ].data ); + } + } +} + +/* + * May be called by a non-RTOS core provided + * xSourceID >= RTOS_MAX_CORE_COUNT. + */ +void rtos_irq( int core_id, int source_id ) +{ + chanend_t source_chanend; + uint32_t pending; + int num_cores = rtos_core_count(); + + xassert( core_id >= 0 && core_id < num_cores ); + xassert( source_id >= 0 && source_id < RTOS_MAX_CORE_COUNT + peripheral_source_count ); + + /* + * Atomically set the pending flag and, if the core we are + * sending an IRQ does not already have a pending IRQ, interrupt + * it with a channel send. This guarantees that if two cores + * simultaneously send a core an IRQ that only one will perform + * the channel send. Another channel send will not be performed + * until the core reads the token from the channel and clears the + * pending flags. + */ + rtos_lock_acquire(0); + { + pending = irq_pending[ core_id ]; + irq_pending[ core_id ] |= ( 1 << source_id ); + + if( pending == 0 ) + { + if( source_id >= 0 && source_id < num_cores ) + { + source_chanend = rtos_irq_chanend[ source_id ]; + } + else if ( source_id >= RTOS_MAX_CORE_COUNT && source_id < RTOS_MAX_CORE_COUNT + peripheral_source_count ) + { + source_chanend = peripheral_irq_chanend[ source_id - RTOS_MAX_CORE_COUNT ]; + } + else + { + xassert(0); + /* If assertions are disabled, setting this to 0 + * here should cause a resource exception below. */ + source_chanend = 0; + } + + /* just ensure the pending flag is set before the channel send. */ + RTOS_MEMORY_BARRIER(); + + chanend_set_dest( source_chanend, rtos_irq_chanend[ core_id ] ); + chanend_out_end_token( source_chanend ); + } + } + rtos_lock_release(0); +} + + +/* + * Must be called by an RTOS core to interrupt a + * non-RTOS core. + */ +void rtos_irq_peripheral( chanend_t dest_chanend ) +{ + int core_id; + + uint32_t mask = rtos_interrupt_mask_all(); + core_id = rtos_core_id_get(); + chanend_set_dest( rtos_irq_chanend[ core_id ], dest_chanend ); + chanend_out_end_token( rtos_irq_chanend[ core_id ] ); + rtos_interrupt_mask_set(mask); +} + +int rtos_irq_register(rtos_irq_isr_t isr, void *data, chanend_t source_chanend) +{ + int source_id; + + xassert( peripheral_source_count < MAX_ADDITIONAL_SOURCES ); + + rtos_lock_acquire(0); + source_id = peripheral_source_count++; + rtos_lock_release(0); + + isr_info[ source_id ].isr = isr; + isr_info[ source_id ].data = data; + peripheral_irq_chanend[ source_id ] = source_chanend; + + return RTOS_MAX_CORE_COUNT + source_id; +} + +void rtos_irq_enable( int total_rtos_cores ) +{ + int core_id; + + core_id = rtos_core_id_get(); + rtos_irq_chanend[ core_id ] = chanend_alloc(); + triggerable_setup_interrupt_callback( rtos_irq_chanend[ core_id ], NULL, RTOS_INTERRUPT_CALLBACK( rtos_irq_handler ) ); + triggerable_enable_trigger( rtos_irq_chanend[ core_id ] ); + + rtos_lock_acquire(0); + { + irq_enable_bf |= (1 << core_id); + + if (irq_enable_bf == (1 << total_rtos_cores) - 1) { + irq_ready = 1; + } + } + rtos_lock_release(0); +} + +int rtos_irq_ready(void) +{ + return irq_ready; +} diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_locks.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_locks.c new file mode 100644 index 000000000..1c2ff1dce --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_locks.c @@ -0,0 +1,38 @@ +// Copyright 2019-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#include "rtos_support.h" + +lock_t rtos_locks[RTOS_LOCK_COUNT] = { +#if RTOS_LOCK_COUNT >= 1 + -1, +#endif +#if RTOS_LOCK_COUNT >= 2 + -1, +#endif +#if RTOS_LOCK_COUNT >= 3 + -1, +#endif +#if RTOS_LOCK_COUNT >= 4 + -1 +#endif +}; + +int rtos_lock_counters[RTOS_LOCK_COUNT] = {0}; + +void rtos_locks_initialize(void) +{ + int i; + + for (i = 0; i < RTOS_LOCK_COUNT; i++) { + rtos_locks[i] = lock_alloc(); + xassert(rtos_locks[i] != 0); + } +} + +/* + * Ensure that these normally inline functions exist + * when compiler optimizations are disabled. + */ +extern inline int rtos_lock_acquire(int lock_id); +extern inline int rtos_lock_release(int lock_id); diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_printf.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_printf.c new file mode 100644 index 000000000..b07ec976c --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_printf.c @@ -0,0 +1,504 @@ +// Copyright 2019-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +/*---------------------------------------------------*/ +/* Modified from : */ +/* Public Domain version of printf */ +/* Rud Merriam, Compsult, Inc. Houston, Tx. */ +/* For Embedded Systems Programming, 1991 */ +/* */ +/*---------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include + +#include "rtos_support.h" + +#undef rtos_printf +#undef rtos_vprintf + +#define LONG64 (LONG_MAX == 9223372036854775807L) +#define POINTER64 (INTPTR_MAX == 9223372036854775807L) + +typedef struct { + size_t size; + size_t pos; + char *str; + int writeout; + int32_t len; + int32_t num1; + int32_t num2; + int32_t do_padding; + int32_t left_flag; + int32_t unsigned_flag; + char pad_character; +} params_t; + +static void outbyte(char b, params_t *par) +{ + if (par->pos < par->size) { + par->str[par->pos] = b; + } + par->pos++; + + if (par->writeout && par->pos >= par->size) { + _write(FD_STDOUT, par->str, par->size); + par->pos = 0; + } +} + +/*---------------------------------------------------*/ +/* The purpose of this routine is to output data the */ +/* same as the standard printf function without the */ +/* overhead most run-time libraries involve. Usually */ +/* the printf brings in many kilobytes of code and */ +/* that is unacceptable in most embedded systems. */ +/*---------------------------------------------------*/ + + +/*---------------------------------------------------*/ +/* */ +/* This routine puts pad characters into the output */ +/* buffer. */ +/* */ +static void padding(const int32_t l_flag, params_t *par) +{ + int32_t i; + + if ((par->do_padding != 0) && (l_flag != 0) && (par->len < par->num1)) { + i=(par->len); + for (; i<(par->num1); i++) { + outbyte(par->pad_character, par); + } + } +} + +/*---------------------------------------------------*/ +/* */ +/* This routine moves a string to the output buffer */ +/* as directed by the padding and positioning flags. */ +/* */ +static void outs(const char *lp, params_t *par) +{ + /* pad on left if needed */ + if(lp != NULL) { + par->len = (int32_t) strlen(lp); + } + padding(!(par->left_flag), par); + + /* Move string to the buffer */ + while (((*lp) != (char)0) && ((par->num2) != 0)) { + (par->num2)--; + outbyte(*lp, par); + lp += 1; + } + + padding(par->left_flag, par); +} + +/*---------------------------------------------------*/ +/* */ +/* This routine moves a number to the output buffer */ +/* as directed by the padding and positioning flags. */ +/* */ + +static void outnum(const int32_t n, const int32_t base, params_t *par) +{ + int32_t negative; + int32_t i; + char outbuf[32]; + const char digits[] = "0123456789ABCDEF"; + uint32_t num; + for(i = 0; i<32; i++) { + outbuf[i] = '0'; + } + + /* Check if number is negative */ + if ((par->unsigned_flag == 0) && (base == 10) && (n < 0L)) { + negative = 1; + num =(-(n)); + } + else{ + num = n; + negative = 0; + } + + /* Build number (backwards) in outbuf */ + i = 0; + do { + outbuf[i] = digits[(num % base)]; + i++; + num /= base; + } while (num > 0); + + if (negative != 0) { + outbuf[i] = '-'; + i++; + } + + outbuf[i] = '\0'; + i--; + + /* Move the converted number to the buffer and */ + /* add in the padding where needed. */ + par->len = (int32_t)strlen(outbuf); + padding(!(par->left_flag), par); + while (&outbuf[i] >= outbuf) { + outbyte(outbuf[i], par); + i--; + } + padding(par->left_flag, par); +} +/*---------------------------------------------------*/ +/* */ +/* This routine moves a 64-bit number to the output */ +/* buffer as directed by the padding and positioning */ +/* flags. */ +/* */ +#if LONG64 +static void outnum1(const int64_t n, const int32_t base, params_t *par) +{ + int32_t negative; + int32_t i; + char outbuf[64]; + const char digits[] = "0123456789ABCDEF"; + uint64_t num; + for(i = 0; i<64; i++) { + outbuf[i] = '0'; + } + + /* Check if number is negative */ + if ((par->unsigned_flag == 0) && (base == 10) && (n < 0L)) { + negative = 1; + num =(-(n)); + } + else{ + num = (n); + negative = 0; + } + + /* Build number (backwards) in outbuf */ + i = 0; + do { + outbuf[i] = digits[(num % base)]; + i++; + num /= base; + } while (num > 0); + + if (negative != 0) { + outbuf[i] = '-'; + i++; + } + + outbuf[i] = '\0'; + i--; + + /* Move the converted number to the buffer and */ + /* add in the padding where needed. */ + par->len = (int32_t)strlen(outbuf); + padding(!(par->left_flag), par); + while (&outbuf[i] >= outbuf) { + outbyte(outbuf[i], par); + i--; + } + padding(par->left_flag, par); +} +#endif +/*---------------------------------------------------*/ +/* */ +/* This routine gets a number from the format */ +/* string. */ +/* */ +static int32_t getnum(char **linep) +{ + int32_t n; + int32_t ResultIsDigit = 0; + char *cptr; + n = 0; + cptr = *linep; + if(cptr != NULL){ + ResultIsDigit = isdigit(((int32_t)*cptr)); + } + while (ResultIsDigit != 0) { + if(cptr != NULL){ + n = ((n*10) + (((int32_t)*cptr) - (int32_t)'0')); + cptr += 1; + if(cptr != NULL){ + ResultIsDigit = isdigit(((int32_t)*cptr)); + } + } + ResultIsDigit = isdigit(((int32_t)*cptr)); + } + *linep = ((char *)(cptr)); + return(n); +} + +/*---------------------------------------------------*/ +/* */ +/* This routine operates just like a printf/sprintf */ +/* routine. It outputs a set of data under the */ +/* control of a formatting string. Not all of the */ +/* standard C format control are supported. The ones */ +/* provided are primarily those needed for embedded */ +/* systems work. Primarily the floating point */ +/* routines are omitted. Other formats could be */ +/* added easily by following the examples shown for */ +/* the supported formats. */ +/* */ + +static int rtos_vsnwprintf(char *str, size_t size, int writeout, const char *fmt, va_list ap) +{ + int32_t Check; +#if LONG64 + int32_t long_flag; +#endif + int32_t dot_flag; + + params_t par; + + char ch; + char *ctrl = (char *)fmt; + + par.size = size; + par.pos = 0; + par.str = str; + par.writeout = writeout; + + while ((ctrl != NULL) && (*ctrl != (char)0)) { + + /* move format string chars to buffer until a */ + /* format control is found. */ + if (*ctrl != '%') { + outbyte(*ctrl, &par); + ctrl += 1; + continue; + } + + /* initialize all the flags for this format. */ + dot_flag = 0; +#if LONG64 + long_flag = 0; +#endif + par.unsigned_flag = 0; + par.left_flag = 0; + par.do_padding = 0; + par.pad_character = ' '; + par.num2=32767; + par.num1=0; + par.len=0; + + try_next: + if(ctrl != NULL) { + ctrl += 1; + } + if(ctrl != NULL) { + ch = *ctrl; + } + else { + ch = *ctrl; + } + + if (isdigit((int32_t)ch) != 0) { + if (dot_flag != 0) { + par.num2 = getnum(&ctrl); + } + else { + if (ch == '0') { + par.pad_character = '0'; + } + if(ctrl != NULL) { + par.num1 = getnum(&ctrl); + } + par.do_padding = 1; + } + if(ctrl != NULL) { + ctrl -= 1; + } + goto try_next; + } + + if (dot_flag != 0 && ch == '*') { + par.num2 = va_arg(ap, int32_t); + goto try_next; + } + + switch (tolower((int32_t)ch)) { + case '%': + outbyte('%', &par); + Check = 1; + break; + + case '-': + par.left_flag = 1; + Check = 0; + break; + + case '.': + dot_flag = 1; + Check = 0; + break; + + case 'l': + #if LONG64 + long_flag = 1; + #endif + Check = 0; + break; + + case 'u': + par.unsigned_flag = 1; + /* fall through */ + case 'i': + case 'd': + #if LONG64 + if (long_flag != 0){ + outnum1((int64_t)va_arg(ap, int64_t), 10L, &par); + } + else { + outnum(va_arg(ap, int32_t), 10L, &par); + } + #else + outnum(va_arg(ap, int32_t), 10L, &par); + #endif + Check = 1; + break; + case 'p': + #if POINTER64 + par.unsigned_flag = 1; + outnum1((int64_t)va_arg(ap, int64_t), 16L, &par); + Check = 1; + break; + #endif + case 'X': + case 'x': + par.unsigned_flag = 1; + #if LONG64 + if (long_flag != 0) { + outnum1((int64_t)va_arg(ap, int64_t), 16L, &par); + } + else { + outnum((int32_t)va_arg(ap, int32_t), 16L, &par); + } + #else + outnum((int32_t)va_arg(ap, int32_t), 16L, &par); + #endif + Check = 1; + break; + + case 's': + outs(va_arg(ap, char *), &par); + Check = 1; + break; + + case 'c': + outbyte(va_arg(ap, int32_t), &par); + Check = 1; + break; + + case '\\': + switch (*ctrl) { + case 'a': + outbyte((char)0x07, &par); + break; + case 'h': + outbyte((char)0x08, &par); + break; + case 'r': + outbyte((char)0x0D, &par); + break; + case 'n': + outbyte((char)0x0D, &par); + outbyte((char)0x0A, &par); + break; + default: + outbyte(*ctrl, &par); + break; + } + ctrl += 1; + Check = 0; + break; + + default: + Check = 1; + break; + } + if(Check == 1) { + if(ctrl != NULL) { + ctrl += 1; + } + continue; + } + goto try_next; + } + + if (par.pos < par.size) { + par.str[par.pos] = '\0'; + } + + return par.pos; +} +/*---------------------------------------------------*/ + +int rtos_snprintf(char *str, size_t size, const char *fmt, ...) +{ + int len; + va_list ap; + + va_start(ap, fmt); + len = rtos_vsnwprintf(str, size, 0, fmt, ap); + va_end(ap); + + return len; +} + +int rtos_sprintf(char *str, const char *fmt, ...) +{ + int len; + va_list ap; + + va_start(ap, fmt); + len = rtos_vsnwprintf(str, SIZE_MAX, 0, fmt, ap); + va_end(ap); + + return len; +} + +#ifndef RTOS_PRINTF_BUFSIZE +#ifdef DEBUG_PRINTF_BUFSIZE +#define RTOS_PRINTF_BUFSIZE DEBUG_PRINTF_BUFSIZE +#else +#define RTOS_PRINTF_BUFSIZE 130 +#endif +#endif + +int rtos_vprintf(const char *fmt, va_list ap) +{ + int len; + uint32_t mask; + char buf[RTOS_PRINTF_BUFSIZE]; + + mask = rtos_interrupt_mask_all(); + len = rtos_vsnwprintf(buf, RTOS_PRINTF_BUFSIZE, 1, fmt, ap); + + _write(FD_STDOUT, buf, len); + + rtos_interrupt_mask_set(mask); + + return len; +} + +int rtos_printf(const char *fmt, ...) +{ + int len; + va_list ap; + + va_start(ap, fmt); + len = rtos_vprintf(fmt, ap); + va_end(ap); + + return len; +} diff --git a/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_time.c b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_time.c new file mode 100644 index 000000000..f30d39719 --- /dev/null +++ b/FreeRTOS/Demo/ThirdParty/Community-Supported/XCORE.AI_xClang/lib_rtos_support/src/rtos_time.c @@ -0,0 +1,49 @@ +// Copyright 2020-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#include "rtos_time.h" +#include "rtos_locks.h" + +static rtos_time_t current_time; + +#define US_FRACTIONAL_BITS 12 +#define ONE_SECOND_US (1000000 << US_FRACTIONAL_BITS) + +void rtos_time_increment(uint32_t tick_period) +{ + rtos_lock_acquire(0); + { + current_time.microseconds += tick_period; + if (current_time.microseconds >= ONE_SECOND_US) { + current_time.microseconds -= ONE_SECOND_US; + current_time.seconds++; + } + } + rtos_lock_release(0); +} + +void rtos_time_set(rtos_time_t new_time) +{ + new_time.microseconds <<= US_FRACTIONAL_BITS; + + rtos_lock_acquire(0); + { + current_time = new_time; + } + rtos_lock_release(0); +} + +rtos_time_t rtos_time_get(void) +{ + rtos_time_t tmp_time; + + rtos_lock_acquire(0); + { + tmp_time = current_time; + } + rtos_lock_release(0); + + tmp_time.microseconds >>= US_FRACTIONAL_BITS; + + return tmp_time; +} diff --git a/FreeRTOS/Source b/FreeRTOS/Source index c3dc20fdb..ae3a498e4 160000 --- a/FreeRTOS/Source +++ b/FreeRTOS/Source @@ -1 +1 @@ -Subproject commit c3dc20fdb4f15115fcaf8ad3f71fdf5696a30415 +Subproject commit ae3a498e435cecdb25b889f2740ea99027dd0cb1 diff --git a/manifest.yml b/manifest.yml index 44d6c1966..4755fca71 100644 --- a/manifest.yml +++ b/manifest.yml @@ -4,7 +4,7 @@ description: "This is the standard distribution of FreeRTOS." dependencies: - name: "FreeRTOS-Kernel" - version: "c3dc20f" + version: "ae3a498e4" repository: type: "git" url: "https://github.com/FreeRTOS/FreeRTOS-Kernel.git"