From 7cd180d914612173fd3654113c4176aadcb4a124 Mon Sep 17 00:00:00 2001 From: RichardBarry <3073890+RichardBarry@users.noreply.github.com> Date: Mon, 19 Feb 2024 07:20:02 -0800 Subject: [PATCH] Add register test tasks to QEMU project (#765) * Add register test tasks to the CORTEX_MPS2_QEMU_IAR GCC and IAR builds. * Update header comment in the two added files. * Fix header checks * Fix build issue * update IAR version --------- Co-authored-by: none <> Co-authored-by: Rahul Kar Co-authored-by: Rahul Kar <118818625+kar-rahul-aws@users.noreply.github.com> --- .../CORTEX_MPS2_QEMU_IAR_GCC/FreeRTOSConfig.h | 155 ++++++++------- .../build/gcc/.project | 44 +++-- .../build/gcc/Makefile | 3 +- .../build/gcc/RegTest.c | 187 ++++++++++++++++++ .../build/iar/RTOSDemo.ewp | 79 ++++++-- .../build/iar/RTOSDemo.ewt | 147 +++++++++----- .../build/iar/RegTest.S | 181 +++++++++++++++++ FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main.c | 2 +- .../CORTEX_MPS2_QEMU_IAR_GCC/main_blinky.c | 6 +- .../Demo/CORTEX_MPS2_QEMU_IAR_GCC/main_full.c | 87 ++++++++ 10 files changed, 724 insertions(+), 167 deletions(-) create mode 100644 FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc/RegTest.c create mode 100644 FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/iar/RegTest.S diff --git a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/FreeRTOSConfig.h index 095f3df763..20e59ea311 100644 --- a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/FreeRTOSConfig.h @@ -28,104 +28,107 @@ #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 - *----------------------------------------------------------*/ +* 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 +*----------------------------------------------------------*/ -#define configUSE_TRACE_FACILITY 0 -#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 0 +#define configGENERATE_RUN_TIME_STATS 0 -#define configUSE_TICKLESS_IDLE 0 -#define configUSE_PREEMPTION 1 -#define configUSE_IDLE_HOOK 0 -#define configUSE_TICK_HOOK 1 -#define configCPU_CLOCK_HZ ( ( unsigned long ) 25000000 ) -#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) -#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 80 ) -#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 60 * 1024 ) ) -#define configMAX_TASK_NAME_LEN ( 12 ) -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 0 -#define configUSE_CO_ROUTINES 0 -#define configUSE_MUTEXES 1 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configCHECK_FOR_STACK_OVERFLOW 2 -#define configUSE_MALLOC_FAILED_HOOK 1 -#define configUSE_QUEUE_SETS 1 -#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 1 +#define configCPU_CLOCK_HZ ( ( unsigned long ) 25000000 ) +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 80 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 60 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_CO_ROUTINES 0 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_QUEUE_SETS 1 +#define configUSE_COUNTING_SEMAPHORES 1 -#define configMAX_PRIORITIES ( 9UL ) -#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) -#define configQUEUE_REGISTRY_SIZE 10 -#define configSUPPORT_STATIC_ALLOCATION 1 +#define configMAX_PRIORITIES ( 9UL ) +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) +#define configQUEUE_REGISTRY_SIZE 10 +#define configSUPPORT_STATIC_ALLOCATION 1 /* Timer related defines. */ -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 4 ) -#define configTIMER_QUEUE_LENGTH 20 -#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 4 ) +#define configTIMER_QUEUE_LENGTH 20 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) -#define configUSE_TASK_NOTIFICATIONS 1 -#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3 /* Set the following definitions to 1 to include the API function, or zero -to exclude the API function. */ + * to exclude the API function. */ -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskCleanUpResources 0 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 1 -#define INCLUDE_xTaskGetSchedulerState 1 -#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 -#define INCLUDE_xTaskGetIdleTaskHandle 1 -#define INCLUDE_xSemaphoreGetMutexHolder 1 -#define INCLUDE_eTaskGetState 1 -#define INCLUDE_xTimerPendFunctionCall 1 -#define INCLUDE_xTaskAbortDelay 1 -#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 1 +#define INCLUDE_xTaskGetHandle 1 + +/* This demo makes use of one or more example stats formatting functions. These + * format the raw data provided by the uxTaskGetSystemState() function in to human + * readable ASCII form. See the notes in the implementation of vTaskList() within + * FreeRTOS/Source/tasks.c for limitations. */ +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +#define configKERNEL_INTERRUPT_PRIORITY ( 255 ) /* All eight bits as QEMU doesn't model the priority bits. */ -/* This demo makes use of one or more example stats formatting functions. These -format the raw data provided by the uxTaskGetSystemState() function in to human -readable ASCII form. See the notes in the implementation of vTaskList() within -FreeRTOS/Source/tasks.c for limitations. */ -#define configUSE_STATS_FORMATTING_FUNCTIONS 0 -#define configKERNEL_INTERRUPT_PRIORITY ( 255 ) /* All eight bits as QEMU doesn't model the priority bits. */ /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! -See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ -#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 4 ) + * See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 4 ) /* Use the Cortex-M3 optimised task selection rather than the generic C code -version. */ -#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 + * version. */ +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 /* The Win32 target is capable of running all the tests tasks at the same * time. */ -#define configRUN_ADDITIONAL_TESTS 1 +#define configRUN_ADDITIONAL_TESTS 1 /* The test that checks the trigger level on stream buffers requires an -allowable margin of error on slower processors (slower than the Win32 -machine on which the test is developed). */ -#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 4 + * allowable margin of error on slower processors (slower than the Win32 + * machine on which the test is developed). */ +#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 4 #ifndef __IASMARM__ /* Prevent C code being included in IAR asm files. */ - void vAssertCalled( const char *pcFileName, uint32_t ulLine ); - #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ ); + void vAssertCalled( const char * pcFileName, + uint32_t ulLine ); + #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ ); #endif -#define intqHIGHER_PRIORITY ( configMAX_PRIORITIES - 5 ) -#define bktPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 ) -#define bktSECONDARY_PRIORITY ( configMAX_PRIORITIES - 4 ) +#define intqHIGHER_PRIORITY ( configMAX_PRIORITIES - 5 ) +#define bktPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 ) +#define bktSECONDARY_PRIORITY ( configMAX_PRIORITIES - 4 ) #endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc/.project b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc/.project index da12b7d9b3..f634908225 100644 --- a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc/.project +++ b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc/.project @@ -25,11 +25,6 @@ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - CommonDemoSource - 2 - FREERTOS_ROOT/Demo/Common/Minimal - FreeRTOS_kernel 2 @@ -40,20 +35,20 @@ 2 virtual:/virtual + + Source/Blinky_Demo + 2 + virtual:/virtual + Source/FreeRTOSConfig.h 1 FREERTOS_ROOT/Demo/CORTEX_MPS2_QEMU_IAR_GCC/FreeRTOSConfig.h - Source/IntQueueTimer.c - 1 - FREERTOS_ROOT/Demo/CORTEX_MPS2_QEMU_IAR_GCC/IntQueueTimer.c - - - Source/IntQueueTimer.h - 1 - FREERTOS_ROOT/Demo/CORTEX_MPS2_QEMU_IAR_GCC/IntQueueTimer.h + Source/Full_Demo + 2 + virtual:/virtual Source/main.c @@ -61,14 +56,29 @@ FREERTOS_ROOT/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main.c - Source/main_blinky.c + Source/Blinky_Demo/main_blinky.c 1 - FREERTOS_ROOT/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main_blinky.c + PARENT-2-PROJECT_LOC/main_blinky.c - Source/main_full.c + Source/Full_Demo/CommonDemoSource + 2 + FREERTOS_ROOT/Demo/Common/Minimal + + + Source/Full_Demo/IntQueueTimer.c 1 - FREERTOS_ROOT/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main_full.c + PARENT-2-PROJECT_LOC/IntQueueTimer.c + + + Source/Full_Demo/IntQueueTimer.h + 1 + PARENT-2-PROJECT_LOC/IntQueueTimer.h + + + Source/Full_Demo/main_full.c + 1 + PARENT-2-PROJECT_LOC/main_full.c diff --git a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc/Makefile b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc/Makefile index 33e0cdde62..b8ced5da37 100644 --- a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc/Makefile +++ b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc/Makefile @@ -12,7 +12,7 @@ MAKE = make CFLAGS += $(INCLUDE_DIRS) -nostartfiles -ffreestanding -mthumb -mcpu=cortex-m3 \ - -Wall -Wextra -g3 -O0 -ffunction-sections -fdata-sections \ + -Wall -Wextra -g3 -Os -ffunction-sections -fdata-sections \ -MMD -MP -MF"$(@:%.o=%.d)" -MT $@ # @@ -79,6 +79,7 @@ SOURCE_FILES += (DEMO_PROJECT)/main.c SOURCE_FILES += (DEMO_PROJECT)/main_blinky.c SOURCE_FILES += (DEMO_PROJECT)/main_full.c SOURCE_FILES += ./startup_gcc.c +SOURCE_FILES += ./RegTest.c # Lightweight print formatting to use in place of the heavier GCC equivalent. SOURCE_FILES += ./printf-stdarg.c diff --git a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc/RegTest.c b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc/RegTest.c new file mode 100644 index 0000000000..f2fb17f677 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc/RegTest.c @@ -0,0 +1,187 @@ +/* + * 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 + * + */ + +/* + * "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 get preempted very frequently. A register + * containing an unexpected value is indicative of an error in the context + * switching mechanism. + */ + +void vRegTest1Implementation( void ) __attribute__ ((naked)); +void vRegTest2Implementation( void ) __attribute__ ((naked)); + +void vRegTest1Implementation( void ) +{ + __asm volatile + ( + ".extern ulRegTest1LoopCounter \n" + + /* Fill the core registers with known values. */ + "mov r0, #100 \n" + "mov r1, #101 \n" + "mov r2, #102 \n" + "mov r3, #103 \n" + "mov r4, #104 \n" + "mov r5, #105 \n" + "mov r6, #106 \n" + "mov r7, #107 \n" + "mov r8, #108 \n" + "mov r9, #109 \n" + "mov r10, #110 \n" + "mov r11, #111 \n" + "mov r12, #112 \n" + + "reg1_loop: \n" + + "cmp r0, #100 \n" + "bne reg1_error_loop \n" + "cmp r1, #101 \n" + "bne reg1_error_loop \n" + "cmp r2, #102 \n" + "bne reg1_error_loop \n" + "cmp r3, #103 \n" + "bne reg1_error_loop \n" + "cmp r4, #104 \n" + "bne reg1_error_loop \n" + "cmp r5, #105 \n" + "bne reg1_error_loop \n" + "cmp r6, #106 \n" + "bne reg1_error_loop \n" + "cmp r7, #107 \n" + "bne reg1_error_loop \n" + "cmp r8, #108 \n" + "bne reg1_error_loop \n" + "cmp r9, #109 \n" + "bne reg1_error_loop \n" + "cmp r10, #110 \n" + "bne reg1_error_loop \n" + "cmp r11, #111 \n" + "bne reg1_error_loop \n" + "cmp r12, #112 \n" + "bne reg1_error_loop \n" + + /* Everything passed, increment the loop counter. */ + "push { r0-r1 } \n" + "ldr r0, =ulRegTest1LoopCounter \n" + "ldr r1, [r0] \n" + "adds r1, r1, #1 \n" + "str r1, [r0] \n" + "pop { r0-r1 } \n" + + /* Start again. */ + "b reg1_loop \n" + + "reg1_error_loop: \n" + /* 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 \n" + "nop \n" + ); /* __asm volatile. */ +} +/*-----------------------------------------------------------*/ + +void vRegTest2Implementation( void ) +{ + __asm volatile + ( + ".extern ulRegTest2LoopCounter \n" + + /* Set all the core registers to known values. */ + "mov r0, #-1 \n" + "mov r1, #1 \n" + "mov r2, #2 \n" + "mov r3, #3 \n" + "mov r4, #4 \n" + "mov r5, #5 \n" + "mov r6, #6 \n" + "mov r7, #7 \n" + "mov r8, #8 \n" + "mov r9, #9 \n" + "mov r10, #10 \n" + "mov r11, #11 \n" + "mov r12, #12 \n" + + "reg2_loop : \n" + + "cmp r0, #-1 \n" + "bne reg2_error_loop \n" + "cmp r1, #1 \n" + "bne reg2_error_loop \n" + "cmp r2, #2 \n" + "bne reg2_error_loop \n" + "cmp r3, #3 \n" + "bne reg2_error_loop \n" + "cmp r4, #4 \n" + "bne reg2_error_loop \n" + "cmp r5, #5 \n" + "bne reg2_error_loop \n" + "cmp r6, #6 \n" + "bne reg2_error_loop \n" + "cmp r7, #7 \n" + "bne reg2_error_loop \n" + "cmp r8, #8 \n" + "bne reg2_error_loop \n" + "cmp r9, #9 \n" + "bne reg2_error_loop \n" + "cmp r10, #10 \n" + "bne reg2_error_loop \n" + "cmp r11, #11 \n" + "bne reg2_error_loop \n" + "cmp r12, #12 \n" + "bne reg2_error_loop \n" + + /* Increment the loop counter to indicate this test is still functioning + correctly. */ + "push { r0-r1 } \n" + "ldr r0, =ulRegTest2LoopCounter \n" + "ldr r1, [r0] \n" + "adds r1, r1, #1 \n" + "str r1, [r0] \n" + + /* Yield to increase test coverage. */ + "movs r0, #0x01 \n" + "ldr r1, =0xe000ed04 \n" /*NVIC_INT_CTRL */ + "lsl r0, r0, #28 \n" /* Shift to PendSV bit */ + "str r0, [r1] \n" + "dsb \n" + + "pop { r0-r1 } \n" + + /* Start again. */ + "b reg2_loop \n" + + "reg2_error_loop: \n" + /* If this line is hit then there was an error in a core register value. + This loop ensures the loop counter variable stops incrementing. */ + "b reg2_error_loop \n" + + ); /* __asm volatile */ +} +/*-----------------------------------------------------------*/ + diff --git a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/iar/RTOSDemo.ewp b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/iar/RTOSDemo.ewp index 2af9104f3a..e7955f066d 100644 --- a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/iar/RTOSDemo.ewp +++ b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/iar/RTOSDemo.ewp @@ -1,6 +1,6 @@ - 3 + 4 Debug @@ -11,7 +11,7 @@ General 3 - 33 + 36 1 1 + + + + ICCARM 2 - 37 + 38 1 1 + + AARM 2 - 11 + 12 1 1 + @@ -659,19 +688,11 @@ inputOutputBased - - BUILDACTION - 1 - - - - - ILINK 0 - 25 + 27 1 1 + + + + @@ -1046,6 +1083,11 @@ + + BUILDACTION + 2 + + Blinky Demo @@ -1208,6 +1250,9 @@ $PROJ_DIR$\..\..\main_full.c + + $PROJ_DIR$\RegTest.S + System files diff --git a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/iar/RTOSDemo.ewt b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/iar/RTOSDemo.ewt index 5e4ad93a2a..41f7a12e6d 100644 --- a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/iar/RTOSDemo.ewt +++ b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/iar/RTOSDemo.ewt @@ -1,6 +1,6 @@ - 3 + 4 Debug @@ -9,9 +9,9 @@ 1 C-STAT - 515 + 518 - 515 + 518 0 @@ -25,7 +25,7 @@ Debug\C-STAT - 2.3.1 + 2.6.0 @@ -356,6 +356,7 @@ + @@ -798,6 +799,7 @@ + @@ -817,6 +819,7 @@ + @@ -830,6 +833,7 @@ + @@ -840,7 +844,15 @@ - + + + + + + + + + @@ -876,6 +888,7 @@ + @@ -883,6 +896,7 @@ + @@ -900,6 +914,9 @@ + + + @@ -922,6 +939,7 @@ + @@ -946,6 +964,7 @@ + @@ -1002,6 +1021,11 @@ + + + + + @@ -1018,6 +1042,7 @@ + @@ -1048,6 +1073,7 @@ + @@ -1063,6 +1089,10 @@ + + + + @@ -1081,6 +1111,16 @@ + + + + + + + + + + @@ -1423,7 +1463,7 @@ Blinky Demo - $PROJ_DIR$\main_blinky.c + $PROJ_DIR$\..\..\main_blinky.c @@ -1431,25 +1471,25 @@ include - $PROJ_DIR$\..\..\Source\include\event_groups.h + $PROJ_DIR$\..\..\..\..\Source\include\event_groups.h - $PROJ_DIR$\..\..\Source\include\message_buffer.h + $PROJ_DIR$\..\..\..\..\Source\include\message_buffer.h - $PROJ_DIR$\..\..\Source\include\queue.h + $PROJ_DIR$\..\..\..\..\Source\include\queue.h - $PROJ_DIR$\..\..\Source\include\semphr.h + $PROJ_DIR$\..\..\..\..\Source\include\semphr.h - $PROJ_DIR$\..\..\Source\include\stream_buffer.h + $PROJ_DIR$\..\..\..\..\Source\include\stream_buffer.h - $PROJ_DIR$\..\..\Source\include\task.h + $PROJ_DIR$\..\..\..\..\Source\include\task.h - $PROJ_DIR$\..\..\Source\include\timers.h + $PROJ_DIR$\..\..\..\..\Source\include\timers.h @@ -1459,37 +1499,37 @@ ARM_CM3 - $PROJ_DIR$\..\..\Source\portable\IAR\ARM_CM3\port.c + $PROJ_DIR$\..\..\..\..\Source\portable\IAR\ARM_CM3\port.c - $PROJ_DIR$\..\..\Source\portable\IAR\ARM_CM3\portasm.s + $PROJ_DIR$\..\..\..\..\Source\portable\IAR\ARM_CM3\portasm.s MemMang - $PROJ_DIR$\..\..\Source\portable\MemMang\heap_4.c + $PROJ_DIR$\..\..\..\..\Source\portable\MemMang\heap_4.c - $PROJ_DIR$\..\..\Source\event_groups.c + $PROJ_DIR$\..\..\..\..\Source\event_groups.c - $PROJ_DIR$\..\..\Source\list.c + $PROJ_DIR$\..\..\..\..\Source\list.c - $PROJ_DIR$\..\..\Source\queue.c + $PROJ_DIR$\..\..\..\..\Source\queue.c - $PROJ_DIR$\..\..\Source\stream_buffer.c + $PROJ_DIR$\..\..\..\..\Source\stream_buffer.c - $PROJ_DIR$\..\..\Source\tasks.c + $PROJ_DIR$\..\..\..\..\Source\tasks.c - $PROJ_DIR$\..\..\Source\timers.c + $PROJ_DIR$\..\..\..\..\Source\timers.c @@ -1497,89 +1537,92 @@ Standard Demo Tasks - $PROJ_DIR$\..\Common\Minimal\AbortDelay.c + $PROJ_DIR$\..\..\..\Common\Minimal\AbortDelay.c - $PROJ_DIR$\..\Common\Minimal\BlockQ.c + $PROJ_DIR$\..\..\..\Common\Minimal\BlockQ.c - $PROJ_DIR$\..\Common\Minimal\blocktim.c + $PROJ_DIR$\..\..\..\Common\Minimal\blocktim.c - $PROJ_DIR$\..\Common\Minimal\countsem.c + $PROJ_DIR$\..\..\..\Common\Minimal\countsem.c - $PROJ_DIR$\..\Common\Minimal\death.c + $PROJ_DIR$\..\..\..\Common\Minimal\death.c - $PROJ_DIR$\..\Common\Minimal\dynamic.c + $PROJ_DIR$\..\..\..\Common\Minimal\dynamic.c - $PROJ_DIR$\..\Common\Minimal\EventGroupsDemo.c + $PROJ_DIR$\..\..\..\Common\Minimal\EventGroupsDemo.c - $PROJ_DIR$\..\Common\Minimal\GenQTest.c + $PROJ_DIR$\..\..\..\Common\Minimal\GenQTest.c - $PROJ_DIR$\..\Common\Minimal\integer.c + $PROJ_DIR$\..\..\..\Common\Minimal\integer.c - $PROJ_DIR$\..\Common\Minimal\IntQueue.c + $PROJ_DIR$\..\..\..\Common\Minimal\IntQueue.c - $PROJ_DIR$\IntQueueTimer.c + $PROJ_DIR$\..\..\IntQueueTimer.c - $PROJ_DIR$\..\Common\Minimal\IntSemTest.c + $PROJ_DIR$\..\..\..\Common\Minimal\IntSemTest.c - $PROJ_DIR$\..\Common\Minimal\MessageBufferAMP.c + $PROJ_DIR$\..\..\..\Common\Minimal\MessageBufferAMP.c - $PROJ_DIR$\..\Common\Minimal\MessageBufferDemo.c + $PROJ_DIR$\..\..\..\Common\Minimal\MessageBufferDemo.c - $PROJ_DIR$\..\Common\Minimal\PollQ.c + $PROJ_DIR$\..\..\..\Common\Minimal\PollQ.c - $PROJ_DIR$\..\Common\Minimal\QPeek.c + $PROJ_DIR$\..\..\..\Common\Minimal\QPeek.c - $PROJ_DIR$\..\Common\Minimal\QueueOverwrite.c + $PROJ_DIR$\..\..\..\Common\Minimal\QueueOverwrite.c - $PROJ_DIR$\..\Common\Minimal\QueueSet.c + $PROJ_DIR$\..\..\..\Common\Minimal\QueueSet.c - $PROJ_DIR$\..\Common\Minimal\QueueSetPolling.c + $PROJ_DIR$\..\..\..\Common\Minimal\QueueSetPolling.c - $PROJ_DIR$\..\Common\Minimal\recmutex.c + $PROJ_DIR$\..\..\..\Common\Minimal\recmutex.c - $PROJ_DIR$\..\Common\Minimal\semtest.c + $PROJ_DIR$\..\..\..\Common\Minimal\semtest.c - $PROJ_DIR$\..\Common\Minimal\StaticAllocation.c + $PROJ_DIR$\..\..\..\Common\Minimal\StaticAllocation.c - $PROJ_DIR$\..\Common\Minimal\StreamBufferDemo.c + $PROJ_DIR$\..\..\..\Common\Minimal\StreamBufferDemo.c - $PROJ_DIR$\..\Common\Minimal\StreamBufferInterrupt.c + $PROJ_DIR$\..\..\..\Common\Minimal\StreamBufferInterrupt.c - $PROJ_DIR$\..\Common\Minimal\TaskNotify.c + $PROJ_DIR$\..\..\..\Common\Minimal\TaskNotify.c - $PROJ_DIR$\..\Common\Minimal\TaskNotifyArray.c + $PROJ_DIR$\..\..\..\Common\Minimal\TaskNotifyArray.c - $PROJ_DIR$\..\Common\Minimal\TimerDemo.c + $PROJ_DIR$\..\..\..\Common\Minimal\TimerDemo.c - $PROJ_DIR$\main_full.c + $PROJ_DIR$\..\..\main_full.c + + + $PROJ_DIR$\RegTest.S @@ -1589,9 +1632,9 @@ - $PROJ_DIR$\FreeRTOSConfig.h + $PROJ_DIR$\..\..\FreeRTOSConfig.h - $PROJ_DIR$\main.c + $PROJ_DIR$\..\..\main.c diff --git a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/iar/RegTest.S b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/iar/RegTest.S new file mode 100644 index 0000000000..5b0541fc8a --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/iar/RegTest.S @@ -0,0 +1,181 @@ +/* + * 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 + * + */ + +#include + + + RSEG CODE:CODE(2) + thumb + + EXTERN ulRegTest1LoopCounter + EXTERN ulRegTest2LoopCounter + + PUBLIC vRegTest1Implementation + PUBLIC vRegTest2Implementation + +/*-----------------------------------------------------------*/ + +vRegTest1Implementation + + /* Fill the core registers with known values. */ + mov r0, #100 + mov r1, #101 + mov r2, #102 + mov r3, #103 + mov r4, #104 + mov r5, #105 + mov r6, #106 + mov r7, #107 + mov r8, #108 + mov r9, #109 + mov r10, #110 + mov r11, #111 + mov r12, #112 + +reg1_loop: + + 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 + cmp r8, #108 + bne reg1_error_loop + cmp r9, #109 + bne reg1_error_loop + cmp r10, #110 + bne reg1_error_loop + cmp r11, #111 + bne reg1_error_loop + cmp r12, #112 + bne reg1_error_loop + + /* Everything passed, increment the loop counter. */ + push { r0-r1 } + ldr r0, =ulRegTest1LoopCounter + ldr r1, [r0] + adds r1, r1, #1 + str r1, [r0] + pop { r0-r1 } + + /* Start again. */ + 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 + +/*-----------------------------------------------------------*/ + + +vRegTest2Implementation + + /* Set all the core registers to known values. */ + mov r0, #-1 + mov r1, #1 + mov r2, #2 + mov r3, #3 + mov r4, #4 + mov r5, #5 + mov r6, #6 + mov r7, #7 + mov r8, #8 + mov r9, #9 + mov r10, #10 + mov r11, #11 + mov r12, #12 + +reg2_loop: + + cmp r0, #-1 + 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 + cmp r8, #8 + bne reg2_error_loop + cmp r9, #9 + bne reg2_error_loop + cmp r10, #10 + bne reg2_error_loop + cmp r11, #11 + bne reg2_error_loop + cmp r12, #12 + bne reg2_error_loop + + /* Increment the loop counter to indicate this test is still functioning + correctly. */ + push { r0-r1 } + ldr r0, =ulRegTest2LoopCounter + ldr r1, [r0] + adds r1, r1, #1 + str r1, [r0] + + /* Yield to increase test coverage. */ + movs r0, #0x01 + ldr r1, =0xe000ed04 /*NVIC_INT_CTRL */ + lsl r0, r0, #28 /* Shift to PendSV bit */ + str r0, [r1] + dsb + + pop { r0-r1 } + + /* Start again. */ + b reg2_loop + +reg2_error_loop: + /* If this line is hit then there was an error in a core register value. + This loop ensures the loop counter variable stops incrementing. */ + b reg2_error_loop + +/*-----------------------------------------------------------*/ + + + END + diff --git a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main.c b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main.c index e24439f3e8..bf8b07901c 100644 --- a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main.c +++ b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main.c @@ -43,7 +43,7 @@ * Use the following commands to start the application running in a way that * enables the debugger to connect, omit the "-s -S" to run the project without * the debugger: - * qemu-system-arm -machine mps2-an385 -cpu cortex-m3 -kernel [path-to]/RTOSDemo.out -nographic -serial stdio -semihosting -semihosting-config enable=on,target=native -s -S + * qemu-system-arm -machine mps2-an385 -cpu cortex-m3 -kernel [path-to]/RTOSDemo.out -monitor none -nographic -serial stdio -s -S */ /* FreeRTOS includes. */ diff --git a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main_blinky.c b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main_blinky.c index 7fcc3b8050..ad136e6e4b 100644 --- a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main_blinky.c +++ b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main_blinky.c @@ -166,9 +166,9 @@ static void prvQueueSendTask( void * pvParameters ) for( ; ; ) { /* Place this task in the blocked state until it is time to run again. - * The block time is specified in ticks, pdMS_TO_TICKS() was used to - * convert a time specified in milliseconds into a time specified in ticks. - * While in the Blocked state this task will not consume any CPU time. */ + * The block time is specified in ticks, pdMS_TO_TICKS() was used to + * convert a time specified in milliseconds into a time specified in ticks. + * While in the Blocked state this task will not consume any CPU time. */ vTaskDelayUntil( &xNextWakeTime, xBlockTime ); /* Send to the queue - causing the queue receive task to unblock and diff --git a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main_full.c b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main_full.c index fd205845b4..38d50c4d5b 100644 --- a/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main_full.c +++ b/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/main_full.c @@ -109,14 +109,40 @@ * constant is different depending on the compiler in use. */ #define mainMESSAGE_BUFFER_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) ) #define mainCHECK_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) ) + +/* 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 ) + /*-----------------------------------------------------------*/ +/* + * 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 task that checks the operation of all the other standard demo tasks, as * described at the top of this file. */ static void prvCheckTask( void * pvParameters ); /*-----------------------------------------------------------*/ +/* The following two variables are used to communicate the status of the + * register test tasks to the check task. If the variables keep incrementing, + * then the register test 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 the standard demo tasks. */ @@ -144,6 +170,15 @@ void main_full( void ) vStartStreamBufferInterruptDemo(); vStartInterruptSemaphoreTasks(); + /* Create the register check tasks, as described at the top of this file */ + xTaskCreate( prvRegTestTaskEntry1, /* Function that implements the task. */ + "Reg1", /* Human readable name for the task - not used by the kernel but helps debugging. */ + configMINIMAL_STACK_SIZE, /* Size of stack to allocate for the task - in words not bytes. */ + mainREG_TEST_TASK_1_PARAMETER, /* A parameter passed into the task to check parameter passing is working correctly. */ + tskIDLE_PRIORITY, /* Priority assigned to the task - must be between 0 (tskIDLE_PRIORITY) and (configMAX_PRIORITIES - 1). */ + NULL ); /* Can be used to pass a handle to the create task out of the xTaskCreate() function. */ + xTaskCreate( prvRegTestTaskEntry2, "Reg2", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL ); + /* The suicide tasks must be created last as they need to know how many * tasks were running prior to their creation in order to ascertain whether * or not the correct/expected number of tasks are running at any given time. */ @@ -168,6 +203,8 @@ void main_full( void ) static void prvCheckTask( void * pvParameters ) { static const char * pcMessage = "PASS"; + unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; + const TickType_t xTaskPeriod = pdMS_TO_TICKS( 5000UL ); TickType_t xPreviousWakeTime; extern uint32_t ulNestCount; @@ -279,6 +316,19 @@ static void prvCheckTask( void * pvParameters ) { pcMessage = "xAreInterruptSemaphoreTasksStillRunning() returned false"; } + else if( ulLastRegTest1Value == ulRegTest1LoopCounter ) + { + /* Check that the register test 1 task is still running. */ + pcMessage = "Error in RegTest 1"; + } + else if( ulLastRegTest2Value == ulRegTest2LoopCounter ) + { + /* Check that the register test 2 task is still running. */ + pcMessage = "Error in RegTest 2"; + } + + ulLastRegTest1Value = ulRegTest1LoopCounter; + ulLastRegTest2Value = ulRegTest2LoopCounter; /* It is normally not good to call printf() from an embedded system, * although it is ok in this simulated case. */ @@ -319,3 +369,40 @@ void vFullDemoTickHookFunction( void ) vInterruptSemaphorePeriodicTest(); } /*-----------------------------------------------------------*/ + +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 ); +} +/*-----------------------------------------------------------*/ +