├── FreeRTOS.html ├── FreeRTOS_API.html ├── LICENSE ├── README.md ├── examples └── blink_task.cpp ├── library.json ├── library.properties └── src ├── FreeRTOS.h ├── FreeRTOSConfig.h ├── FreeRTOSConfig_default.h ├── FreeRTOS_TEENSY4.c ├── FreeRTOS_TEENSY4.h ├── StackMacros.h ├── croutine.c ├── croutine.h ├── deprecated_definitions.h ├── event_groups.c ├── event_groups.h ├── heap_3.c ├── list.c ├── list.h ├── memcpy-armv7m.S ├── memset.S ├── message_buffer.h ├── mpu_prototypes.h ├── mpu_wrappers.h ├── port.c ├── portable.h ├── portmacro.h ├── projdefs.h ├── queue.c ├── queue.h ├── semphr.h ├── stack_macros.h ├── stream_buffer.c ├── stream_buffer.h ├── task.h ├── tasks.c ├── threading_alt.h ├── timers.c └── timers.h /FreeRTOS.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | A web page that points a browser to a different page 4 | 5 | 6 | 7 | 8 | Your browser didn't automatically redirect. Open html/index.html manually. 9 | 10 | 11 | -------------------------------------------------------------------------------- /FreeRTOS_API.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2020 Julian DESVIGNES 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Teensy 4.0 FreeRTOS Library for Teensyduino 2 | 3 | This is a port of FreeRTOS 10.0 for the Teensy 4.0 running teensyduino 4 | 5 | This is based on https://github.com/greiman/FreeRTOS-Arduino for the error handling. 6 | 7 | The Arduino systick-ing is kept running after starting the scheduler, so `delay`, `millis` and `micro` work in tasks. 8 | *For better performance, use `vTaskDelay` instead of `delay`* 9 | 10 | The documentation for FreeRTOS is located here: 11 | http://www.freertos.org/ 12 | 13 | ## FreeRTOS configuration 14 | 15 | The default configuration is in `FreeRTOSConfig_Default.h`. 16 | 17 | You can specify your own by having an include file named `Teensy4FreeRTOSConfig.h`, 18 | or you can add/replace to the default one by having an include file named `Teensy4FreeRTOSConfig_addition.h`. 19 | 20 | ### Run-time stats 21 | 22 | Activating run-time stats (`configGENERATE_RUN_TIME_STATS`) configures Timer3, this will affect the PWM on pins 6, 7, 8 and 9. Please avoid using them when using run-time stats as it might cause conflict. 23 | 24 | If you still want to use them as PWM, please look at [this library](https://github.com/PaulStoffregen/TimerThree) and mimick its actions for configuring the PWM without touching the timer. 25 | 26 | ### For PlatformIO users 27 | 28 | The way PlatformIO works makes it impossible to load a configuration header in a system-level library. 29 | If you installed this library using the library manager, your config files will not be read as PlatformIO isolates the library from your project files when building it. 30 | 31 | To alleviate this problem, you can clone this repository in the `lib` folder of your project and add the config files in your `include` folder. 32 | PlatformIO will blindly search for includes in `../../include/` as per project configuration. 33 | 34 | When the PlatformIO team implements a way to add per-project configuration files, I will update this method. 35 | 36 | ## How-to 37 | 38 | Please read FreeRTOS.html for more information. 39 | 40 | See FreeRTOS_API.html for API documentation. 41 | -------------------------------------------------------------------------------- /examples/blink_task.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Example to demonstrate thread definition, semaphores, and thread sleep. 3 | */ 4 | #include 5 | 6 | // The LED is attached to pin 13 on the Teensy 4.0 7 | const uint8_t LED_PIN = 13; 8 | 9 | // Declare a semaphore handle. 10 | SemaphoreHandle_t sem; 11 | //------------------------------------------------------------------------------ 12 | /* 13 | * Thread 1, turn the LED off when signalled by thread 2. 14 | */ 15 | // Declare the thread function for thread 1. 16 | static void Thread1(void* arg) { 17 | while (1) { 18 | 19 | Serial.println("Thread 1 : Waiting on Thread 2 to turn LED OFF"); 20 | 21 | // Wait for signal from thread 2. 22 | xSemaphoreTake(sem, portMAX_DELAY); 23 | 24 | Serial.println("Thread 1 : Turning LED OFF"); 25 | 26 | // Turn LED off. 27 | digitalWrite(LED_PIN, LOW); 28 | } 29 | } 30 | //------------------------------------------------------------------------------ 31 | /* 32 | * Thread 2, turn the LED on and signal thread 1 to turn the LED off. 33 | */ 34 | // Declare the thread function for thread 2. 35 | static void Thread2(void* arg) { 36 | 37 | pinMode(LED_PIN, OUTPUT); 38 | 39 | while (1) { 40 | // Turn LED on. 41 | digitalWrite(LED_PIN, HIGH); 42 | 43 | Serial.println("Thread 2 : Turning LED ON"); 44 | 45 | // Sleep for 200 milliseconds. 46 | vTaskDelay((200L * configTICK_RATE_HZ) / 1000L); 47 | 48 | Serial.println("Thread 2 : Asking Thread 1 to turn LED OFF"); 49 | 50 | // Signal thread 1 to turn LED off. 51 | xSemaphoreGive(sem); 52 | 53 | // Sleep for 200 milliseconds. 54 | vTaskDelay((200L * configTICK_RATE_HZ) / 1000L); 55 | } 56 | } 57 | //------------------------------------------------------------------------------ 58 | void setup() { 59 | portBASE_TYPE s1, s2; 60 | 61 | Serial.begin(9600); 62 | 63 | // initialize semaphore 64 | sem = xSemaphoreCreateCounting(1, 0); 65 | 66 | // create task at priority two 67 | s1 = xTaskCreate(Thread1, NULL, configMINIMAL_STACK_SIZE, NULL, 2, NULL); 68 | 69 | // create task at priority one 70 | s2 = xTaskCreate(Thread2, NULL, configMINIMAL_STACK_SIZE, NULL, 1, NULL); 71 | 72 | // check for creation errors 73 | if (sem== NULL || s1 != pdPASS || s2 != pdPASS ) { 74 | Serial.println("Creation problem"); 75 | while(1); 76 | } 77 | 78 | Serial.println("Starting the scheduler !"); 79 | 80 | // start scheduler 81 | vTaskStartScheduler(); 82 | Serial.println("Insufficient RAM"); 83 | while(1); 84 | } 85 | //------------------------------------------------------------------------------ 86 | // WARNING idle loop has a very small stack (configMINIMAL_STACK_SIZE) 87 | // loop must never block 88 | void loop() { 89 | // Not used. 90 | } -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FreeRTOS-Teensy4", 3 | "version": "10.0.5", 4 | "keywords": "rtos, freertos, teensy4", 5 | "description": "Teensy 4.0 FreeRTOS Library for Teensyduino", 6 | "repository": 7 | { 8 | "type": "git", 9 | "url": "https://github.com/discord-intech/FreeRTOS-Teensy4.git" 10 | }, 11 | "authors": 12 | [ 13 | { 14 | "name": "Julian Desvignes", 15 | "email": "julian.desvignes@rakuten.com", 16 | "maintainer": true 17 | } 18 | ], 19 | "export": { 20 | "include": 21 | [ 22 | "src/*", 23 | "examples/*" 24 | ] 25 | }, 26 | "frameworks": "arduino", 27 | "platforms": "teensy", 28 | "build": 29 | { 30 | "flags": "-mno-unaligned-access", 31 | "libArchive": false, 32 | "includeDir": "../../include/" 33 | } 34 | } -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=FreeRTOS-Teensy4 2 | version=10.0.5 3 | author=Julian Desvignes 4 | maintainer=Julian Desvignes 5 | sentence=Teensy 4.0 FreeRTOS Library for Teensyduino 6 | paragraph=FreeRTOS provides methods for multiple threads or tasks, mutexes, semaphores, ... with a small footprint. 7 | category=Timing 8 | url=https://github.com/discord-intech/FreeRTOS-Teensy4.git 9 | architectures=teensy 10 | -------------------------------------------------------------------------------- /src/FreeRTOSConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef SELECT_FREERTOS_CONFIG_H 2 | #define SELECT_FREERTOS_CONFIG_H 3 | 4 | #if __has_include("Teensy4FreeRTOSConfig.h") 5 | #include "Teensy4FreeRTOSConfig.h" 6 | #else 7 | #if __has_include("Teensy4FreeRTOSConfig_addition.h") 8 | #include "Teensy4FreeRTOSConfig_addition.h" 9 | #endif 10 | #include "FreeRTOSConfig_default.h" 11 | #endif 12 | 13 | #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 0 ) ) 14 | #error If configGENERATE_RUN_TIME_STATS is 1, then configUSE_STATS_FORMATTING_FUNCTIONS should not be zero 15 | #endif 16 | 17 | #if configGENERATE_RUN_TIME_STATS == 1 18 | extern volatile uint64_t ulTimerCounter; 19 | extern void vPortSetupRuntimeTimer(); 20 | #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vPortSetupRuntimeTimer() 21 | #define portGET_RUN_TIME_COUNTER_VALUE() ulTimerCounter 22 | #endif 23 | 24 | #endif // SELECT_FREERTOS_CONFIG_H -------------------------------------------------------------------------------- /src/FreeRTOSConfig_default.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://aws.amazon.com/freertos 23 | * http://www.FreeRTOS.org 24 | */ 25 | 26 | #ifndef FREERTOS_CONFIG_H 27 | #define FREERTOS_CONFIG_H 28 | 29 | #include 30 | 31 | /*----------------------------------------------------------- 32 | * Application specific definitions. 33 | * 34 | * These definitions should be adjusted for your particular hardware and 35 | * application requirements. 36 | * 37 | * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE 38 | * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. 39 | * 40 | * See http://www.freertos.org/a00110.html. 41 | *----------------------------------------------------------*/ 42 | 43 | #define F_CPU 600000000 44 | 45 | #define configUSE_PREEMPTION 1 46 | #define configUSE_TICKLESS_IDLE 0 47 | #define configCPU_CLOCK_HZ (F_CPU) 48 | #define configTICK_RATE_HZ ((TickType_t)1000) 49 | #define configMAX_PRIORITIES ( 10 ) 50 | #define configMINIMAL_STACK_SIZE ((unsigned short)90) 51 | #define configMINIMAL_SECURE_STACK_SIZE ((unsigned short)120) 52 | #define configMAX_TASK_NAME_LEN 20 53 | #define configUSE_16_BIT_TICKS 0 54 | #define configIDLE_SHOULD_YIELD 1 55 | #define configUSE_TASK_NOTIFICATIONS 1 56 | #define configUSE_MUTEXES 1 57 | #define configUSE_RECURSIVE_MUTEXES 1 58 | #define configUSE_COUNTING_SEMAPHORES 1 59 | #define configUSE_ALTERNATIVE_API 0 /* Deprecated! */ 60 | #define configQUEUE_REGISTRY_SIZE 8 61 | #define configUSE_QUEUE_SETS 0 62 | #define configUSE_TIME_SLICING 0 63 | #define configUSE_NEWLIB_REENTRANT 0 64 | #define configENABLE_BACKWARD_COMPATIBILITY 1 65 | #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 66 | #define configUSE_APPLICATION_TASK_TAG 0 67 | 68 | /* Memory allocation related definitions. */ 69 | #define configSUPPORT_STATIC_ALLOCATION 0 70 | #define configSUPPORT_DYNAMIC_ALLOCATION 1 71 | #define configTOTAL_HEAP_SIZE ((size_t)(256000)) 72 | #define configAPPLICATION_ALLOCATED_HEAP 0 73 | 74 | /* Hook function related definitions. */ 75 | #define configUSE_IDLE_HOOK 0 76 | #define configUSE_TICK_HOOK 0 77 | #define configCHECK_FOR_STACK_OVERFLOW 0 78 | #define configUSE_MALLOC_FAILED_HOOK 0 79 | #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 80 | 81 | /* Run time and task stats gathering related definitions. */ 82 | #define configGENERATE_RUN_TIME_STATS 0 83 | #define configUSE_TRACE_FACILITY 1 84 | #define configUSE_STATS_FORMATTING_FUNCTIONS 0 85 | 86 | /* Co-routine related definitions. */ 87 | #define configUSE_CO_ROUTINES 0 88 | #define configMAX_CO_ROUTINE_PRIORITIES 2 89 | 90 | /* Software timer related definitions. */ 91 | #define configUSE_TIMERS 1 92 | #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) 93 | #define configTIMER_QUEUE_LENGTH 10 94 | #define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2) 95 | 96 | /* Define to trap errors during development. */ 97 | //#define configASSERT(x) if((x) == 0) {taskDISABLE_INTERRUPTS(); for (;;);} 98 | 99 | /* Optional functions - most linkers will remove unused functions anyway. */ 100 | #define INCLUDE_vTaskPrioritySet 1 101 | #define INCLUDE_uxTaskPriorityGet 1 102 | #define INCLUDE_vTaskDelete 1 103 | #define INCLUDE_vTaskSuspend 1 104 | #define INCLUDE_vTaskDelayUntil 1 105 | #define INCLUDE_vTaskDelay 1 106 | #define INCLUDE_xTaskGetSchedulerState 1 107 | #define INCLUDE_xTaskGetCurrentTaskHandle 1 108 | #define INCLUDE_uxTaskGetStackHighWaterMark 0 109 | #define INCLUDE_xTaskGetIdleTaskHandle 0 110 | #define INCLUDE_eTaskGetState 0 111 | #define INCLUDE_xTimerPendFunctionCall 1 112 | #define INCLUDE_xTaskAbortDelay 0 113 | #define INCLUDE_xTaskGetHandle 1 114 | #define INCLUDE_xTaskResumeFromISR 1 115 | #define INCLUDE_vTaskEndScheduler 0 116 | 117 | #ifdef __NVIC_PRIO_BITS 118 | /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ 119 | #define configPRIO_BITS __NVIC_PRIO_BITS 120 | #else 121 | #define configPRIO_BITS 8 122 | #endif 123 | 124 | /* The lowest interrupt priority that can be used in a call to a "set priority" 125 | function. */ 126 | #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1U << (configPRIO_BITS)) - 1) 127 | 128 | /* The highest interrupt priority that can be used by any interrupt service 129 | routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL 130 | INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER 131 | PRIORITY THAN THIS! (higher priorities are lower numeric values. */ 132 | #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2 133 | 134 | /* Interrupt priorities used by the kernel port layer itself. These are generic 135 | to all Cortex-M ports, and do not rely on any particular library functions. */ 136 | #define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) 137 | /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! 138 | See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ 139 | #define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) 140 | 141 | /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS 142 | standard names. */ 143 | //#define vPortSVCHandler SVC_Handler 144 | //#define xPortPendSVHandler PendSV_Handler 145 | //#define xPortSysTickHandler SysTick_Handler 146 | 147 | #endif /* FREERTOS_CONFIG_H */ 148 | -------------------------------------------------------------------------------- /src/FreeRTOS_TEENSY4.c: -------------------------------------------------------------------------------- 1 | /** 2 | * \file 3 | * \brief FreeRTOS for Teensy 4.0 4 | */ 5 | #include "FreeRTOS_TEENSY4.h" 6 | #include 7 | //------------------------------------------------------------------------------ 8 | /** calibration factor for delayMS */ 9 | #define CAL_FACTOR (F_CPU/7000) 10 | /** delay between led error flashes 11 | * \param[in] millis milliseconds to delay 12 | */ 13 | static void delayMS(uint32_t millis) { 14 | uint32_t iterations = millis * CAL_FACTOR; 15 | uint32_t i; 16 | for(i = 0; i < iterations; ++i) { 17 | asm volatile("nop\n\t"); 18 | } 19 | } 20 | //------------------------------------------------------------------------------ 21 | /** Blink error pattern 22 | * 23 | * \param[in] n number of short pulses 24 | */ 25 | static void errorBlink(int n) { 26 | noInterrupts(); 27 | pinMode(13, OUTPUT); 28 | for (;;) { 29 | int i; 30 | for (i = 0; i < n; i++) { 31 | digitalWrite(13, 1); 32 | delayMS(300); 33 | digitalWrite(13, 0); 34 | delayMS(300); 35 | } 36 | delayMS(2000); 37 | } 38 | } 39 | //------------------------------------------------------------------------------ 40 | /** assertBlink 41 | * Blink one short pulse every two seconds if configASSERT fails. 42 | */ 43 | void assertBlink() { 44 | errorBlink(1); 45 | } 46 | //------------------------------------------------------------------------------ 47 | /** vApplicationMallocFailedHook() 48 | Blink two short pulses if malloc fails. 49 | 50 | will only be called if 51 | configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook 52 | function that will get called if a call to pvPortMalloc() fails. 53 | pvPortMalloc() is called internally by the kernel whenever a task, queue, 54 | timer or semaphore is created. It is also called by various parts of the 55 | demo application. If heap_1.c or heap_2.c are used, then the size of the 56 | heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in 57 | FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used 58 | to query the size of free heap space that remains (although it does not 59 | provide information on how the remaining heap might be fragmented). */ 60 | void vApplicationMallocFailedHook() { 61 | errorBlink(2); 62 | } 63 | //------------------------------------------------------------------------------ 64 | 65 | /** vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set 66 | to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle 67 | task. It is essential that code added to this hook function never attempts 68 | to block in any way (for example, call xQueueReceive() with a block time 69 | specified, or call vTaskDelay()). If the application makes use of the 70 | vTaskDelete() API function (as this demo application does) then it is also 71 | important that vApplicationIdleHook() is permitted to return to its calling 72 | function, because it is the responsibility of the idle task to clean up 73 | memory allocated by the kernel to any task that has since been deleted. */ 74 | void __attribute__((weak)) vApplicationIdleHook( void ) { 75 | void loop(); 76 | loop(); 77 | } 78 | /*-----------------------------------------------------------*/ 79 | /** Blink three short pulses if stack overflow is detected. 80 | Run time stack overflow checking is performed if 81 | configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook 82 | function is called if a stack overflow is detected. 83 | \param[in] pxTask Task handle 84 | \param[in] pcTaskName Task name 85 | */ 86 | void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) { 87 | (void) pcTaskName; 88 | (void) pxTask; 89 | errorBlink(3); 90 | } 91 | //------------------------------------------------------------------------------ 92 | // catch Teensy 3 and Due exceptions 93 | /** Hard fault - blink four short flash every two seconds */ 94 | void hard_fault_isr() {errorBlink(4);} 95 | /** Hard fault - blink four short flash every two seconds */ 96 | void HardFault_Handler() {errorBlink(4);} 97 | 98 | /** Bus fault - blink five short flashes every two seconds */ 99 | void bus_fault_isr() {errorBlink(5);} 100 | /** Bus fault - blink five short flashes every two seconds */ 101 | void BusFault_Handler() {errorBlink(5);} 102 | 103 | /** Usage fault - blink six short flashes every two seconds */ 104 | void usage_fault_isr() {errorBlink(6);} 105 | /** Usage fault - blink six short flashes every two seconds */ 106 | void UsageFault_Handler() {errorBlink(6);} 107 | /*-----------------------------------------------------------*/ 108 | /** This function will be called by each tick interrupt if 109 | configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be 110 | added here, but the tick hook is called from an interrupt context, so 111 | code must not attempt to block, and only the interrupt safe FreeRTOS API 112 | functions can be used (those that end in FromISR()). */ 113 | void __attribute__((weak)) vApplicationTickHook() { 114 | } 115 | /*-----------------------------------------------------------*/ 116 | /** Dummy time stats gathering functions need to be defined to keep the 117 | linker happy. Could edit FreeRTOSConfig.h to remove these.*/ 118 | void vMainConfigureTimerForRunTimeStats( void ) {} 119 | /** Dummy function 120 | * \return zero 121 | */ 122 | unsigned long ulMainGetRunTimeCounterValue() {return 0UL;} -------------------------------------------------------------------------------- /src/FreeRTOS_TEENSY4.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file 3 | * \brief FreeRTOS for Teensy 4.0 4 | */ 5 | #ifndef FreeRTOS_TEENSY4_h 6 | #define FreeRTOS_TEENSY4_h 7 | 8 | #ifndef __arm__ 9 | #error Teensy 4.0 required 10 | #else // __arm__ 11 | 12 | #include 13 | 14 | #include "FreeRTOS.h" 15 | #include "task.h" 16 | #include "queue.h" 17 | #include "semphr.h" 18 | #include "portmacro.h" 19 | 20 | #endif // __arm__ 21 | #endif // FreeRTOS_TEENSY4_h -------------------------------------------------------------------------------- /src/StackMacros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef STACK_MACROS_H 29 | #define STACK_MACROS_H 30 | 31 | #ifndef _MSC_VER /* Visual Studio doesn't support #warning. */ 32 | #warning The name of this file has changed to stack_macros.h. Please update your code accordingly. This source file (which has the original name) will be removed in future released. 33 | #endif 34 | 35 | /* 36 | * Call the stack overflow hook function if the stack of the task being swapped 37 | * out is currently overflowed, or looks like it might have overflowed in the 38 | * past. 39 | * 40 | * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check 41 | * the current stack state only - comparing the current top of stack value to 42 | * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 43 | * will also cause the last few stack bytes to be checked to ensure the value 44 | * to which the bytes were set when the task was created have not been 45 | * overwritten. Note this second test does not guarantee that an overflowed 46 | * stack will always be recognised. 47 | */ 48 | 49 | /*-----------------------------------------------------------*/ 50 | 51 | #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) 52 | 53 | /* Only the current stack state is to be checked. */ 54 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 55 | { \ 56 | /* Is the currently saved stack pointer within the stack limit? */ \ 57 | if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ 58 | { \ 59 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 60 | } \ 61 | } 62 | 63 | #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ 64 | /*-----------------------------------------------------------*/ 65 | 66 | #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) 67 | 68 | /* Only the current stack state is to be checked. */ 69 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 70 | { \ 71 | \ 72 | /* Is the currently saved stack pointer within the stack limit? */ \ 73 | if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ 74 | { \ 75 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 76 | } \ 77 | } 78 | 79 | #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ 80 | /*-----------------------------------------------------------*/ 81 | 82 | #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) 83 | 84 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 85 | { \ 86 | const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ 87 | const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ 88 | \ 89 | if( ( pulStack[ 0 ] != ulCheckValue ) || \ 90 | ( pulStack[ 1 ] != ulCheckValue ) || \ 91 | ( pulStack[ 2 ] != ulCheckValue ) || \ 92 | ( pulStack[ 3 ] != ulCheckValue ) ) \ 93 | { \ 94 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 95 | } \ 96 | } 97 | 98 | #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 99 | /*-----------------------------------------------------------*/ 100 | 101 | #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) 102 | 103 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 104 | { \ 105 | int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ 106 | static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 107 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 108 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 109 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 110 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ 111 | \ 112 | \ 113 | pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ 114 | \ 115 | /* Has the extremity of the task stack ever been written over? */ \ 116 | if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ 117 | { \ 118 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 119 | } \ 120 | } 121 | 122 | #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 123 | /*-----------------------------------------------------------*/ 124 | 125 | /* Remove stack overflow macro if not being used. */ 126 | #ifndef taskCHECK_FOR_STACK_OVERFLOW 127 | #define taskCHECK_FOR_STACK_OVERFLOW() 128 | #endif 129 | 130 | 131 | 132 | #endif /* STACK_MACROS_H */ 133 | 134 | -------------------------------------------------------------------------------- /src/croutine.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #include "FreeRTOS.h" 29 | #include "task.h" 30 | #include "croutine.h" 31 | 32 | /* Remove the whole file is co-routines are not being used. */ 33 | #if( configUSE_CO_ROUTINES != 0 ) 34 | 35 | /* 36 | * Some kernel aware debuggers require data to be viewed to be global, rather 37 | * than file scope. 38 | */ 39 | #ifdef portREMOVE_STATIC_QUALIFIER 40 | #define static 41 | #endif 42 | 43 | 44 | /* Lists for ready and blocked co-routines. --------------------*/ 45 | static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ 46 | static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */ 47 | static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ 48 | static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ 49 | static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ 50 | static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ 51 | 52 | /* Other file private variables. --------------------------------*/ 53 | CRCB_t * pxCurrentCoRoutine = NULL; 54 | static UBaseType_t uxTopCoRoutineReadyPriority = 0; 55 | static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; 56 | 57 | /* The initial state of the co-routine when it is created. */ 58 | #define corINITIAL_STATE ( 0 ) 59 | 60 | /* 61 | * Place the co-routine represented by pxCRCB into the appropriate ready queue 62 | * for the priority. It is inserted at the end of the list. 63 | * 64 | * This macro accesses the co-routine ready lists and therefore must not be 65 | * used from within an ISR. 66 | */ 67 | #define prvAddCoRoutineToReadyQueue( pxCRCB ) \ 68 | { \ 69 | if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ 70 | { \ 71 | uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ 72 | } \ 73 | vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ 74 | } 75 | 76 | /* 77 | * Utility to ready all the lists used by the scheduler. This is called 78 | * automatically upon the creation of the first co-routine. 79 | */ 80 | static void prvInitialiseCoRoutineLists( void ); 81 | 82 | /* 83 | * Co-routines that are readied by an interrupt cannot be placed directly into 84 | * the ready lists (there is no mutual exclusion). Instead they are placed in 85 | * in the pending ready list in order that they can later be moved to the ready 86 | * list by the co-routine scheduler. 87 | */ 88 | static void prvCheckPendingReadyList( void ); 89 | 90 | /* 91 | * Macro that looks at the list of co-routines that are currently delayed to 92 | * see if any require waking. 93 | * 94 | * Co-routines are stored in the queue in the order of their wake time - 95 | * meaning once one co-routine has been found whose timer has not expired 96 | * we need not look any further down the list. 97 | */ 98 | static void prvCheckDelayedList( void ); 99 | 100 | /*-----------------------------------------------------------*/ 101 | 102 | BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ) 103 | { 104 | BaseType_t xReturn; 105 | CRCB_t *pxCoRoutine; 106 | 107 | /* Allocate the memory that will store the co-routine control block. */ 108 | pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); 109 | if( pxCoRoutine ) 110 | { 111 | /* If pxCurrentCoRoutine is NULL then this is the first co-routine to 112 | be created and the co-routine data structures need initialising. */ 113 | if( pxCurrentCoRoutine == NULL ) 114 | { 115 | pxCurrentCoRoutine = pxCoRoutine; 116 | prvInitialiseCoRoutineLists(); 117 | } 118 | 119 | /* Check the priority is within limits. */ 120 | if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) 121 | { 122 | uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; 123 | } 124 | 125 | /* Fill out the co-routine control block from the function parameters. */ 126 | pxCoRoutine->uxState = corINITIAL_STATE; 127 | pxCoRoutine->uxPriority = uxPriority; 128 | pxCoRoutine->uxIndex = uxIndex; 129 | pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; 130 | 131 | /* Initialise all the other co-routine control block parameters. */ 132 | vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); 133 | vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); 134 | 135 | /* Set the co-routine control block as a link back from the ListItem_t. 136 | This is so we can get back to the containing CRCB from a generic item 137 | in a list. */ 138 | listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); 139 | listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); 140 | 141 | /* Event lists are always in priority order. */ 142 | listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); 143 | 144 | /* Now the co-routine has been initialised it can be added to the ready 145 | list at the correct priority. */ 146 | prvAddCoRoutineToReadyQueue( pxCoRoutine ); 147 | 148 | xReturn = pdPASS; 149 | } 150 | else 151 | { 152 | xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; 153 | } 154 | 155 | return xReturn; 156 | } 157 | /*-----------------------------------------------------------*/ 158 | 159 | void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ) 160 | { 161 | TickType_t xTimeToWake; 162 | 163 | /* Calculate the time to wake - this may overflow but this is 164 | not a problem. */ 165 | xTimeToWake = xCoRoutineTickCount + xTicksToDelay; 166 | 167 | /* We must remove ourselves from the ready list before adding 168 | ourselves to the blocked list as the same list item is used for 169 | both lists. */ 170 | ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); 171 | 172 | /* The list item will be inserted in wake time order. */ 173 | listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); 174 | 175 | if( xTimeToWake < xCoRoutineTickCount ) 176 | { 177 | /* Wake time has overflowed. Place this item in the 178 | overflow list. */ 179 | vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); 180 | } 181 | else 182 | { 183 | /* The wake time has not overflowed, so we can use the 184 | current block list. */ 185 | vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); 186 | } 187 | 188 | if( pxEventList ) 189 | { 190 | /* Also add the co-routine to an event list. If this is done then the 191 | function must be called with interrupts disabled. */ 192 | vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); 193 | } 194 | } 195 | /*-----------------------------------------------------------*/ 196 | 197 | static void prvCheckPendingReadyList( void ) 198 | { 199 | /* Are there any co-routines waiting to get moved to the ready list? These 200 | are co-routines that have been readied by an ISR. The ISR cannot access 201 | the ready lists itself. */ 202 | while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) 203 | { 204 | CRCB_t *pxUnblockedCRCB; 205 | 206 | /* The pending ready list can be accessed by an ISR. */ 207 | portDISABLE_INTERRUPTS(); 208 | { 209 | pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); 210 | ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); 211 | } 212 | portENABLE_INTERRUPTS(); 213 | 214 | ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); 215 | prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); 216 | } 217 | } 218 | /*-----------------------------------------------------------*/ 219 | 220 | static void prvCheckDelayedList( void ) 221 | { 222 | CRCB_t *pxCRCB; 223 | 224 | xPassedTicks = xTaskGetTickCount() - xLastTickCount; 225 | while( xPassedTicks ) 226 | { 227 | xCoRoutineTickCount++; 228 | xPassedTicks--; 229 | 230 | /* If the tick count has overflowed we need to swap the ready lists. */ 231 | if( xCoRoutineTickCount == 0 ) 232 | { 233 | List_t * pxTemp; 234 | 235 | /* Tick count has overflowed so we need to swap the delay lists. If there are 236 | any items in pxDelayedCoRoutineList here then there is an error! */ 237 | pxTemp = pxDelayedCoRoutineList; 238 | pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; 239 | pxOverflowDelayedCoRoutineList = pxTemp; 240 | } 241 | 242 | /* See if this tick has made a timeout expire. */ 243 | while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) 244 | { 245 | pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); 246 | 247 | if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) 248 | { 249 | /* Timeout not yet expired. */ 250 | break; 251 | } 252 | 253 | portDISABLE_INTERRUPTS(); 254 | { 255 | /* The event could have occurred just before this critical 256 | section. If this is the case then the generic list item will 257 | have been moved to the pending ready list and the following 258 | line is still valid. Also the pvContainer parameter will have 259 | been set to NULL so the following lines are also valid. */ 260 | ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); 261 | 262 | /* Is the co-routine waiting on an event also? */ 263 | if( pxCRCB->xEventListItem.pxContainer ) 264 | { 265 | ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); 266 | } 267 | } 268 | portENABLE_INTERRUPTS(); 269 | 270 | prvAddCoRoutineToReadyQueue( pxCRCB ); 271 | } 272 | } 273 | 274 | xLastTickCount = xCoRoutineTickCount; 275 | } 276 | /*-----------------------------------------------------------*/ 277 | 278 | void vCoRoutineSchedule( void ) 279 | { 280 | /* See if any co-routines readied by events need moving to the ready lists. */ 281 | prvCheckPendingReadyList(); 282 | 283 | /* See if any delayed co-routines have timed out. */ 284 | prvCheckDelayedList(); 285 | 286 | /* Find the highest priority queue that contains ready co-routines. */ 287 | while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) 288 | { 289 | if( uxTopCoRoutineReadyPriority == 0 ) 290 | { 291 | /* No more co-routines to check. */ 292 | return; 293 | } 294 | --uxTopCoRoutineReadyPriority; 295 | } 296 | 297 | /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines 298 | of the same priority get an equal share of the processor time. */ 299 | listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); 300 | 301 | /* Call the co-routine. */ 302 | ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); 303 | 304 | return; 305 | } 306 | /*-----------------------------------------------------------*/ 307 | 308 | static void prvInitialiseCoRoutineLists( void ) 309 | { 310 | UBaseType_t uxPriority; 311 | 312 | for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) 313 | { 314 | vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); 315 | } 316 | 317 | vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); 318 | vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); 319 | vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); 320 | 321 | /* Start with pxDelayedCoRoutineList using list1 and the 322 | pxOverflowDelayedCoRoutineList using list2. */ 323 | pxDelayedCoRoutineList = &xDelayedCoRoutineList1; 324 | pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; 325 | } 326 | /*-----------------------------------------------------------*/ 327 | 328 | BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ) 329 | { 330 | CRCB_t *pxUnblockedCRCB; 331 | BaseType_t xReturn; 332 | 333 | /* This function is called from within an interrupt. It can only access 334 | event lists and the pending ready list. This function assumes that a 335 | check has already been made to ensure pxEventList is not empty. */ 336 | pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); 337 | ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); 338 | vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); 339 | 340 | if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) 341 | { 342 | xReturn = pdTRUE; 343 | } 344 | else 345 | { 346 | xReturn = pdFALSE; 347 | } 348 | 349 | return xReturn; 350 | } 351 | 352 | #endif /* configUSE_CO_ROUTINES == 0 */ 353 | 354 | -------------------------------------------------------------------------------- /src/croutine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef CO_ROUTINE_H 29 | #define CO_ROUTINE_H 30 | 31 | #ifndef INC_FREERTOS_H 32 | #error "include FreeRTOS.h must appear in source files before include croutine.h" 33 | #endif 34 | 35 | #include "list.h" 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #endif 40 | 41 | /* Used to hide the implementation of the co-routine control block. The 42 | control block structure however has to be included in the header due to 43 | the macro implementation of the co-routine functionality. */ 44 | typedef void * CoRoutineHandle_t; 45 | 46 | /* Defines the prototype to which co-routine functions must conform. */ 47 | typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t ); 48 | 49 | typedef struct corCoRoutineControlBlock 50 | { 51 | crCOROUTINE_CODE pxCoRoutineFunction; 52 | ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ 53 | ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */ 54 | UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ 55 | UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ 56 | uint16_t uxState; /*< Used internally by the co-routine implementation. */ 57 | } CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */ 58 | 59 | /** 60 | * croutine. h 61 | *
 62 |  BaseType_t xCoRoutineCreate(
 63 |                                  crCOROUTINE_CODE pxCoRoutineCode,
 64 |                                  UBaseType_t uxPriority,
 65 |                                  UBaseType_t uxIndex
 66 |                                );
67 | * 68 | * Create a new co-routine and add it to the list of co-routines that are 69 | * ready to run. 70 | * 71 | * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine 72 | * functions require special syntax - see the co-routine section of the WEB 73 | * documentation for more information. 74 | * 75 | * @param uxPriority The priority with respect to other co-routines at which 76 | * the co-routine will run. 77 | * 78 | * @param uxIndex Used to distinguish between different co-routines that 79 | * execute the same function. See the example below and the co-routine section 80 | * of the WEB documentation for further information. 81 | * 82 | * @return pdPASS if the co-routine was successfully created and added to a ready 83 | * list, otherwise an error code defined with ProjDefs.h. 84 | * 85 | * Example usage: 86 |
 87 |  // Co-routine to be created.
 88 |  void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 89 |  {
 90 |  // Variables in co-routines must be declared static if they must maintain value across a blocking call.
 91 |  // This may not be necessary for const variables.
 92 |  static const char cLedToFlash[ 2 ] = { 5, 6 };
 93 |  static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
 94 | 
 95 |      // Must start every co-routine with a call to crSTART();
 96 |      crSTART( xHandle );
 97 | 
 98 |      for( ;; )
 99 |      {
100 |          // This co-routine just delays for a fixed period, then toggles
101 |          // an LED.  Two co-routines are created using this function, so
102 |          // the uxIndex parameter is used to tell the co-routine which
103 |          // LED to flash and how int32_t to delay.  This assumes xQueue has
104 |          // already been created.
105 |          vParTestToggleLED( cLedToFlash[ uxIndex ] );
106 |          crDELAY( xHandle, uxFlashRates[ uxIndex ] );
107 |      }
108 | 
109 |      // Must end every co-routine with a call to crEND();
110 |      crEND();
111 |  }
112 | 
113 |  // Function that creates two co-routines.
114 |  void vOtherFunction( void )
115 |  {
116 |  uint8_t ucParameterToPass;
117 |  TaskHandle_t xHandle;
118 | 
119 |      // Create two co-routines at priority 0.  The first is given index 0
120 |      // so (from the code above) toggles LED 5 every 200 ticks.  The second
121 |      // is given index 1 so toggles LED 6 every 400 ticks.
122 |      for( uxIndex = 0; uxIndex < 2; uxIndex++ )
123 |      {
124 |          xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
125 |      }
126 |  }
127 |    
128 | * \defgroup xCoRoutineCreate xCoRoutineCreate 129 | * \ingroup Tasks 130 | */ 131 | BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ); 132 | 133 | 134 | /** 135 | * croutine. h 136 | *
137 |  void vCoRoutineSchedule( void );
138 | * 139 | * Run a co-routine. 140 | * 141 | * vCoRoutineSchedule() executes the highest priority co-routine that is able 142 | * to run. The co-routine will execute until it either blocks, yields or is 143 | * preempted by a task. Co-routines execute cooperatively so one 144 | * co-routine cannot be preempted by another, but can be preempted by a task. 145 | * 146 | * If an application comprises of both tasks and co-routines then 147 | * vCoRoutineSchedule should be called from the idle task (in an idle task 148 | * hook). 149 | * 150 | * Example usage: 151 |
152 |  // This idle task hook will schedule a co-routine each time it is called.
153 |  // The rest of the idle task will execute between co-routine calls.
154 |  void vApplicationIdleHook( void )
155 |  {
156 | 	vCoRoutineSchedule();
157 |  }
158 | 
159 |  // Alternatively, if you do not require any other part of the idle task to
160 |  // execute, the idle task hook can call vCoRoutineScheduler() within an
161 |  // infinite loop.
162 |  void vApplicationIdleHook( void )
163 |  {
164 |     for( ;; )
165 |     {
166 |         vCoRoutineSchedule();
167 |     }
168 |  }
169 |  
170 | * \defgroup vCoRoutineSchedule vCoRoutineSchedule 171 | * \ingroup Tasks 172 | */ 173 | void vCoRoutineSchedule( void ); 174 | 175 | /** 176 | * croutine. h 177 | *
178 |  crSTART( CoRoutineHandle_t xHandle );
179 | * 180 | * This macro MUST always be called at the start of a co-routine function. 181 | * 182 | * Example usage: 183 |
184 |  // Co-routine to be created.
185 |  void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
186 |  {
187 |  // Variables in co-routines must be declared static if they must maintain value across a blocking call.
188 |  static int32_t ulAVariable;
189 | 
190 |      // Must start every co-routine with a call to crSTART();
191 |      crSTART( xHandle );
192 | 
193 |      for( ;; )
194 |      {
195 |           // Co-routine functionality goes here.
196 |      }
197 | 
198 |      // Must end every co-routine with a call to crEND();
199 |      crEND();
200 |  }
201 | * \defgroup crSTART crSTART 202 | * \ingroup Tasks 203 | */ 204 | #define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0: 205 | 206 | /** 207 | * croutine. h 208 | *
209 |  crEND();
210 | * 211 | * This macro MUST always be called at the end of a co-routine function. 212 | * 213 | * Example usage: 214 |
215 |  // Co-routine to be created.
216 |  void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
217 |  {
218 |  // Variables in co-routines must be declared static if they must maintain value across a blocking call.
219 |  static int32_t ulAVariable;
220 | 
221 |      // Must start every co-routine with a call to crSTART();
222 |      crSTART( xHandle );
223 | 
224 |      for( ;; )
225 |      {
226 |           // Co-routine functionality goes here.
227 |      }
228 | 
229 |      // Must end every co-routine with a call to crEND();
230 |      crEND();
231 |  }
232 | * \defgroup crSTART crSTART 233 | * \ingroup Tasks 234 | */ 235 | #define crEND() } 236 | 237 | /* 238 | * These macros are intended for internal use by the co-routine implementation 239 | * only. The macros should not be used directly by application writers. 240 | */ 241 | #define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): 242 | #define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): 243 | 244 | /** 245 | * croutine. h 246 | *
247 |  crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );
248 | * 249 | * Delay a co-routine for a fixed period of time. 250 | * 251 | * crDELAY can only be called from the co-routine function itself - not 252 | * from within a function called by the co-routine function. This is because 253 | * co-routines do not maintain their own stack. 254 | * 255 | * @param xHandle The handle of the co-routine to delay. This is the xHandle 256 | * parameter of the co-routine function. 257 | * 258 | * @param xTickToDelay The number of ticks that the co-routine should delay 259 | * for. The actual amount of time this equates to is defined by 260 | * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS 261 | * can be used to convert ticks to milliseconds. 262 | * 263 | * Example usage: 264 |
265 |  // Co-routine to be created.
266 |  void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
267 |  {
268 |  // Variables in co-routines must be declared static if they must maintain value across a blocking call.
269 |  // This may not be necessary for const variables.
270 |  // We are to delay for 200ms.
271 |  static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
272 | 
273 |      // Must start every co-routine with a call to crSTART();
274 |      crSTART( xHandle );
275 | 
276 |      for( ;; )
277 |      {
278 |         // Delay for 200ms.
279 |         crDELAY( xHandle, xDelayTime );
280 | 
281 |         // Do something here.
282 |      }
283 | 
284 |      // Must end every co-routine with a call to crEND();
285 |      crEND();
286 |  }
287 | * \defgroup crDELAY crDELAY 288 | * \ingroup Tasks 289 | */ 290 | #define crDELAY( xHandle, xTicksToDelay ) \ 291 | if( ( xTicksToDelay ) > 0 ) \ 292 | { \ 293 | vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ 294 | } \ 295 | crSET_STATE0( ( xHandle ) ); 296 | 297 | /** 298 | *
299 |  crQUEUE_SEND(
300 |                   CoRoutineHandle_t xHandle,
301 |                   QueueHandle_t pxQueue,
302 |                   void *pvItemToQueue,
303 |                   TickType_t xTicksToWait,
304 |                   BaseType_t *pxResult
305 |              )
306 | * 307 | * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine 308 | * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. 309 | * 310 | * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas 311 | * xQueueSend() and xQueueReceive() can only be used from tasks. 312 | * 313 | * crQUEUE_SEND can only be called from the co-routine function itself - not 314 | * from within a function called by the co-routine function. This is because 315 | * co-routines do not maintain their own stack. 316 | * 317 | * See the co-routine section of the WEB documentation for information on 318 | * passing data between tasks and co-routines and between ISR's and 319 | * co-routines. 320 | * 321 | * @param xHandle The handle of the calling co-routine. This is the xHandle 322 | * parameter of the co-routine function. 323 | * 324 | * @param pxQueue The handle of the queue on which the data will be posted. 325 | * The handle is obtained as the return value when the queue is created using 326 | * the xQueueCreate() API function. 327 | * 328 | * @param pvItemToQueue A pointer to the data being posted onto the queue. 329 | * The number of bytes of each queued item is specified when the queue is 330 | * created. This number of bytes is copied from pvItemToQueue into the queue 331 | * itself. 332 | * 333 | * @param xTickToDelay The number of ticks that the co-routine should block 334 | * to wait for space to become available on the queue, should space not be 335 | * available immediately. The actual amount of time this equates to is defined 336 | * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant 337 | * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example 338 | * below). 339 | * 340 | * @param pxResult The variable pointed to by pxResult will be set to pdPASS if 341 | * data was successfully posted onto the queue, otherwise it will be set to an 342 | * error defined within ProjDefs.h. 343 | * 344 | * Example usage: 345 |
346 |  // Co-routine function that blocks for a fixed period then posts a number onto
347 |  // a queue.
348 |  static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
349 |  {
350 |  // Variables in co-routines must be declared static if they must maintain value across a blocking call.
351 |  static BaseType_t xNumberToPost = 0;
352 |  static BaseType_t xResult;
353 | 
354 |     // Co-routines must begin with a call to crSTART().
355 |     crSTART( xHandle );
356 | 
357 |     for( ;; )
358 |     {
359 |         // This assumes the queue has already been created.
360 |         crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
361 | 
362 |         if( xResult != pdPASS )
363 |         {
364 |             // The message was not posted!
365 |         }
366 | 
367 |         // Increment the number to be posted onto the queue.
368 |         xNumberToPost++;
369 | 
370 |         // Delay for 100 ticks.
371 |         crDELAY( xHandle, 100 );
372 |     }
373 | 
374 |     // Co-routines must end with a call to crEND().
375 |     crEND();
376 |  }
377 | * \defgroup crQUEUE_SEND crQUEUE_SEND 378 | * \ingroup Tasks 379 | */ 380 | #define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ 381 | { \ 382 | *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \ 383 | if( *( pxResult ) == errQUEUE_BLOCKED ) \ 384 | { \ 385 | crSET_STATE0( ( xHandle ) ); \ 386 | *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ 387 | } \ 388 | if( *pxResult == errQUEUE_YIELD ) \ 389 | { \ 390 | crSET_STATE1( ( xHandle ) ); \ 391 | *pxResult = pdPASS; \ 392 | } \ 393 | } 394 | 395 | /** 396 | * croutine. h 397 | *
398 |   crQUEUE_RECEIVE(
399 |                      CoRoutineHandle_t xHandle,
400 |                      QueueHandle_t pxQueue,
401 |                      void *pvBuffer,
402 |                      TickType_t xTicksToWait,
403 |                      BaseType_t *pxResult
404 |                  )
405 | * 406 | * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine 407 | * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. 408 | * 409 | * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas 410 | * xQueueSend() and xQueueReceive() can only be used from tasks. 411 | * 412 | * crQUEUE_RECEIVE can only be called from the co-routine function itself - not 413 | * from within a function called by the co-routine function. This is because 414 | * co-routines do not maintain their own stack. 415 | * 416 | * See the co-routine section of the WEB documentation for information on 417 | * passing data between tasks and co-routines and between ISR's and 418 | * co-routines. 419 | * 420 | * @param xHandle The handle of the calling co-routine. This is the xHandle 421 | * parameter of the co-routine function. 422 | * 423 | * @param pxQueue The handle of the queue from which the data will be received. 424 | * The handle is obtained as the return value when the queue is created using 425 | * the xQueueCreate() API function. 426 | * 427 | * @param pvBuffer The buffer into which the received item is to be copied. 428 | * The number of bytes of each queued item is specified when the queue is 429 | * created. This number of bytes is copied into pvBuffer. 430 | * 431 | * @param xTickToDelay The number of ticks that the co-routine should block 432 | * to wait for data to become available from the queue, should data not be 433 | * available immediately. The actual amount of time this equates to is defined 434 | * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant 435 | * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the 436 | * crQUEUE_SEND example). 437 | * 438 | * @param pxResult The variable pointed to by pxResult will be set to pdPASS if 439 | * data was successfully retrieved from the queue, otherwise it will be set to 440 | * an error code as defined within ProjDefs.h. 441 | * 442 | * Example usage: 443 |
444 |  // A co-routine receives the number of an LED to flash from a queue.  It
445 |  // blocks on the queue until the number is received.
446 |  static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
447 |  {
448 |  // Variables in co-routines must be declared static if they must maintain value across a blocking call.
449 |  static BaseType_t xResult;
450 |  static UBaseType_t uxLEDToFlash;
451 | 
452 |     // All co-routines must start with a call to crSTART().
453 |     crSTART( xHandle );
454 | 
455 |     for( ;; )
456 |     {
457 |         // Wait for data to become available on the queue.
458 |         crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
459 | 
460 |         if( xResult == pdPASS )
461 |         {
462 |             // We received the LED to flash - flash it!
463 |             vParTestToggleLED( uxLEDToFlash );
464 |         }
465 |     }
466 | 
467 |     crEND();
468 |  }
469 | * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE 470 | * \ingroup Tasks 471 | */ 472 | #define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ 473 | { \ 474 | *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \ 475 | if( *( pxResult ) == errQUEUE_BLOCKED ) \ 476 | { \ 477 | crSET_STATE0( ( xHandle ) ); \ 478 | *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \ 479 | } \ 480 | if( *( pxResult ) == errQUEUE_YIELD ) \ 481 | { \ 482 | crSET_STATE1( ( xHandle ) ); \ 483 | *( pxResult ) = pdPASS; \ 484 | } \ 485 | } 486 | 487 | /** 488 | * croutine. h 489 | *
490 |   crQUEUE_SEND_FROM_ISR(
491 |                             QueueHandle_t pxQueue,
492 |                             void *pvItemToQueue,
493 |                             BaseType_t xCoRoutinePreviouslyWoken
494 |                        )
495 | * 496 | * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the 497 | * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() 498 | * functions used by tasks. 499 | * 500 | * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to 501 | * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and 502 | * xQueueReceiveFromISR() can only be used to pass data between a task and and 503 | * ISR. 504 | * 505 | * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue 506 | * that is being used from within a co-routine. 507 | * 508 | * See the co-routine section of the WEB documentation for information on 509 | * passing data between tasks and co-routines and between ISR's and 510 | * co-routines. 511 | * 512 | * @param xQueue The handle to the queue on which the item is to be posted. 513 | * 514 | * @param pvItemToQueue A pointer to the item that is to be placed on the 515 | * queue. The size of the items the queue will hold was defined when the 516 | * queue was created, so this many bytes will be copied from pvItemToQueue 517 | * into the queue storage area. 518 | * 519 | * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto 520 | * the same queue multiple times from a single interrupt. The first call 521 | * should always pass in pdFALSE. Subsequent calls should pass in 522 | * the value returned from the previous call. 523 | * 524 | * @return pdTRUE if a co-routine was woken by posting onto the queue. This is 525 | * used by the ISR to determine if a context switch may be required following 526 | * the ISR. 527 | * 528 | * Example usage: 529 |
530 |  // A co-routine that blocks on a queue waiting for characters to be received.
531 |  static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
532 |  {
533 |  char cRxedChar;
534 |  BaseType_t xResult;
535 | 
536 |      // All co-routines must start with a call to crSTART().
537 |      crSTART( xHandle );
538 | 
539 |      for( ;; )
540 |      {
541 |          // Wait for data to become available on the queue.  This assumes the
542 |          // queue xCommsRxQueue has already been created!
543 |          crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
544 | 
545 |          // Was a character received?
546 |          if( xResult == pdPASS )
547 |          {
548 |              // Process the character here.
549 |          }
550 |      }
551 | 
552 |      // All co-routines must end with a call to crEND().
553 |      crEND();
554 |  }
555 | 
556 |  // An ISR that uses a queue to send characters received on a serial port to
557 |  // a co-routine.
558 |  void vUART_ISR( void )
559 |  {
560 |  char cRxedChar;
561 |  BaseType_t xCRWokenByPost = pdFALSE;
562 | 
563 |      // We loop around reading characters until there are none left in the UART.
564 |      while( UART_RX_REG_NOT_EMPTY() )
565 |      {
566 |          // Obtain the character from the UART.
567 |          cRxedChar = UART_RX_REG;
568 | 
569 |          // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
570 |          // the first time around the loop.  If the post causes a co-routine
571 |          // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
572 |          // In this manner we can ensure that if more than one co-routine is
573 |          // blocked on the queue only one is woken by this ISR no matter how
574 |          // many characters are posted to the queue.
575 |          xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
576 |      }
577 |  }
578 | * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR 579 | * \ingroup Tasks 580 | */ 581 | #define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) 582 | 583 | 584 | /** 585 | * croutine. h 586 | *
587 |   crQUEUE_SEND_FROM_ISR(
588 |                             QueueHandle_t pxQueue,
589 |                             void *pvBuffer,
590 |                             BaseType_t * pxCoRoutineWoken
591 |                        )
592 | * 593 | * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the 594 | * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() 595 | * functions used by tasks. 596 | * 597 | * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to 598 | * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and 599 | * xQueueReceiveFromISR() can only be used to pass data between a task and and 600 | * ISR. 601 | * 602 | * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data 603 | * from a queue that is being used from within a co-routine (a co-routine 604 | * posted to the queue). 605 | * 606 | * See the co-routine section of the WEB documentation for information on 607 | * passing data between tasks and co-routines and between ISR's and 608 | * co-routines. 609 | * 610 | * @param xQueue The handle to the queue on which the item is to be posted. 611 | * 612 | * @param pvBuffer A pointer to a buffer into which the received item will be 613 | * placed. The size of the items the queue will hold was defined when the 614 | * queue was created, so this many bytes will be copied from the queue into 615 | * pvBuffer. 616 | * 617 | * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become 618 | * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a 619 | * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise 620 | * *pxCoRoutineWoken will remain unchanged. 621 | * 622 | * @return pdTRUE an item was successfully received from the queue, otherwise 623 | * pdFALSE. 624 | * 625 | * Example usage: 626 |
627 |  // A co-routine that posts a character to a queue then blocks for a fixed
628 |  // period.  The character is incremented each time.
629 |  static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
630 |  {
631 |  // cChar holds its value while this co-routine is blocked and must therefore
632 |  // be declared static.
633 |  static char cCharToTx = 'a';
634 |  BaseType_t xResult;
635 | 
636 |      // All co-routines must start with a call to crSTART().
637 |      crSTART( xHandle );
638 | 
639 |      for( ;; )
640 |      {
641 |          // Send the next character to the queue.
642 |          crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
643 | 
644 |          if( xResult == pdPASS )
645 |          {
646 |              // The character was successfully posted to the queue.
647 |          }
648 | 		 else
649 | 		 {
650 | 			// Could not post the character to the queue.
651 | 		 }
652 | 
653 |          // Enable the UART Tx interrupt to cause an interrupt in this
654 | 		 // hypothetical UART.  The interrupt will obtain the character
655 | 		 // from the queue and send it.
656 | 		 ENABLE_RX_INTERRUPT();
657 | 
658 | 		 // Increment to the next character then block for a fixed period.
659 | 		 // cCharToTx will maintain its value across the delay as it is
660 | 		 // declared static.
661 | 		 cCharToTx++;
662 | 		 if( cCharToTx > 'x' )
663 | 		 {
664 | 			cCharToTx = 'a';
665 | 		 }
666 | 		 crDELAY( 100 );
667 |      }
668 | 
669 |      // All co-routines must end with a call to crEND().
670 |      crEND();
671 |  }
672 | 
673 |  // An ISR that uses a queue to receive characters to send on a UART.
674 |  void vUART_ISR( void )
675 |  {
676 |  char cCharToTx;
677 |  BaseType_t xCRWokenByPost = pdFALSE;
678 | 
679 |      while( UART_TX_REG_EMPTY() )
680 |      {
681 |          // Are there any characters in the queue waiting to be sent?
682 | 		 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
683 | 		 // is woken by the post - ensuring that only a single co-routine is
684 | 		 // woken no matter how many times we go around this loop.
685 |          if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
686 | 		 {
687 | 			 SEND_CHARACTER( cCharToTx );
688 | 		 }
689 |      }
690 |  }
691 | * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR 692 | * \ingroup Tasks 693 | */ 694 | #define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) 695 | 696 | /* 697 | * This function is intended for internal use by the co-routine macros only. 698 | * The macro nature of the co-routine implementation requires that the 699 | * prototype appears here. The function should not be used by application 700 | * writers. 701 | * 702 | * Removes the current co-routine from its ready list and places it in the 703 | * appropriate delayed list. 704 | */ 705 | void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ); 706 | 707 | /* 708 | * This function is intended for internal use by the queue implementation only. 709 | * The function should not be used by application writers. 710 | * 711 | * Removes the highest priority co-routine from the event list and places it in 712 | * the pending ready list. 713 | */ 714 | BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ); 715 | 716 | #ifdef __cplusplus 717 | } 718 | #endif 719 | 720 | #endif /* CO_ROUTINE_H */ 721 | -------------------------------------------------------------------------------- /src/deprecated_definitions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.0 3 | * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef DEPRECATED_DEFINITIONS_H 29 | #define DEPRECATED_DEFINITIONS_H 30 | 31 | 32 | /* Each FreeRTOS port has a unique portmacro.h header file. Originally a 33 | pre-processor definition was used to ensure the pre-processor found the correct 34 | portmacro.h file for the port being used. That scheme was deprecated in favour 35 | of setting the compiler's include path such that it found the correct 36 | portmacro.h file - removing the need for the constant and allowing the 37 | portmacro.h file to be located anywhere in relation to the port being used. The 38 | definitions below remain in the code for backward compatibility only. New 39 | projects should not use them. */ 40 | 41 | #ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT 42 | #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" 43 | typedef void ( __interrupt __far *pxISR )(); 44 | #endif 45 | 46 | #ifdef OPEN_WATCOM_FLASH_LITE_186_PORT 47 | #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" 48 | typedef void ( __interrupt __far *pxISR )(); 49 | #endif 50 | 51 | #ifdef GCC_MEGA_AVR 52 | #include "../portable/GCC/ATMega323/portmacro.h" 53 | #endif 54 | 55 | #ifdef IAR_MEGA_AVR 56 | #include "../portable/IAR/ATMega323/portmacro.h" 57 | #endif 58 | 59 | #ifdef MPLAB_PIC24_PORT 60 | #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" 61 | #endif 62 | 63 | #ifdef MPLAB_DSPIC_PORT 64 | #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" 65 | #endif 66 | 67 | #ifdef MPLAB_PIC18F_PORT 68 | #include "../../Source/portable/MPLAB/PIC18F/portmacro.h" 69 | #endif 70 | 71 | #ifdef MPLAB_PIC32MX_PORT 72 | #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" 73 | #endif 74 | 75 | #ifdef _FEDPICC 76 | #include "libFreeRTOS/Include/portmacro.h" 77 | #endif 78 | 79 | #ifdef SDCC_CYGNAL 80 | #include "../../Source/portable/SDCC/Cygnal/portmacro.h" 81 | #endif 82 | 83 | #ifdef GCC_ARM7 84 | #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" 85 | #endif 86 | 87 | #ifdef GCC_ARM7_ECLIPSE 88 | #include "portmacro.h" 89 | #endif 90 | 91 | #ifdef ROWLEY_LPC23xx 92 | #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" 93 | #endif 94 | 95 | #ifdef IAR_MSP430 96 | #include "..\..\Source\portable\IAR\MSP430\portmacro.h" 97 | #endif 98 | 99 | #ifdef GCC_MSP430 100 | #include "../../Source/portable/GCC/MSP430F449/portmacro.h" 101 | #endif 102 | 103 | #ifdef ROWLEY_MSP430 104 | #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" 105 | #endif 106 | 107 | #ifdef ARM7_LPC21xx_KEIL_RVDS 108 | #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" 109 | #endif 110 | 111 | #ifdef SAM7_GCC 112 | #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" 113 | #endif 114 | 115 | #ifdef SAM7_IAR 116 | #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" 117 | #endif 118 | 119 | #ifdef SAM9XE_IAR 120 | #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" 121 | #endif 122 | 123 | #ifdef LPC2000_IAR 124 | #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" 125 | #endif 126 | 127 | #ifdef STR71X_IAR 128 | #include "..\..\Source\portable\IAR\STR71x\portmacro.h" 129 | #endif 130 | 131 | #ifdef STR75X_IAR 132 | #include "..\..\Source\portable\IAR\STR75x\portmacro.h" 133 | #endif 134 | 135 | #ifdef STR75X_GCC 136 | #include "..\..\Source\portable\GCC\STR75x\portmacro.h" 137 | #endif 138 | 139 | #ifdef STR91X_IAR 140 | #include "..\..\Source\portable\IAR\STR91x\portmacro.h" 141 | #endif 142 | 143 | #ifdef GCC_H8S 144 | #include "../../Source/portable/GCC/H8S2329/portmacro.h" 145 | #endif 146 | 147 | #ifdef GCC_AT91FR40008 148 | #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" 149 | #endif 150 | 151 | #ifdef RVDS_ARMCM3_LM3S102 152 | #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" 153 | #endif 154 | 155 | #ifdef GCC_ARMCM3_LM3S102 156 | #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" 157 | #endif 158 | 159 | #ifdef GCC_ARMCM3 160 | #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" 161 | #endif 162 | 163 | #ifdef IAR_ARM_CM3 164 | #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" 165 | #endif 166 | 167 | #ifdef IAR_ARMCM3_LM 168 | #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" 169 | #endif 170 | 171 | #ifdef HCS12_CODE_WARRIOR 172 | #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" 173 | #endif 174 | 175 | #ifdef MICROBLAZE_GCC 176 | #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" 177 | #endif 178 | 179 | #ifdef TERN_EE 180 | #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" 181 | #endif 182 | 183 | #ifdef GCC_HCS12 184 | #include "../../Source/portable/GCC/HCS12/portmacro.h" 185 | #endif 186 | 187 | #ifdef GCC_MCF5235 188 | #include "../../Source/portable/GCC/MCF5235/portmacro.h" 189 | #endif 190 | 191 | #ifdef COLDFIRE_V2_GCC 192 | #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" 193 | #endif 194 | 195 | #ifdef COLDFIRE_V2_CODEWARRIOR 196 | #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" 197 | #endif 198 | 199 | #ifdef GCC_PPC405 200 | #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" 201 | #endif 202 | 203 | #ifdef GCC_PPC440 204 | #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" 205 | #endif 206 | 207 | #ifdef _16FX_SOFTUNE 208 | #include "..\..\Source\portable\Softune\MB96340\portmacro.h" 209 | #endif 210 | 211 | #ifdef BCC_INDUSTRIAL_PC_PORT 212 | /* A short file name has to be used in place of the normal 213 | FreeRTOSConfig.h when using the Borland compiler. */ 214 | #include "frconfig.h" 215 | #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" 216 | typedef void ( __interrupt __far *pxISR )(); 217 | #endif 218 | 219 | #ifdef BCC_FLASH_LITE_186_PORT 220 | /* A short file name has to be used in place of the normal 221 | FreeRTOSConfig.h when using the Borland compiler. */ 222 | #include "frconfig.h" 223 | #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" 224 | typedef void ( __interrupt __far *pxISR )(); 225 | #endif 226 | 227 | #ifdef __GNUC__ 228 | #ifdef __AVR32_AVR32A__ 229 | #include "portmacro.h" 230 | #endif 231 | #endif 232 | 233 | #ifdef __ICCAVR32__ 234 | #ifdef __CORE__ 235 | #if __CORE__ == __AVR32A__ 236 | #include "portmacro.h" 237 | #endif 238 | #endif 239 | #endif 240 | 241 | #ifdef __91467D 242 | #include "portmacro.h" 243 | #endif 244 | 245 | #ifdef __96340 246 | #include "portmacro.h" 247 | #endif 248 | 249 | 250 | #ifdef __IAR_V850ES_Fx3__ 251 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 252 | #endif 253 | 254 | #ifdef __IAR_V850ES_Jx3__ 255 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 256 | #endif 257 | 258 | #ifdef __IAR_V850ES_Jx3_L__ 259 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 260 | #endif 261 | 262 | #ifdef __IAR_V850ES_Jx2__ 263 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 264 | #endif 265 | 266 | #ifdef __IAR_V850ES_Hx2__ 267 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 268 | #endif 269 | 270 | #ifdef __IAR_78K0R_Kx3__ 271 | #include "../../Source/portable/IAR/78K0R/portmacro.h" 272 | #endif 273 | 274 | #ifdef __IAR_78K0R_Kx3L__ 275 | #include "../../Source/portable/IAR/78K0R/portmacro.h" 276 | #endif 277 | 278 | #endif /* DEPRECATED_DEFINITIONS_H */ 279 | 280 | -------------------------------------------------------------------------------- /src/event_groups.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.0 3 | * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /* Standard includes. */ 29 | #include 30 | 31 | /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 32 | all the API functions to use the MPU wrappers. That should only be done when 33 | task.h is included from an application file. */ 34 | #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 35 | 36 | /* FreeRTOS includes. */ 37 | #include "FreeRTOS.h" 38 | #include "task.h" 39 | #include "timers.h" 40 | #include "event_groups.h" 41 | 42 | /* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified 43 | because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined 44 | for the header files above, but not in this file, in order to generate the 45 | correct privileged Vs unprivileged linkage and placement. */ 46 | #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */ 47 | 48 | /* The following bit fields convey control information in a task's event list 49 | item value. It is important they don't clash with the 50 | taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */ 51 | #if configUSE_16_BIT_TICKS == 1 52 | #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U 53 | #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U 54 | #define eventWAIT_FOR_ALL_BITS 0x0400U 55 | #define eventEVENT_BITS_CONTROL_BYTES 0xff00U 56 | #else 57 | #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL 58 | #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL 59 | #define eventWAIT_FOR_ALL_BITS 0x04000000UL 60 | #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL 61 | #endif 62 | 63 | typedef struct EventGroupDef_t 64 | { 65 | EventBits_t uxEventBits; 66 | List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ 67 | 68 | #if( configUSE_TRACE_FACILITY == 1 ) 69 | UBaseType_t uxEventGroupNumber; 70 | #endif 71 | 72 | #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) 73 | uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ 74 | #endif 75 | } EventGroup_t; 76 | 77 | /*-----------------------------------------------------------*/ 78 | 79 | /* 80 | * Test the bits set in uxCurrentEventBits to see if the wait condition is met. 81 | * The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is 82 | * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor 83 | * are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the 84 | * wait condition is met if any of the bits set in uxBitsToWait for are also set 85 | * in uxCurrentEventBits. 86 | */ 87 | static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION; 88 | 89 | /*-----------------------------------------------------------*/ 90 | 91 | #if( configSUPPORT_STATIC_ALLOCATION == 1 ) 92 | 93 | EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) 94 | { 95 | EventGroup_t *pxEventBits; 96 | 97 | /* A StaticEventGroup_t object must be provided. */ 98 | configASSERT( pxEventGroupBuffer ); 99 | 100 | #if( configASSERT_DEFINED == 1 ) 101 | { 102 | /* Sanity check that the size of the structure used to declare a 103 | variable of type StaticEventGroup_t equals the size of the real 104 | event group structure. */ 105 | volatile size_t xSize = sizeof( StaticEventGroup_t ); 106 | configASSERT( xSize == sizeof( EventGroup_t ) ); 107 | } /*lint !e529 xSize is referenced if configASSERT() is defined. */ 108 | #endif /* configASSERT_DEFINED */ 109 | 110 | /* The user has provided a statically allocated event group - use it. */ 111 | pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 !e9087 EventGroup_t and StaticEventGroup_t are deliberately aliased for data hiding purposes and guaranteed to have the same size and alignment requirement - checked by configASSERT(). */ 112 | 113 | if( pxEventBits != NULL ) 114 | { 115 | pxEventBits->uxEventBits = 0; 116 | vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); 117 | 118 | #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) 119 | { 120 | /* Both static and dynamic allocation can be used, so note that 121 | this event group was created statically in case the event group 122 | is later deleted. */ 123 | pxEventBits->ucStaticallyAllocated = pdTRUE; 124 | } 125 | #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ 126 | 127 | traceEVENT_GROUP_CREATE( pxEventBits ); 128 | } 129 | else 130 | { 131 | /* xEventGroupCreateStatic should only ever be called with 132 | pxEventGroupBuffer pointing to a pre-allocated (compile time 133 | allocated) StaticEventGroup_t variable. */ 134 | traceEVENT_GROUP_CREATE_FAILED(); 135 | } 136 | 137 | return pxEventBits; 138 | } 139 | 140 | #endif /* configSUPPORT_STATIC_ALLOCATION */ 141 | /*-----------------------------------------------------------*/ 142 | 143 | #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) 144 | 145 | EventGroupHandle_t xEventGroupCreate( void ) 146 | { 147 | EventGroup_t *pxEventBits; 148 | 149 | /* Allocate the event group. Justification for MISRA deviation as 150 | follows: pvPortMalloc() always ensures returned memory blocks are 151 | aligned per the requirements of the MCU stack. In this case 152 | pvPortMalloc() must return a pointer that is guaranteed to meet the 153 | alignment requirements of the EventGroup_t structure - which (if you 154 | follow it through) is the alignment requirements of the TickType_t type 155 | (EventBits_t being of TickType_t itself). Therefore, whenever the 156 | stack alignment requirements are greater than or equal to the 157 | TickType_t alignment requirements the cast is safe. In other cases, 158 | where the natural word size of the architecture is less than 159 | sizeof( TickType_t ), the TickType_t variables will be accessed in two 160 | or more reads operations, and the alignment requirements is only that 161 | of each individual read. */ 162 | pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */ 163 | 164 | if( pxEventBits != NULL ) 165 | { 166 | pxEventBits->uxEventBits = 0; 167 | vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); 168 | 169 | #if( configSUPPORT_STATIC_ALLOCATION == 1 ) 170 | { 171 | /* Both static and dynamic allocation can be used, so note this 172 | event group was allocated statically in case the event group is 173 | later deleted. */ 174 | pxEventBits->ucStaticallyAllocated = pdFALSE; 175 | } 176 | #endif /* configSUPPORT_STATIC_ALLOCATION */ 177 | 178 | traceEVENT_GROUP_CREATE( pxEventBits ); 179 | } 180 | else 181 | { 182 | traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */ 183 | } 184 | 185 | return pxEventBits; 186 | } 187 | 188 | #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ 189 | /*-----------------------------------------------------------*/ 190 | 191 | EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) 192 | { 193 | EventBits_t uxOriginalBitValue, uxReturn; 194 | EventGroup_t *pxEventBits = xEventGroup; 195 | BaseType_t xAlreadyYielded; 196 | BaseType_t xTimeoutOccurred = pdFALSE; 197 | 198 | configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); 199 | configASSERT( uxBitsToWaitFor != 0 ); 200 | #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) 201 | { 202 | configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); 203 | } 204 | #endif 205 | 206 | vTaskSuspendAll(); 207 | { 208 | uxOriginalBitValue = pxEventBits->uxEventBits; 209 | 210 | ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet ); 211 | 212 | if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor ) 213 | { 214 | /* All the rendezvous bits are now set - no need to block. */ 215 | uxReturn = ( uxOriginalBitValue | uxBitsToSet ); 216 | 217 | /* Rendezvous always clear the bits. They will have been cleared 218 | already unless this is the only task in the rendezvous. */ 219 | pxEventBits->uxEventBits &= ~uxBitsToWaitFor; 220 | 221 | xTicksToWait = 0; 222 | } 223 | else 224 | { 225 | if( xTicksToWait != ( TickType_t ) 0 ) 226 | { 227 | traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); 228 | 229 | /* Store the bits that the calling task is waiting for in the 230 | task's event list item so the kernel knows when a match is 231 | found. Then enter the blocked state. */ 232 | vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); 233 | 234 | /* This assignment is obsolete as uxReturn will get set after 235 | the task unblocks, but some compilers mistakenly generate a 236 | warning about uxReturn being returned without being set if the 237 | assignment is omitted. */ 238 | uxReturn = 0; 239 | } 240 | else 241 | { 242 | /* The rendezvous bits were not set, but no block time was 243 | specified - just return the current event bit value. */ 244 | uxReturn = pxEventBits->uxEventBits; 245 | xTimeoutOccurred = pdTRUE; 246 | } 247 | } 248 | } 249 | xAlreadyYielded = xTaskResumeAll(); 250 | 251 | if( xTicksToWait != ( TickType_t ) 0 ) 252 | { 253 | if( xAlreadyYielded == pdFALSE ) 254 | { 255 | portYIELD_WITHIN_API(); 256 | } 257 | else 258 | { 259 | mtCOVERAGE_TEST_MARKER(); 260 | } 261 | 262 | /* The task blocked to wait for its required bits to be set - at this 263 | point either the required bits were set or the block time expired. If 264 | the required bits were set they will have been stored in the task's 265 | event list item, and they should now be retrieved then cleared. */ 266 | uxReturn = uxTaskResetEventItemValue(); 267 | 268 | if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) 269 | { 270 | /* The task timed out, just return the current event bit value. */ 271 | taskENTER_CRITICAL(); 272 | { 273 | uxReturn = pxEventBits->uxEventBits; 274 | 275 | /* Although the task got here because it timed out before the 276 | bits it was waiting for were set, it is possible that since it 277 | unblocked another task has set the bits. If this is the case 278 | then it needs to clear the bits before exiting. */ 279 | if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) 280 | { 281 | pxEventBits->uxEventBits &= ~uxBitsToWaitFor; 282 | } 283 | else 284 | { 285 | mtCOVERAGE_TEST_MARKER(); 286 | } 287 | } 288 | taskEXIT_CRITICAL(); 289 | 290 | xTimeoutOccurred = pdTRUE; 291 | } 292 | else 293 | { 294 | /* The task unblocked because the bits were set. */ 295 | } 296 | 297 | /* Control bits might be set as the task had blocked should not be 298 | returned. */ 299 | uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; 300 | } 301 | 302 | traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); 303 | 304 | /* Prevent compiler warnings when trace macros are not used. */ 305 | ( void ) xTimeoutOccurred; 306 | 307 | return uxReturn; 308 | } 309 | /*-----------------------------------------------------------*/ 310 | 311 | EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) 312 | { 313 | EventGroup_t *pxEventBits = xEventGroup; 314 | EventBits_t uxReturn, uxControlBits = 0; 315 | BaseType_t xWaitConditionMet, xAlreadyYielded; 316 | BaseType_t xTimeoutOccurred = pdFALSE; 317 | 318 | /* Check the user is not attempting to wait on the bits used by the kernel 319 | itself, and that at least one bit is being requested. */ 320 | configASSERT( xEventGroup ); 321 | configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); 322 | configASSERT( uxBitsToWaitFor != 0 ); 323 | #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) 324 | { 325 | configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); 326 | } 327 | #endif 328 | 329 | vTaskSuspendAll(); 330 | { 331 | const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; 332 | 333 | /* Check to see if the wait condition is already met or not. */ 334 | xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits ); 335 | 336 | if( xWaitConditionMet != pdFALSE ) 337 | { 338 | /* The wait condition has already been met so there is no need to 339 | block. */ 340 | uxReturn = uxCurrentEventBits; 341 | xTicksToWait = ( TickType_t ) 0; 342 | 343 | /* Clear the wait bits if requested to do so. */ 344 | if( xClearOnExit != pdFALSE ) 345 | { 346 | pxEventBits->uxEventBits &= ~uxBitsToWaitFor; 347 | } 348 | else 349 | { 350 | mtCOVERAGE_TEST_MARKER(); 351 | } 352 | } 353 | else if( xTicksToWait == ( TickType_t ) 0 ) 354 | { 355 | /* The wait condition has not been met, but no block time was 356 | specified, so just return the current value. */ 357 | uxReturn = uxCurrentEventBits; 358 | xTimeoutOccurred = pdTRUE; 359 | } 360 | else 361 | { 362 | /* The task is going to block to wait for its required bits to be 363 | set. uxControlBits are used to remember the specified behaviour of 364 | this call to xEventGroupWaitBits() - for use when the event bits 365 | unblock the task. */ 366 | if( xClearOnExit != pdFALSE ) 367 | { 368 | uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; 369 | } 370 | else 371 | { 372 | mtCOVERAGE_TEST_MARKER(); 373 | } 374 | 375 | if( xWaitForAllBits != pdFALSE ) 376 | { 377 | uxControlBits |= eventWAIT_FOR_ALL_BITS; 378 | } 379 | else 380 | { 381 | mtCOVERAGE_TEST_MARKER(); 382 | } 383 | 384 | /* Store the bits that the calling task is waiting for in the 385 | task's event list item so the kernel knows when a match is 386 | found. Then enter the blocked state. */ 387 | vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); 388 | 389 | /* This is obsolete as it will get set after the task unblocks, but 390 | some compilers mistakenly generate a warning about the variable 391 | being returned without being set if it is not done. */ 392 | uxReturn = 0; 393 | 394 | traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); 395 | } 396 | } 397 | xAlreadyYielded = xTaskResumeAll(); 398 | 399 | if( xTicksToWait != ( TickType_t ) 0 ) 400 | { 401 | if( xAlreadyYielded == pdFALSE ) 402 | { 403 | portYIELD_WITHIN_API(); 404 | } 405 | else 406 | { 407 | mtCOVERAGE_TEST_MARKER(); 408 | } 409 | 410 | /* The task blocked to wait for its required bits to be set - at this 411 | point either the required bits were set or the block time expired. If 412 | the required bits were set they will have been stored in the task's 413 | event list item, and they should now be retrieved then cleared. */ 414 | uxReturn = uxTaskResetEventItemValue(); 415 | 416 | if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) 417 | { 418 | taskENTER_CRITICAL(); 419 | { 420 | /* The task timed out, just return the current event bit value. */ 421 | uxReturn = pxEventBits->uxEventBits; 422 | 423 | /* It is possible that the event bits were updated between this 424 | task leaving the Blocked state and running again. */ 425 | if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) 426 | { 427 | if( xClearOnExit != pdFALSE ) 428 | { 429 | pxEventBits->uxEventBits &= ~uxBitsToWaitFor; 430 | } 431 | else 432 | { 433 | mtCOVERAGE_TEST_MARKER(); 434 | } 435 | } 436 | else 437 | { 438 | mtCOVERAGE_TEST_MARKER(); 439 | } 440 | xTimeoutOccurred = pdTRUE; 441 | } 442 | taskEXIT_CRITICAL(); 443 | } 444 | else 445 | { 446 | /* The task unblocked because the bits were set. */ 447 | } 448 | 449 | /* The task blocked so control bits may have been set. */ 450 | uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; 451 | } 452 | traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); 453 | 454 | /* Prevent compiler warnings when trace macros are not used. */ 455 | ( void ) xTimeoutOccurred; 456 | 457 | return uxReturn; 458 | } 459 | /*-----------------------------------------------------------*/ 460 | 461 | EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) 462 | { 463 | EventGroup_t *pxEventBits = xEventGroup; 464 | EventBits_t uxReturn; 465 | 466 | /* Check the user is not attempting to clear the bits used by the kernel 467 | itself. */ 468 | configASSERT( xEventGroup ); 469 | configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); 470 | 471 | taskENTER_CRITICAL(); 472 | { 473 | traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); 474 | 475 | /* The value returned is the event group value prior to the bits being 476 | cleared. */ 477 | uxReturn = pxEventBits->uxEventBits; 478 | 479 | /* Clear the bits. */ 480 | pxEventBits->uxEventBits &= ~uxBitsToClear; 481 | } 482 | taskEXIT_CRITICAL(); 483 | 484 | return uxReturn; 485 | } 486 | /*-----------------------------------------------------------*/ 487 | 488 | #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) 489 | 490 | BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) 491 | { 492 | BaseType_t xReturn; 493 | 494 | traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); 495 | xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ 496 | 497 | return xReturn; 498 | } 499 | 500 | #endif 501 | /*-----------------------------------------------------------*/ 502 | 503 | EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) 504 | { 505 | UBaseType_t uxSavedInterruptStatus; 506 | EventGroup_t const * const pxEventBits = xEventGroup; 507 | EventBits_t uxReturn; 508 | 509 | uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); 510 | { 511 | uxReturn = pxEventBits->uxEventBits; 512 | } 513 | portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); 514 | 515 | return uxReturn; 516 | } /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */ 517 | /*-----------------------------------------------------------*/ 518 | 519 | EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) 520 | { 521 | ListItem_t *pxListItem, *pxNext; 522 | ListItem_t const *pxListEnd; 523 | List_t const * pxList; 524 | EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits; 525 | EventGroup_t *pxEventBits = xEventGroup; 526 | BaseType_t xMatchFound = pdFALSE; 527 | 528 | /* Check the user is not attempting to set the bits used by the kernel 529 | itself. */ 530 | configASSERT( xEventGroup ); 531 | configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); 532 | 533 | pxList = &( pxEventBits->xTasksWaitingForBits ); 534 | pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 535 | vTaskSuspendAll(); 536 | { 537 | traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); 538 | 539 | pxListItem = listGET_HEAD_ENTRY( pxList ); 540 | 541 | /* Set the bits. */ 542 | pxEventBits->uxEventBits |= uxBitsToSet; 543 | 544 | /* See if the new bit value should unblock any tasks. */ 545 | while( pxListItem != pxListEnd ) 546 | { 547 | pxNext = listGET_NEXT( pxListItem ); 548 | uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem ); 549 | xMatchFound = pdFALSE; 550 | 551 | /* Split the bits waited for from the control bits. */ 552 | uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES; 553 | uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES; 554 | 555 | if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 ) 556 | { 557 | /* Just looking for single bit being set. */ 558 | if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 ) 559 | { 560 | xMatchFound = pdTRUE; 561 | } 562 | else 563 | { 564 | mtCOVERAGE_TEST_MARKER(); 565 | } 566 | } 567 | else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor ) 568 | { 569 | /* All bits are set. */ 570 | xMatchFound = pdTRUE; 571 | } 572 | else 573 | { 574 | /* Need all bits to be set, but not all the bits were set. */ 575 | } 576 | 577 | if( xMatchFound != pdFALSE ) 578 | { 579 | /* The bits match. Should the bits be cleared on exit? */ 580 | if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 ) 581 | { 582 | uxBitsToClear |= uxBitsWaitedFor; 583 | } 584 | else 585 | { 586 | mtCOVERAGE_TEST_MARKER(); 587 | } 588 | 589 | /* Store the actual event flag value in the task's event list 590 | item before removing the task from the event list. The 591 | eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows 592 | that is was unblocked due to its required bits matching, rather 593 | than because it timed out. */ 594 | vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); 595 | } 596 | 597 | /* Move onto the next list item. Note pxListItem->pxNext is not 598 | used here as the list item may have been removed from the event list 599 | and inserted into the ready/pending reading list. */ 600 | pxListItem = pxNext; 601 | } 602 | 603 | /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT 604 | bit was set in the control word. */ 605 | pxEventBits->uxEventBits &= ~uxBitsToClear; 606 | } 607 | ( void ) xTaskResumeAll(); 608 | 609 | return pxEventBits->uxEventBits; 610 | } 611 | /*-----------------------------------------------------------*/ 612 | 613 | void vEventGroupDelete( EventGroupHandle_t xEventGroup ) 614 | { 615 | EventGroup_t *pxEventBits = xEventGroup; 616 | const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); 617 | 618 | vTaskSuspendAll(); 619 | { 620 | traceEVENT_GROUP_DELETE( xEventGroup ); 621 | 622 | while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) 623 | { 624 | /* Unblock the task, returning 0 as the event list is being deleted 625 | and cannot therefore have any bits set. */ 626 | configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); 627 | vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); 628 | } 629 | 630 | #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) 631 | { 632 | /* The event group can only have been allocated dynamically - free 633 | it again. */ 634 | vPortFree( pxEventBits ); 635 | } 636 | #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) 637 | { 638 | /* The event group could have been allocated statically or 639 | dynamically, so check before attempting to free the memory. */ 640 | if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) 641 | { 642 | vPortFree( pxEventBits ); 643 | } 644 | else 645 | { 646 | mtCOVERAGE_TEST_MARKER(); 647 | } 648 | } 649 | #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ 650 | } 651 | ( void ) xTaskResumeAll(); 652 | } 653 | /*-----------------------------------------------------------*/ 654 | 655 | /* For internal use only - execute a 'set bits' command that was pended from 656 | an interrupt. */ 657 | void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) 658 | { 659 | ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ 660 | } 661 | /*-----------------------------------------------------------*/ 662 | 663 | /* For internal use only - execute a 'clear bits' command that was pended from 664 | an interrupt. */ 665 | void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) 666 | { 667 | ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ 668 | } 669 | /*-----------------------------------------------------------*/ 670 | 671 | static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) 672 | { 673 | BaseType_t xWaitConditionMet = pdFALSE; 674 | 675 | if( xWaitForAllBits == pdFALSE ) 676 | { 677 | /* Task only has to wait for one bit within uxBitsToWaitFor to be 678 | set. Is one already set? */ 679 | if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) 680 | { 681 | xWaitConditionMet = pdTRUE; 682 | } 683 | else 684 | { 685 | mtCOVERAGE_TEST_MARKER(); 686 | } 687 | } 688 | else 689 | { 690 | /* Task has to wait for all the bits in uxBitsToWaitFor to be set. 691 | Are they set already? */ 692 | if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) 693 | { 694 | xWaitConditionMet = pdTRUE; 695 | } 696 | else 697 | { 698 | mtCOVERAGE_TEST_MARKER(); 699 | } 700 | } 701 | 702 | return xWaitConditionMet; 703 | } 704 | /*-----------------------------------------------------------*/ 705 | 706 | #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) 707 | 708 | BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) 709 | { 710 | BaseType_t xReturn; 711 | 712 | traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); 713 | xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ 714 | 715 | return xReturn; 716 | } 717 | 718 | #endif 719 | /*-----------------------------------------------------------*/ 720 | 721 | #if (configUSE_TRACE_FACILITY == 1) 722 | 723 | UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) 724 | { 725 | UBaseType_t xReturn; 726 | EventGroup_t const *pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ 727 | 728 | if( xEventGroup == NULL ) 729 | { 730 | xReturn = 0; 731 | } 732 | else 733 | { 734 | xReturn = pxEventBits->uxEventGroupNumber; 735 | } 736 | 737 | return xReturn; 738 | } 739 | 740 | #endif /* configUSE_TRACE_FACILITY */ 741 | /*-----------------------------------------------------------*/ 742 | 743 | #if ( configUSE_TRACE_FACILITY == 1 ) 744 | 745 | void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) 746 | { 747 | ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ 748 | } 749 | 750 | #endif /* configUSE_TRACE_FACILITY */ 751 | /*-----------------------------------------------------------*/ 752 | 753 | 754 | -------------------------------------------------------------------------------- /src/heap_3.c: -------------------------------------------------------------------------------- 1 | /* 2 | FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. 3 | All rights reserved 4 | 5 | VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 6 | 7 | This file is part of the FreeRTOS distribution. 8 | 9 | FreeRTOS is free software; you can redistribute it and/or modify it under 10 | the terms of the GNU General Public License (version 2) as published by the 11 | Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. 12 | 13 | *************************************************************************** 14 | >>! NOTE: The modification to the GPL is included to allow you to !<< 15 | >>! distribute a combined work that includes FreeRTOS without being !<< 16 | >>! obliged to provide the source code for proprietary components !<< 17 | >>! outside of the FreeRTOS kernel. !<< 18 | *************************************************************************** 19 | 20 | FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 22 | FOR A PARTICULAR PURPOSE. Full license text is available on the following 23 | link: http://www.freertos.org/a00114.html 24 | 25 | *************************************************************************** 26 | * * 27 | * FreeRTOS provides completely free yet professionally developed, * 28 | * robust, strictly quality controlled, supported, and cross * 29 | * platform software that is more than just the market leader, it * 30 | * is the industry's de facto standard. * 31 | * * 32 | * Help yourself get started quickly while simultaneously helping * 33 | * to support the FreeRTOS project by purchasing a FreeRTOS * 34 | * tutorial book, reference manual, or both: * 35 | * http://www.FreeRTOS.org/Documentation * 36 | * * 37 | *************************************************************************** 38 | 39 | http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 40 | the FAQ page "My application does not run, what could be wrong?". Have you 41 | defined configASSERT()? 42 | 43 | http://www.FreeRTOS.org/support - In return for receiving this top quality 44 | embedded software for free we request you assist our global community by 45 | participating in the support forum. 46 | 47 | http://www.FreeRTOS.org/training - Investing in training allows your team to 48 | be as productive as possible as early as possible. Now you can receive 49 | FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 50 | Ltd, and the world's leading authority on the world's leading RTOS. 51 | 52 | http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 53 | including FreeRTOS+Trace - an indispensable productivity tool, a DOS 54 | compatible FAT file system, and our tiny thread aware UDP/IP stack. 55 | 56 | http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 57 | Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 58 | 59 | http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 60 | Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 61 | licenses offer ticketed support, indemnification and commercial middleware. 62 | 63 | http://www.SafeRTOS.com - High Integrity Systems also provide a safety 64 | engineered and independently SIL3 certified version for use in safety and 65 | mission critical applications that require provable dependability. 66 | 67 | 1 tab == 4 spaces! 68 | */ 69 | 70 | 71 | /* 72 | * Implementation of pvPortMalloc() and vPortFree() that relies on the 73 | * compilers own malloc() and free() implementations. 74 | * 75 | * This file can only be used if the linker is configured to to generate 76 | * a heap memory area. 77 | * 78 | * See heap_1.c, heap_2.c and heap_4.c for alternative implementations, and the 79 | * memory management pages of http://www.FreeRTOS.org for more information. 80 | */ 81 | 82 | #include 83 | 84 | /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 85 | all the API functions to use the MPU wrappers. That should only be done when 86 | task.h is included from an application file. */ 87 | #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 88 | 89 | #include "FreeRTOS.h" 90 | #include "task.h" 91 | 92 | #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 93 | 94 | #if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) 95 | #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 96 | #endif 97 | 98 | /*-----------------------------------------------------------*/ 99 | 100 | void *pvPortMalloc( size_t xWantedSize ) 101 | { 102 | void *pvReturn; 103 | 104 | vTaskSuspendAll(); 105 | { 106 | pvReturn = malloc( xWantedSize ); 107 | traceMALLOC( pvReturn, xWantedSize ); 108 | } 109 | ( void ) xTaskResumeAll(); 110 | 111 | #if( configUSE_MALLOC_FAILED_HOOK == 1 ) 112 | { 113 | if( pvReturn == NULL ) 114 | { 115 | extern void vApplicationMallocFailedHook( void ); 116 | vApplicationMallocFailedHook(); 117 | } 118 | } 119 | #endif 120 | 121 | return pvReturn; 122 | } 123 | /*-----------------------------------------------------------*/ 124 | 125 | void vPortFree( void *pv ) 126 | { 127 | if( pv ) 128 | { 129 | vTaskSuspendAll(); 130 | { 131 | free( pv ); 132 | traceFREE( pv, 0 ); 133 | } 134 | ( void ) xTaskResumeAll(); 135 | } 136 | } 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /src/list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.0 3 | * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | 29 | #include 30 | #include "FreeRTOS.h" 31 | #include "list.h" 32 | 33 | /*----------------------------------------------------------- 34 | * PUBLIC LIST API documented in list.h 35 | *----------------------------------------------------------*/ 36 | 37 | void vListInitialise( List_t * const pxList ) 38 | { 39 | /* The list structure contains a list item which is used to mark the 40 | end of the list. To initialise the list the list end is inserted 41 | as the only list entry. */ 42 | pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 43 | 44 | /* The list end value is the highest possible value in the list to 45 | ensure it remains at the end of the list. */ 46 | pxList->xListEnd.xItemValue = portMAX_DELAY; 47 | 48 | /* The list end next and previous pointers point to itself so we know 49 | when the list is empty. */ 50 | pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 51 | pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 52 | 53 | pxList->uxNumberOfItems = ( UBaseType_t ) 0U; 54 | 55 | /* Write known values into the list if 56 | configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 57 | listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); 58 | listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); 59 | } 60 | /*-----------------------------------------------------------*/ 61 | 62 | void vListInitialiseItem( ListItem_t * const pxItem ) 63 | { 64 | /* Make sure the list item is not recorded as being on a list. */ 65 | pxItem->pxContainer = NULL; 66 | 67 | /* Write known values into the list item if 68 | configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 69 | listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); 70 | listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); 71 | } 72 | /*-----------------------------------------------------------*/ 73 | 74 | void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) 75 | { 76 | ListItem_t * const pxIndex = pxList->pxIndex; 77 | 78 | /* Only effective when configASSERT() is also defined, these tests may catch 79 | the list data structures being overwritten in memory. They will not catch 80 | data errors caused by incorrect configuration or use of FreeRTOS. */ 81 | listTEST_LIST_INTEGRITY( pxList ); 82 | listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); 83 | 84 | /* Insert a new list item into pxList, but rather than sort the list, 85 | makes the new list item the last item to be removed by a call to 86 | listGET_OWNER_OF_NEXT_ENTRY(). */ 87 | pxNewListItem->pxNext = pxIndex; 88 | pxNewListItem->pxPrevious = pxIndex->pxPrevious; 89 | 90 | /* Only used during decision coverage testing. */ 91 | mtCOVERAGE_TEST_DELAY(); 92 | 93 | pxIndex->pxPrevious->pxNext = pxNewListItem; 94 | pxIndex->pxPrevious = pxNewListItem; 95 | 96 | /* Remember which list the item is in. */ 97 | pxNewListItem->pxContainer = pxList; 98 | 99 | ( pxList->uxNumberOfItems )++; 100 | } 101 | /*-----------------------------------------------------------*/ 102 | 103 | void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) 104 | { 105 | ListItem_t *pxIterator; 106 | const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; 107 | 108 | /* Only effective when configASSERT() is also defined, these tests may catch 109 | the list data structures being overwritten in memory. They will not catch 110 | data errors caused by incorrect configuration or use of FreeRTOS. */ 111 | listTEST_LIST_INTEGRITY( pxList ); 112 | listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); 113 | 114 | /* Insert the new list item into the list, sorted in xItemValue order. 115 | 116 | If the list already contains a list item with the same item value then the 117 | new list item should be placed after it. This ensures that TCBs which are 118 | stored in ready lists (all of which have the same xItemValue value) get a 119 | share of the CPU. However, if the xItemValue is the same as the back marker 120 | the iteration loop below will not end. Therefore the value is checked 121 | first, and the algorithm slightly modified if necessary. */ 122 | if( xValueOfInsertion == portMAX_DELAY ) 123 | { 124 | pxIterator = pxList->xListEnd.pxPrevious; 125 | } 126 | else 127 | { 128 | /* *** NOTE *********************************************************** 129 | If you find your application is crashing here then likely causes are 130 | listed below. In addition see https://www.freertos.org/FAQHelp.html for 131 | more tips, and ensure configASSERT() is defined! 132 | https://www.freertos.org/a00110.html#configASSERT 133 | 134 | 1) Stack overflow - 135 | see https://www.freertos.org/Stacks-and-stack-overflow-checking.html 136 | 2) Incorrect interrupt priority assignment, especially on Cortex-M 137 | parts where numerically high priority values denote low actual 138 | interrupt priorities, which can seem counter intuitive. See 139 | https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition 140 | of configMAX_SYSCALL_INTERRUPT_PRIORITY on 141 | https://www.freertos.org/a00110.html 142 | 3) Calling an API function from within a critical section or when 143 | the scheduler is suspended, or calling an API function that does 144 | not end in "FromISR" from an interrupt. 145 | 4) Using a queue or semaphore before it has been initialised or 146 | before the scheduler has been started (are interrupts firing 147 | before vTaskStartScheduler() has been called?). 148 | **********************************************************************/ 149 | 150 | for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */ 151 | { 152 | /* There is nothing to do here, just iterating to the wanted 153 | insertion position. */ 154 | } 155 | } 156 | 157 | pxNewListItem->pxNext = pxIterator->pxNext; 158 | pxNewListItem->pxNext->pxPrevious = pxNewListItem; 159 | pxNewListItem->pxPrevious = pxIterator; 160 | pxIterator->pxNext = pxNewListItem; 161 | 162 | /* Remember which list the item is in. This allows fast removal of the 163 | item later. */ 164 | pxNewListItem->pxContainer = pxList; 165 | 166 | ( pxList->uxNumberOfItems )++; 167 | } 168 | /*-----------------------------------------------------------*/ 169 | 170 | UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) 171 | { 172 | /* The list item knows which list it is in. Obtain the list from the list 173 | item. */ 174 | List_t * const pxList = pxItemToRemove->pxContainer; 175 | 176 | pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; 177 | pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; 178 | 179 | /* Only used during decision coverage testing. */ 180 | mtCOVERAGE_TEST_DELAY(); 181 | 182 | /* Make sure the index is left pointing to a valid item. */ 183 | if( pxList->pxIndex == pxItemToRemove ) 184 | { 185 | pxList->pxIndex = pxItemToRemove->pxPrevious; 186 | } 187 | else 188 | { 189 | mtCOVERAGE_TEST_MARKER(); 190 | } 191 | 192 | pxItemToRemove->pxContainer = NULL; 193 | ( pxList->uxNumberOfItems )--; 194 | 195 | return pxList->uxNumberOfItems; 196 | } 197 | /*-----------------------------------------------------------*/ 198 | 199 | -------------------------------------------------------------------------------- /src/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.0 3 | * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /* 29 | * This is the list implementation used by the scheduler. While it is tailored 30 | * heavily for the schedulers needs, it is also available for use by 31 | * application code. 32 | * 33 | * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a 34 | * numeric value (xItemValue). Most of the time the lists are sorted in 35 | * descending item value order. 36 | * 37 | * Lists are created already containing one list item. The value of this 38 | * item is the maximum possible that can be stored, it is therefore always at 39 | * the end of the list and acts as a marker. The list member pxHead always 40 | * points to this marker - even though it is at the tail of the list. This 41 | * is because the tail contains a wrap back pointer to the true head of 42 | * the list. 43 | * 44 | * In addition to it's value, each list item contains a pointer to the next 45 | * item in the list (pxNext), a pointer to the list it is in (pxContainer) 46 | * and a pointer to back to the object that contains it. These later two 47 | * pointers are included for efficiency of list manipulation. There is 48 | * effectively a two way link between the object containing the list item and 49 | * the list item itself. 50 | * 51 | * 52 | * \page ListIntroduction List Implementation 53 | * \ingroup FreeRTOSIntro 54 | */ 55 | 56 | #ifndef INC_FREERTOS_H 57 | #error FreeRTOS.h must be included before list.h 58 | #endif 59 | 60 | #ifndef LIST_H 61 | #define LIST_H 62 | 63 | /* 64 | * The list structure members are modified from within interrupts, and therefore 65 | * by rights should be declared volatile. However, they are only modified in a 66 | * functionally atomic way (within critical sections of with the scheduler 67 | * suspended) and are either passed by reference into a function or indexed via 68 | * a volatile variable. Therefore, in all use cases tested so far, the volatile 69 | * qualifier can be omitted in order to provide a moderate performance 70 | * improvement without adversely affecting functional behaviour. The assembly 71 | * instructions generated by the IAR, ARM and GCC compilers when the respective 72 | * compiler's options were set for maximum optimisation has been inspected and 73 | * deemed to be as intended. That said, as compiler technology advances, and 74 | * especially if aggressive cross module optimisation is used (a use case that 75 | * has not been exercised to any great extend) then it is feasible that the 76 | * volatile qualifier will be needed for correct optimisation. It is expected 77 | * that a compiler removing essential code because, without the volatile 78 | * qualifier on the list structure members and with aggressive cross module 79 | * optimisation, the compiler deemed the code unnecessary will result in 80 | * complete and obvious failure of the scheduler. If this is ever experienced 81 | * then the volatile qualifier can be inserted in the relevant places within the 82 | * list structures by simply defining configLIST_VOLATILE to volatile in 83 | * FreeRTOSConfig.h (as per the example at the bottom of this comment block). 84 | * If configLIST_VOLATILE is not defined then the preprocessor directives below 85 | * will simply #define configLIST_VOLATILE away completely. 86 | * 87 | * To use volatile list structure members then add the following line to 88 | * FreeRTOSConfig.h (without the quotes): 89 | * "#define configLIST_VOLATILE volatile" 90 | */ 91 | #ifndef configLIST_VOLATILE 92 | #define configLIST_VOLATILE 93 | #endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ 94 | 95 | #ifdef __cplusplus 96 | extern "C" { 97 | #endif 98 | 99 | /* Macros that can be used to place known values within the list structures, 100 | then check that the known values do not get corrupted during the execution of 101 | the application. These may catch the list data structures being overwritten in 102 | memory. They will not catch data errors caused by incorrect configuration or 103 | use of FreeRTOS.*/ 104 | #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) 105 | /* Define the macros to do nothing. */ 106 | #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE 107 | #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE 108 | #define listFIRST_LIST_INTEGRITY_CHECK_VALUE 109 | #define listSECOND_LIST_INTEGRITY_CHECK_VALUE 110 | #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) 111 | #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) 112 | #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) 113 | #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) 114 | #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) 115 | #define listTEST_LIST_INTEGRITY( pxList ) 116 | #else 117 | /* Define macros that add new members into the list structures. */ 118 | #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; 119 | #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; 120 | #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1; 121 | #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2; 122 | 123 | /* Define macros that set the new structure members to known values. */ 124 | #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE 125 | #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE 126 | #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE 127 | #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE 128 | 129 | /* Define macros that will assert if one of the structure members does not 130 | contain its expected value. */ 131 | #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) 132 | #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) 133 | #endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ 134 | 135 | 136 | /* 137 | * Definition of the only type of object that a list can contain. 138 | */ 139 | struct xLIST; 140 | struct xLIST_ITEM 141 | { 142 | listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 143 | configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ 144 | struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ 145 | struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ 146 | void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ 147 | struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */ 148 | listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 149 | }; 150 | typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ 151 | 152 | struct xMINI_LIST_ITEM 153 | { 154 | listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 155 | configLIST_VOLATILE TickType_t xItemValue; 156 | struct xLIST_ITEM * configLIST_VOLATILE pxNext; 157 | struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; 158 | }; 159 | typedef struct xMINI_LIST_ITEM MiniListItem_t; 160 | 161 | /* 162 | * Definition of the type of queue used by the scheduler. 163 | */ 164 | typedef struct xLIST 165 | { 166 | listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 167 | volatile UBaseType_t uxNumberOfItems; 168 | ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ 169 | MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ 170 | listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 171 | } List_t; 172 | 173 | /* 174 | * Access macro to set the owner of a list item. The owner of a list item 175 | * is the object (usually a TCB) that contains the list item. 176 | * 177 | * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER 178 | * \ingroup LinkedList 179 | */ 180 | #define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) 181 | 182 | /* 183 | * Access macro to get the owner of a list item. The owner of a list item 184 | * is the object (usually a TCB) that contains the list item. 185 | * 186 | * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER 187 | * \ingroup LinkedList 188 | */ 189 | #define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner ) 190 | 191 | /* 192 | * Access macro to set the value of the list item. In most cases the value is 193 | * used to sort the list in descending order. 194 | * 195 | * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE 196 | * \ingroup LinkedList 197 | */ 198 | #define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) 199 | 200 | /* 201 | * Access macro to retrieve the value of the list item. The value can 202 | * represent anything - for example the priority of a task, or the time at 203 | * which a task should be unblocked. 204 | * 205 | * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE 206 | * \ingroup LinkedList 207 | */ 208 | #define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) 209 | 210 | /* 211 | * Access macro to retrieve the value of the list item at the head of a given 212 | * list. 213 | * 214 | * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE 215 | * \ingroup LinkedList 216 | */ 217 | #define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) 218 | 219 | /* 220 | * Return the list item at the head of the list. 221 | * 222 | * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY 223 | * \ingroup LinkedList 224 | */ 225 | #define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext ) 226 | 227 | /* 228 | * Return the list item at the head of the list. 229 | * 230 | * \page listGET_NEXT listGET_NEXT 231 | * \ingroup LinkedList 232 | */ 233 | #define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext ) 234 | 235 | /* 236 | * Return the list item that marks the end of the list 237 | * 238 | * \page listGET_END_MARKER listGET_END_MARKER 239 | * \ingroup LinkedList 240 | */ 241 | #define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) 242 | 243 | /* 244 | * Access macro to determine if a list contains any items. The macro will 245 | * only have the value true if the list is empty. 246 | * 247 | * \page listLIST_IS_EMPTY listLIST_IS_EMPTY 248 | * \ingroup LinkedList 249 | */ 250 | #define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE ) 251 | 252 | /* 253 | * Access macro to return the number of items in the list. 254 | */ 255 | #define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) 256 | 257 | /* 258 | * Access function to obtain the owner of the next entry in a list. 259 | * 260 | * The list member pxIndex is used to walk through a list. Calling 261 | * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list 262 | * and returns that entry's pxOwner parameter. Using multiple calls to this 263 | * function it is therefore possible to move through every item contained in 264 | * a list. 265 | * 266 | * The pxOwner parameter of a list item is a pointer to the object that owns 267 | * the list item. In the scheduler this is normally a task control block. 268 | * The pxOwner parameter effectively creates a two way link between the list 269 | * item and its owner. 270 | * 271 | * @param pxTCB pxTCB is set to the address of the owner of the next list item. 272 | * @param pxList The list from which the next item owner is to be returned. 273 | * 274 | * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY 275 | * \ingroup LinkedList 276 | */ 277 | #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ 278 | { \ 279 | List_t * const pxConstList = ( pxList ); \ 280 | /* Increment the index to the next item and return the item, ensuring */ \ 281 | /* we don't return the marker used at the end of the list. */ \ 282 | ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ 283 | if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ 284 | { \ 285 | ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ 286 | } \ 287 | ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ 288 | } 289 | 290 | 291 | /* 292 | * Access function to obtain the owner of the first entry in a list. Lists 293 | * are normally sorted in ascending item value order. 294 | * 295 | * This function returns the pxOwner member of the first item in the list. 296 | * The pxOwner parameter of a list item is a pointer to the object that owns 297 | * the list item. In the scheduler this is normally a task control block. 298 | * The pxOwner parameter effectively creates a two way link between the list 299 | * item and its owner. 300 | * 301 | * @param pxList The list from which the owner of the head item is to be 302 | * returned. 303 | * 304 | * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY 305 | * \ingroup LinkedList 306 | */ 307 | #define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) 308 | 309 | /* 310 | * Check to see if a list item is within a list. The list item maintains a 311 | * "container" pointer that points to the list it is in. All this macro does 312 | * is check to see if the container and the list match. 313 | * 314 | * @param pxList The list we want to know if the list item is within. 315 | * @param pxListItem The list item we want to know if is in the list. 316 | * @return pdTRUE if the list item is in the list, otherwise pdFALSE. 317 | */ 318 | #define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) ) 319 | 320 | /* 321 | * Return the list a list item is contained within (referenced from). 322 | * 323 | * @param pxListItem The list item being queried. 324 | * @return A pointer to the List_t object that references the pxListItem 325 | */ 326 | #define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer ) 327 | 328 | /* 329 | * This provides a crude means of knowing if a list has been initialised, as 330 | * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() 331 | * function. 332 | */ 333 | #define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) 334 | 335 | /* 336 | * Must be called before a list is used! This initialises all the members 337 | * of the list structure and inserts the xListEnd item into the list as a 338 | * marker to the back of the list. 339 | * 340 | * @param pxList Pointer to the list being initialised. 341 | * 342 | * \page vListInitialise vListInitialise 343 | * \ingroup LinkedList 344 | */ 345 | void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION; 346 | 347 | /* 348 | * Must be called before a list item is used. This sets the list container to 349 | * null so the item does not think that it is already contained in a list. 350 | * 351 | * @param pxItem Pointer to the list item being initialised. 352 | * 353 | * \page vListInitialiseItem vListInitialiseItem 354 | * \ingroup LinkedList 355 | */ 356 | void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION; 357 | 358 | /* 359 | * Insert a list item into a list. The item will be inserted into the list in 360 | * a position determined by its item value (descending item value order). 361 | * 362 | * @param pxList The list into which the item is to be inserted. 363 | * 364 | * @param pxNewListItem The item that is to be placed in the list. 365 | * 366 | * \page vListInsert vListInsert 367 | * \ingroup LinkedList 368 | */ 369 | void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; 370 | 371 | /* 372 | * Insert a list item into a list. The item will be inserted in a position 373 | * such that it will be the last item within the list returned by multiple 374 | * calls to listGET_OWNER_OF_NEXT_ENTRY. 375 | * 376 | * The list member pxIndex is used to walk through a list. Calling 377 | * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. 378 | * Placing an item in a list using vListInsertEnd effectively places the item 379 | * in the list position pointed to by pxIndex. This means that every other 380 | * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before 381 | * the pxIndex parameter again points to the item being inserted. 382 | * 383 | * @param pxList The list into which the item is to be inserted. 384 | * 385 | * @param pxNewListItem The list item to be inserted into the list. 386 | * 387 | * \page vListInsertEnd vListInsertEnd 388 | * \ingroup LinkedList 389 | */ 390 | void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; 391 | 392 | /* 393 | * Remove an item from a list. The list item has a pointer to the list that 394 | * it is in, so only the list item need be passed into the function. 395 | * 396 | * @param uxListRemove The item to be removed. The item will remove itself from 397 | * the list pointed to by it's pxContainer parameter. 398 | * 399 | * @return The number of items that remain in the list after the list item has 400 | * been removed. 401 | * 402 | * \page uxListRemove uxListRemove 403 | * \ingroup LinkedList 404 | */ 405 | UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION; 406 | 407 | #ifdef __cplusplus 408 | } 409 | #endif 410 | 411 | #endif 412 | 413 | -------------------------------------------------------------------------------- /src/memcpy-armv7m.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 ARM Ltd 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. The name of the company may not be used to endorse or promote 14 | * products derived from this software without specific prior written 15 | * permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 22 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #if defined (__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) 30 | /* 31 | * Let __ARM_FEATURE_UNALIGNED be set by the achitechture and the compiler flags: 32 | * -munaligned-access 33 | * -mno-unaligned-access 34 | * instead of always setting it here. 35 | * 36 | * #define __ARM_FEATURE_UNALIGNED 1 37 | */ 38 | 39 | /* This memcpy routine is optimised for Cortex-M3/M4 cores with/without 40 | unaligned access. 41 | 42 | If compiled with GCC, this file should be enclosed within following 43 | pre-processing check: 44 | if defined (__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) 45 | 46 | Prototype: void *memcpy (void *dst, const void *src, size_t count); 47 | 48 | The job will be done in 5 steps. 49 | Step 1: Align src/dest pointers, copy mis-aligned if fail to align both 50 | Step 2: Repeatedly copy big block size of __OPT_BIG_BLOCK_SIZE 51 | Step 3: Repeatedly copy big block size of __OPT_MID_BLOCK_SIZE 52 | Step 4: Copy word by word 53 | Step 5: Copy byte-to-byte 54 | 55 | Tunable options: 56 | __OPT_BIG_BLOCK_SIZE: Size of big block in words. Default to 64. 57 | __OPT_MID_BLOCK_SIZE: Size of big block in words. Default to 16. 58 | */ 59 | #ifndef __OPT_BIG_BLOCK_SIZE 60 | #define __OPT_BIG_BLOCK_SIZE (4 * 16) 61 | #endif 62 | 63 | #ifndef __OPT_MID_BLOCK_SIZE 64 | #define __OPT_MID_BLOCK_SIZE (4 * 4) 65 | #endif 66 | 67 | #if __OPT_BIG_BLOCK_SIZE == 16 68 | #define BEGIN_UNROLL_BIG_BLOCK \ 69 | .irp offset, 0,4,8,12 70 | #elif __OPT_BIG_BLOCK_SIZE == 32 71 | #define BEGIN_UNROLL_BIG_BLOCK \ 72 | .irp offset, 0,4,8,12,16,20,24,28 73 | #elif __OPT_BIG_BLOCK_SIZE == 64 74 | #define BEGIN_UNROLL_BIG_BLOCK \ 75 | .irp offset, 0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60 76 | #else 77 | #error "Illegal __OPT_BIG_BLOCK_SIZE" 78 | #endif 79 | 80 | #if __OPT_MID_BLOCK_SIZE == 8 81 | #define BEGIN_UNROLL_MID_BLOCK \ 82 | .irp offset, 0,4 83 | #elif __OPT_MID_BLOCK_SIZE == 16 84 | #define BEGIN_UNROLL_MID_BLOCK \ 85 | .irp offset, 0,4,8,12 86 | #else 87 | #error "Illegal __OPT_MID_BLOCK_SIZE" 88 | #endif 89 | 90 | #define END_UNROLL .endr 91 | 92 | .syntax unified 93 | .text 94 | .align 2 95 | .global memcpy 96 | .thumb 97 | .thumb_func 98 | .type memcpy, %function 99 | memcpy: 100 | @ r0: dst 101 | @ r1: src 102 | @ r2: len 103 | #ifdef __ARM_FEATURE_UNALIGNED 104 | /* In case of UNALIGNED access supported, ip is not used in 105 | function body. */ 106 | mov ip, r0 107 | #else 108 | push {r0} 109 | #endif 110 | orr r3, r1, r0 111 | ands r3, r3, #3 112 | bne .Lmisaligned_copy 113 | 114 | .Lbig_block: 115 | subs r2, __OPT_BIG_BLOCK_SIZE 116 | blo .Lmid_block 117 | 118 | /* Kernel loop for big block copy */ 119 | .align 2 120 | .Lbig_block_loop: 121 | BEGIN_UNROLL_BIG_BLOCK 122 | #ifdef __ARM_ARCH_7EM__ 123 | ldr r3, [r1], #4 124 | str r3, [r0], #4 125 | END_UNROLL 126 | #else /* __ARM_ARCH_7M__ */ 127 | ldr r3, [r1, \offset] 128 | str r3, [r0, \offset] 129 | END_UNROLL 130 | adds r0, __OPT_BIG_BLOCK_SIZE 131 | adds r1, __OPT_BIG_BLOCK_SIZE 132 | #endif 133 | subs r2, __OPT_BIG_BLOCK_SIZE 134 | bhs .Lbig_block_loop 135 | 136 | .Lmid_block: 137 | adds r2, __OPT_BIG_BLOCK_SIZE - __OPT_MID_BLOCK_SIZE 138 | blo .Lcopy_word_by_word 139 | 140 | /* Kernel loop for mid-block copy */ 141 | .align 2 142 | .Lmid_block_loop: 143 | BEGIN_UNROLL_MID_BLOCK 144 | #ifdef __ARM_ARCH_7EM__ 145 | ldr r3, [r1], #4 146 | str r3, [r0], #4 147 | END_UNROLL 148 | #else /* __ARM_ARCH_7M__ */ 149 | ldr r3, [r1, \offset] 150 | str r3, [r0, \offset] 151 | END_UNROLL 152 | adds r0, __OPT_MID_BLOCK_SIZE 153 | adds r1, __OPT_MID_BLOCK_SIZE 154 | #endif 155 | subs r2, __OPT_MID_BLOCK_SIZE 156 | bhs .Lmid_block_loop 157 | 158 | .Lcopy_word_by_word: 159 | adds r2, __OPT_MID_BLOCK_SIZE - 4 160 | blo .Lcopy_less_than_4 161 | 162 | /* Kernel loop for small block copy */ 163 | .align 2 164 | .Lcopy_word_by_word_loop: 165 | ldr r3, [r1], #4 166 | str r3, [r0], #4 167 | subs r2, #4 168 | bhs .Lcopy_word_by_word_loop 169 | 170 | .Lcopy_less_than_4: 171 | adds r2, #4 172 | beq .Ldone 173 | 174 | lsls r2, r2, #31 175 | itt ne 176 | ldrbne r3, [r1], #1 177 | strbne r3, [r0], #1 178 | 179 | bcc .Ldone 180 | #ifdef __ARM_FEATURE_UNALIGNED 181 | ldrh r3, [r1] 182 | strh r3, [r0] 183 | #else 184 | ldrb r3, [r1] 185 | strb r3, [r0] 186 | ldrb r3, [r1, #1] 187 | strb r3, [r0, #1] 188 | #endif /* __ARM_FEATURE_UNALIGNED */ 189 | 190 | .Ldone: 191 | #ifdef __ARM_FEATURE_UNALIGNED 192 | mov r0, ip 193 | #else 194 | pop {r0} 195 | #endif 196 | bx lr 197 | 198 | .align 2 199 | .Lmisaligned_copy: 200 | #ifdef __ARM_FEATURE_UNALIGNED 201 | /* Define label DST_ALIGNED to BIG_BLOCK. It will go to aligned copy 202 | once destination is adjusted to aligned. */ 203 | #define Ldst_aligned Lbig_block 204 | 205 | /* Copy word by word using LDR when alignment can be done in hardware, 206 | i.e., SCTLR.A is set, supporting unaligned access in LDR and STR. */ 207 | 208 | cmp r2, #8 209 | blo .Lbyte_copy 210 | 211 | /* if src is aligned, just go to the big block loop. */ 212 | lsls r3, r1, #30 213 | beq .Ldst_aligned 214 | #else 215 | /* if len < 12, misalignment adjustment has more overhead than 216 | just byte-to-byte copy. Also, len must >=8 to guarantee code 217 | afterward work correctly. */ 218 | cmp r2, #12 219 | blo .Lbyte_copy 220 | #endif /* __ARM_FEATURE_UNALIGNED */ 221 | 222 | /* Align dst only, not trying to align src. That is the because 223 | handling of aligned src and misaligned dst need more overhead than 224 | otherwise. By doing this the worst case is when initial src is aligned, 225 | additional up to 4 byte additional copy will executed, which is 226 | acceptable. */ 227 | 228 | ands r3, r0, #3 229 | beq .Ldst_aligned 230 | 231 | rsb r3, #4 232 | subs r2, r3 233 | 234 | lsls r3, r3, #31 235 | itt ne 236 | ldrbne r3, [r1], #1 237 | strbne r3, [r0], #1 238 | 239 | bcc .Ldst_aligned 240 | 241 | #ifdef __ARM_FEATURE_UNALIGNED 242 | ldrh r3, [r1], #2 243 | strh r3, [r0], #2 244 | b .Ldst_aligned 245 | #else 246 | ldrb r3, [r1], #1 247 | strb r3, [r0], #1 248 | ldrb r3, [r1], #1 249 | strb r3, [r0], #1 250 | /* Now that dst is aligned */ 251 | .Ldst_aligned: 252 | /* if r1 is aligned now, it means r0/r1 has the same misalignment, 253 | and they are both aligned now. Go aligned copy. */ 254 | ands r3, r1, #3 255 | beq .Lbig_block 256 | 257 | /* dst is aligned, but src isn't. Misaligned copy. */ 258 | 259 | push {r4, r5} 260 | subs r2, #4 261 | 262 | /* Backward r1 by misaligned bytes, to make r1 aligned. 263 | Since we need to restore r1 to unaligned address after the loop, 264 | we need keep the offset bytes to ip and sub it from r1 afterward. */ 265 | subs r1, r3 266 | rsb ip, r3, #4 267 | 268 | /* Pre-load on word */ 269 | ldr r4, [r1], #4 270 | 271 | cmp r3, #2 272 | beq .Lmisaligned_copy_2_2 273 | cmp r3, #3 274 | beq .Lmisaligned_copy_3_1 275 | 276 | .macro mis_src_copy shift 277 | 1: 278 | lsrs r4, r4, \shift 279 | ldr r3, [r1], #4 280 | lsls r5, r3, 32-\shift 281 | orr r4, r4, r5 282 | str r4, [r0], #4 283 | mov r4, r3 284 | subs r2, #4 285 | bhs 1b 286 | .endm 287 | 288 | .Lmisaligned_copy_1_3: 289 | mis_src_copy shift=8 290 | b .Lsrc_misaligned_tail 291 | 292 | .Lmisaligned_copy_3_1: 293 | mis_src_copy shift=24 294 | b .Lsrc_misaligned_tail 295 | 296 | .Lmisaligned_copy_2_2: 297 | /* For 2_2 misalignment, ldr is still faster than 2 x ldrh. */ 298 | mis_src_copy shift=16 299 | 300 | .Lsrc_misaligned_tail: 301 | adds r2, #4 302 | subs r1, ip 303 | pop {r4, r5} 304 | 305 | #endif /* __ARM_FEATURE_UNALIGNED */ 306 | 307 | .Lbyte_copy: 308 | subs r2, #4 309 | blo .Lcopy_less_than_4 310 | 311 | .Lbyte_copy_loop: 312 | subs r2, #1 313 | ldrb r3, [r1], #1 314 | strb r3, [r0], #1 315 | bhs .Lbyte_copy_loop 316 | 317 | ldrb r3, [r1] 318 | strb r3, [r0] 319 | ldrb r3, [r1, #1] 320 | strb r3, [r0, #1] 321 | ldrb r3, [r1, #2] 322 | strb r3, [r0, #2] 323 | 324 | #ifdef __ARM_FEATURE_UNALIGNED 325 | mov r0, ip 326 | #else 327 | pop {r0} 328 | #endif 329 | bx lr 330 | 331 | .size memcpy, .-memcpy 332 | #endif 333 | -------------------------------------------------------------------------------- /src/memset.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Travis Geiselbrecht 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files 6 | * (the "Software"), to deal in the Software without restriction, 7 | * including without limitation the rights to use, copy, modify, merge, 8 | * publish, distribute, sublicense, and/or sell copies of the Software, 9 | * and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | //#include 24 | //#include 25 | #if defined (__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) 26 | .global memset 27 | .text 28 | .syntax unified 29 | .thumb 30 | .align 2 31 | 32 | /* void *memset(void *s, int c, size_t n); */ 33 | .type memset, %function 34 | .thumb_func 35 | memset: 36 | //FUNCTION(memset) 37 | // save the original pointer 38 | push { r0, lr } 39 | 40 | // check for zero length 41 | cbz r2, .L_done 42 | 43 | // short memsets aren't worth optimizing and make sure we have 44 | // enough headroom to try to do dwordwise move optimization 45 | cmp r2, #16 46 | blt .L_bytewise 47 | 48 | // see how many bytes we need to move to align to dword boundaries 49 | and r3, r0, #7 50 | cbz r3, .L_prepare_dwordwise 51 | rsb r3, #8 52 | subs r2, r3 53 | 54 | .L_bytewise_align: 55 | // bytewise to align memset 56 | subs r3, r3, #1 57 | strb r1, [r0], #1 58 | bgt .L_bytewise_align 59 | 60 | .L_prepare_dwordwise: 61 | // fill a pair of 32 bit registers with the 8 bit value 62 | uxtb r1, r1 63 | orr r1, r1, r1, lsl #8 64 | orr r1, r1, r1, lsl #16 65 | mov r12, r1 66 | 67 | // load the number of dwords left 68 | lsrs r3, r2, #3 69 | 70 | .L_dwordwise: 71 | // dwordwise memset 72 | 73 | subs r3, r3, #1 74 | strd r1, r12, [r0], #8 75 | bgt .L_dwordwise 76 | 77 | // remaining bytes 78 | ands r2, #7 79 | beq .L_done 80 | 81 | .L_bytewise: 82 | // bytewise memset 83 | subs r2, r2, #1 84 | strb r1, [r0], #1 85 | bgt .L_bytewise 86 | 87 | .L_done: 88 | // restore the base pointer as return value 89 | pop { r0, pc } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /src/mpu_prototypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.0 3 | * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /* 29 | * When the MPU is used the standard (non MPU) API functions are mapped to 30 | * equivalents that start "MPU_", the prototypes for which are defined in this 31 | * header files. This will cause the application code to call the MPU_ version 32 | * which wraps the non-MPU version with privilege promoting then demoting code, 33 | * so the kernel code always runs will full privileges. 34 | */ 35 | 36 | 37 | #ifndef MPU_PROTOTYPES_H 38 | #define MPU_PROTOTYPES_H 39 | 40 | /* MPU versions of tasks.h API functions. */ 41 | BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL; 42 | TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL; 43 | BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; 44 | BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; 45 | void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) FREERTOS_SYSTEM_CALL; 46 | void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL; 47 | void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL; 48 | void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL; 49 | BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; 50 | UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; 51 | eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; 52 | void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) FREERTOS_SYSTEM_CALL; 53 | void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL; 54 | void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL; 55 | void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL; 56 | void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL; 57 | void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL; 58 | BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL; 59 | TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL; 60 | UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL; 61 | char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL; 62 | TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) FREERTOS_SYSTEM_CALL; 63 | UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; 64 | configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; 65 | void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL; 66 | TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; 67 | void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) FREERTOS_SYSTEM_CALL; 68 | void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) FREERTOS_SYSTEM_CALL; 69 | BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) FREERTOS_SYSTEM_CALL; 70 | TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL; 71 | UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL; 72 | TickType_t MPU_xTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL; 73 | void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; 74 | void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) FREERTOS_SYSTEM_CALL; 75 | BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL; 76 | BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; 77 | uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; 78 | BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; 79 | BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL; 80 | TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; 81 | void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL; 82 | BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL; 83 | void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL; 84 | BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; 85 | 86 | /* MPU versions of queue.h API functions. */ 87 | BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL; 88 | BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; 89 | BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; 90 | BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; 91 | UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; 92 | UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; 93 | void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; 94 | QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; 95 | QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL; 96 | QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL; 97 | QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL; 98 | TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL; 99 | BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; 100 | BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL; 101 | void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) FREERTOS_SYSTEM_CALL; 102 | void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; 103 | const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; 104 | QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; 105 | QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; 106 | QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL; 107 | BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; 108 | BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; 109 | QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; 110 | BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL; 111 | void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL; 112 | UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; 113 | uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; 114 | 115 | /* MPU versions of timers.h API functions. */ 116 | TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL; 117 | TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) FREERTOS_SYSTEM_CALL; 118 | void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; 119 | void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) FREERTOS_SYSTEM_CALL; 120 | BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; 121 | TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL; 122 | BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; 123 | const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; 124 | void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; 125 | TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; 126 | TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; 127 | BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL; 128 | BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; 129 | 130 | /* MPU versions of event_group.h API functions. */ 131 | EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL; 132 | EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; 133 | EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; 134 | EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; 135 | EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL; 136 | EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; 137 | void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; 138 | UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ) FREERTOS_SYSTEM_CALL; 139 | 140 | /* MPU versions of message/stream_buffer.h API functions. */ 141 | size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; 142 | size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; 143 | size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; 144 | void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; 145 | BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; 146 | BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; 147 | BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; 148 | size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; 149 | size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; 150 | BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; 151 | StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL; 152 | StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL; 153 | 154 | 155 | 156 | #endif /* MPU_PROTOTYPES_H */ 157 | 158 | -------------------------------------------------------------------------------- /src/mpu_wrappers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.0 3 | * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef MPU_WRAPPERS_H 29 | #define MPU_WRAPPERS_H 30 | 31 | /* This file redefines API functions to be called through a wrapper macro, but 32 | only for ports that are using the MPU. */ 33 | #ifdef portUSING_MPU_WRAPPERS 34 | 35 | /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is 36 | included from queue.c or task.c to prevent it from having an effect within 37 | those files. */ 38 | #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 39 | 40 | /* 41 | * Map standard (non MPU) API functions to equivalents that start 42 | * "MPU_". This will cause the application code to call the MPU_ 43 | * version, which wraps the non-MPU version with privilege promoting 44 | * then demoting code, so the kernel code always runs will full 45 | * privileges. 46 | */ 47 | 48 | /* Map standard tasks.h API functions to the MPU equivalents. */ 49 | #define xTaskCreate MPU_xTaskCreate 50 | #define xTaskCreateStatic MPU_xTaskCreateStatic 51 | #define xTaskCreateRestricted MPU_xTaskCreateRestricted 52 | #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions 53 | #define vTaskDelete MPU_vTaskDelete 54 | #define vTaskDelay MPU_vTaskDelay 55 | #define vTaskDelayUntil MPU_vTaskDelayUntil 56 | #define xTaskAbortDelay MPU_xTaskAbortDelay 57 | #define uxTaskPriorityGet MPU_uxTaskPriorityGet 58 | #define eTaskGetState MPU_eTaskGetState 59 | #define vTaskGetInfo MPU_vTaskGetInfo 60 | #define vTaskPrioritySet MPU_vTaskPrioritySet 61 | #define vTaskSuspend MPU_vTaskSuspend 62 | #define vTaskResume MPU_vTaskResume 63 | #define vTaskSuspendAll MPU_vTaskSuspendAll 64 | #define xTaskResumeAll MPU_xTaskResumeAll 65 | #define xTaskGetTickCount MPU_xTaskGetTickCount 66 | #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks 67 | #define pcTaskGetName MPU_pcTaskGetName 68 | #define xTaskGetHandle MPU_xTaskGetHandle 69 | #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark 70 | #define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 71 | #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag 72 | #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag 73 | #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer 74 | #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer 75 | #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook 76 | #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle 77 | #define uxTaskGetSystemState MPU_uxTaskGetSystemState 78 | #define vTaskList MPU_vTaskList 79 | #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats 80 | #define xTaskGetIdleRunTimeCounter MPU_xTaskGetIdleRunTimeCounter 81 | #define xTaskGenericNotify MPU_xTaskGenericNotify 82 | #define xTaskNotifyWait MPU_xTaskNotifyWait 83 | #define ulTaskNotifyTake MPU_ulTaskNotifyTake 84 | #define xTaskNotifyStateClear MPU_xTaskNotifyStateClear 85 | 86 | #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle 87 | #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState 88 | #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut 89 | #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState 90 | 91 | /* Map standard queue.h API functions to the MPU equivalents. */ 92 | #define xQueueGenericSend MPU_xQueueGenericSend 93 | #define xQueueReceive MPU_xQueueReceive 94 | #define xQueuePeek MPU_xQueuePeek 95 | #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake 96 | #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting 97 | #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable 98 | #define vQueueDelete MPU_vQueueDelete 99 | #define xQueueCreateMutex MPU_xQueueCreateMutex 100 | #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic 101 | #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore 102 | #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic 103 | #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder 104 | #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive 105 | #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive 106 | #define xQueueGenericCreate MPU_xQueueGenericCreate 107 | #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic 108 | #define xQueueCreateSet MPU_xQueueCreateSet 109 | #define xQueueAddToSet MPU_xQueueAddToSet 110 | #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet 111 | #define xQueueSelectFromSet MPU_xQueueSelectFromSet 112 | #define xQueueGenericReset MPU_xQueueGenericReset 113 | 114 | #if( configQUEUE_REGISTRY_SIZE > 0 ) 115 | #define vQueueAddToRegistry MPU_vQueueAddToRegistry 116 | #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue 117 | #define pcQueueGetName MPU_pcQueueGetName 118 | #endif 119 | 120 | /* Map standard timer.h API functions to the MPU equivalents. */ 121 | #define xTimerCreate MPU_xTimerCreate 122 | #define xTimerCreateStatic MPU_xTimerCreateStatic 123 | #define pvTimerGetTimerID MPU_pvTimerGetTimerID 124 | #define vTimerSetTimerID MPU_vTimerSetTimerID 125 | #define xTimerIsTimerActive MPU_xTimerIsTimerActive 126 | #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle 127 | #define xTimerPendFunctionCall MPU_xTimerPendFunctionCall 128 | #define pcTimerGetName MPU_pcTimerGetName 129 | #define vTimerSetReloadMode MPU_vTimerSetReloadMode 130 | #define xTimerGetPeriod MPU_xTimerGetPeriod 131 | #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime 132 | #define xTimerGenericCommand MPU_xTimerGenericCommand 133 | 134 | /* Map standard event_group.h API functions to the MPU equivalents. */ 135 | #define xEventGroupCreate MPU_xEventGroupCreate 136 | #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic 137 | #define xEventGroupWaitBits MPU_xEventGroupWaitBits 138 | #define xEventGroupClearBits MPU_xEventGroupClearBits 139 | #define xEventGroupSetBits MPU_xEventGroupSetBits 140 | #define xEventGroupSync MPU_xEventGroupSync 141 | #define vEventGroupDelete MPU_vEventGroupDelete 142 | 143 | /* Map standard message/stream_buffer.h API functions to the MPU 144 | equivalents. */ 145 | #define xStreamBufferSend MPU_xStreamBufferSend 146 | #define xStreamBufferReceive MPU_xStreamBufferReceive 147 | #define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes 148 | #define vStreamBufferDelete MPU_vStreamBufferDelete 149 | #define xStreamBufferIsFull MPU_xStreamBufferIsFull 150 | #define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty 151 | #define xStreamBufferReset MPU_xStreamBufferReset 152 | #define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable 153 | #define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable 154 | #define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel 155 | #define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate 156 | #define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic 157 | 158 | 159 | /* Remove the privileged function macro, but keep the PRIVILEGED_DATA 160 | macro so applications can place data in privileged access sections 161 | (useful when using statically allocated objects). */ 162 | #define PRIVILEGED_FUNCTION 163 | #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) 164 | #define FREERTOS_SYSTEM_CALL 165 | 166 | #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ 167 | 168 | /* Ensure API functions go in the privileged execution section. */ 169 | #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) 170 | #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) 171 | #define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls"))) 172 | 173 | #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ 174 | 175 | #else /* portUSING_MPU_WRAPPERS */ 176 | 177 | #define PRIVILEGED_FUNCTION 178 | #define PRIVILEGED_DATA 179 | #define FREERTOS_SYSTEM_CALL 180 | #define portUSING_MPU_WRAPPERS 0 181 | 182 | #endif /* portUSING_MPU_WRAPPERS */ 183 | 184 | 185 | #endif /* MPU_WRAPPERS_H */ 186 | 187 | -------------------------------------------------------------------------------- /src/portable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.0 3 | * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /*----------------------------------------------------------- 29 | * Portable layer API. Each function must be defined for each port. 30 | *----------------------------------------------------------*/ 31 | 32 | #ifndef PORTABLE_H 33 | #define PORTABLE_H 34 | 35 | /* Each FreeRTOS port has a unique portmacro.h header file. Originally a 36 | pre-processor definition was used to ensure the pre-processor found the correct 37 | portmacro.h file for the port being used. That scheme was deprecated in favour 38 | of setting the compiler's include path such that it found the correct 39 | portmacro.h file - removing the need for the constant and allowing the 40 | portmacro.h file to be located anywhere in relation to the port being used. 41 | Purely for reasons of backward compatibility the old method is still valid, but 42 | to make it clear that new projects should not use it, support for the port 43 | specific constants has been moved into the deprecated_definitions.h header 44 | file. */ 45 | #include "deprecated_definitions.h" 46 | 47 | /* If portENTER_CRITICAL is not defined then including deprecated_definitions.h 48 | did not result in a portmacro.h header file being included - and it should be 49 | included here. In this case the path to the correct portmacro.h header file 50 | must be set in the compiler's include path. */ 51 | #ifndef portENTER_CRITICAL 52 | #include "portmacro.h" 53 | #endif 54 | 55 | #if portBYTE_ALIGNMENT == 32 56 | #define portBYTE_ALIGNMENT_MASK ( 0x001f ) 57 | #endif 58 | 59 | #if portBYTE_ALIGNMENT == 16 60 | #define portBYTE_ALIGNMENT_MASK ( 0x000f ) 61 | #endif 62 | 63 | #if portBYTE_ALIGNMENT == 8 64 | #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) 65 | #endif 66 | 67 | #if portBYTE_ALIGNMENT == 4 68 | #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) 69 | #endif 70 | 71 | #if portBYTE_ALIGNMENT == 2 72 | #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) 73 | #endif 74 | 75 | #if portBYTE_ALIGNMENT == 1 76 | #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) 77 | #endif 78 | 79 | #ifndef portBYTE_ALIGNMENT_MASK 80 | #error "Invalid portBYTE_ALIGNMENT definition" 81 | #endif 82 | 83 | #ifndef portNUM_CONFIGURABLE_REGIONS 84 | #define portNUM_CONFIGURABLE_REGIONS 1 85 | #endif 86 | 87 | #ifndef portHAS_STACK_OVERFLOW_CHECKING 88 | #define portHAS_STACK_OVERFLOW_CHECKING 0 89 | #endif 90 | 91 | #ifndef portARCH_NAME 92 | #define portARCH_NAME NULL 93 | #endif 94 | 95 | #ifdef __cplusplus 96 | extern "C" { 97 | #endif 98 | 99 | #include "mpu_wrappers.h" 100 | 101 | /* 102 | * Setup the stack of a new task so it is ready to be placed under the 103 | * scheduler control. The registers have to be placed on the stack in 104 | * the order that the port expects to find them. 105 | * 106 | */ 107 | #if( portUSING_MPU_WRAPPERS == 1 ) 108 | #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) 109 | StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; 110 | #else 111 | StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; 112 | #endif 113 | #else 114 | #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) 115 | StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; 116 | #else 117 | StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; 118 | #endif 119 | #endif 120 | 121 | /* Used by heap_5.c. */ 122 | typedef struct HeapRegion 123 | { 124 | uint8_t *pucStartAddress; 125 | size_t xSizeInBytes; 126 | } HeapRegion_t; 127 | 128 | /* 129 | * Used to define multiple heap regions for use by heap_5.c. This function 130 | * must be called before any calls to pvPortMalloc() - not creating a task, 131 | * queue, semaphore, mutex, software timer, event group, etc. will result in 132 | * pvPortMalloc being called. 133 | * 134 | * pxHeapRegions passes in an array of HeapRegion_t structures - each of which 135 | * defines a region of memory that can be used as the heap. The array is 136 | * terminated by a HeapRegions_t structure that has a size of 0. The region 137 | * with the lowest start address must appear first in the array. 138 | */ 139 | void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION; 140 | 141 | 142 | /* 143 | * Map to the memory management routines required for the port. 144 | */ 145 | void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; 146 | void vPortFree( void *pv ) PRIVILEGED_FUNCTION; 147 | void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; 148 | size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; 149 | size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; 150 | 151 | /* 152 | * Setup the hardware ready for the scheduler to take control. This generally 153 | * sets up a tick interrupt and sets timers for the correct tick frequency. 154 | */ 155 | BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; 156 | 157 | /* 158 | * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so 159 | * the hardware is left in its original condition after the scheduler stops 160 | * executing. 161 | */ 162 | void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; 163 | 164 | /* 165 | * The structures and methods of manipulating the MPU are contained within the 166 | * port layer. 167 | * 168 | * Fills the xMPUSettings structure with the memory region information 169 | * contained in xRegions. 170 | */ 171 | #if( portUSING_MPU_WRAPPERS == 1 ) 172 | struct xMEMORY_REGION; 173 | void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; 174 | #endif 175 | 176 | #ifdef __cplusplus 177 | } 178 | #endif 179 | 180 | #endif /* PORTABLE_H */ 181 | 182 | -------------------------------------------------------------------------------- /src/portmacro.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.0 3 | * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | 29 | #ifndef PORTMACRO_H 30 | #define PORTMACRO_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | /*----------------------------------------------------------- 37 | * Port specific definitions. 38 | * 39 | * The settings in this file configure FreeRTOS correctly for the 40 | * given hardware and compiler. 41 | * 42 | * These settings should not be altered. 43 | *----------------------------------------------------------- 44 | */ 45 | 46 | /* Type definitions. */ 47 | #define portCHAR char 48 | #define portFLOAT float 49 | #define portDOUBLE double 50 | #define portLONG long 51 | #define portSHORT short 52 | #define portSTACK_TYPE uint32_t 53 | #define portBASE_TYPE long 54 | 55 | typedef portSTACK_TYPE StackType_t; 56 | typedef long BaseType_t; 57 | typedef unsigned long UBaseType_t; 58 | 59 | #if( configUSE_16_BIT_TICKS == 1 ) 60 | typedef uint16_t TickType_t; 61 | #define portMAX_DELAY ( TickType_t ) 0xffff 62 | #else 63 | typedef uint32_t TickType_t; 64 | #define portMAX_DELAY ( TickType_t ) 0xffffffffUL 65 | 66 | /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do 67 | not need to be guarded with a critical section. */ 68 | #define portTICK_TYPE_IS_ATOMIC 1 69 | #endif 70 | /*-----------------------------------------------------------*/ 71 | 72 | /* Architecture specifics. */ 73 | #define portSTACK_GROWTH ( -1 ) 74 | #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) 75 | #define portBYTE_ALIGNMENT 4 76 | /*-----------------------------------------------------------*/ 77 | 78 | /* Scheduler utilities. */ 79 | #define portYIELD() \ 80 | { \ 81 | /* Set a PendSV to request a context switch. */ \ 82 | portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ 83 | \ 84 | /* Barriers are normally not required but do ensure the code is completely \ 85 | within the specified behaviour for the architecture. */ \ 86 | __asm volatile( "dsb" ::: "memory" ); \ 87 | __asm volatile( "isb" ); \ 88 | } 89 | 90 | #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) 91 | #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) 92 | #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD() 93 | #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) 94 | /*-----------------------------------------------------------*/ 95 | 96 | /* Critical section management. */ 97 | extern void vPortEnterCritical( void ); 98 | extern void vPortExitCritical( void ); 99 | #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() 100 | #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x) 101 | #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() 102 | #define portENABLE_INTERRUPTS() vPortSetBASEPRI(0) 103 | #define portENTER_CRITICAL() vPortEnterCritical() 104 | #define portEXIT_CRITICAL() vPortExitCritical() 105 | 106 | 107 | /*-----------------------------------------------------------*/ 108 | 109 | /* Task function macros as described on the FreeRTOS.org WEB site. These are 110 | not necessary for to use this port. They are defined so the common demo files 111 | (which build with all the ports) will build. */ 112 | #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) 113 | #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) 114 | /*-----------------------------------------------------------*/ 115 | 116 | /* Tickless idle/low power functionality. */ 117 | #ifndef portSUPPRESS_TICKS_AND_SLEEP 118 | extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); 119 | #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) 120 | #endif 121 | /*-----------------------------------------------------------*/ 122 | 123 | /* Architecture specific optimisations. */ 124 | #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION 125 | #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 126 | #endif 127 | 128 | #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 129 | 130 | /* Generic helper function. */ 131 | __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) 132 | { 133 | uint8_t ucReturn; 134 | 135 | __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); 136 | return ucReturn; 137 | } 138 | 139 | /* Check the configuration. */ 140 | #if( configMAX_PRIORITIES > 32 ) 141 | #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. 142 | #endif 143 | 144 | /* Store/clear the ready priorities in a bit map. */ 145 | #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) 146 | #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) 147 | 148 | /*-----------------------------------------------------------*/ 149 | 150 | #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) 151 | 152 | #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ 153 | 154 | /*-----------------------------------------------------------*/ 155 | 156 | #ifdef configASSERT 157 | void vPortValidateInterruptPriority( void ); 158 | #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() 159 | #endif 160 | 161 | /* portNOP() is not required by this port. */ 162 | #define portNOP() 163 | 164 | #define portINLINE __inline 165 | 166 | #ifndef portFORCE_INLINE 167 | #define portFORCE_INLINE inline __attribute__(( always_inline)) 168 | #endif 169 | 170 | portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) 171 | { 172 | uint32_t ulCurrentInterrupt; 173 | BaseType_t xReturn; 174 | 175 | /* Obtain the number of the currently executing interrupt. */ 176 | __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" ); 177 | 178 | if( ulCurrentInterrupt == 0 ) 179 | { 180 | xReturn = pdFALSE; 181 | } 182 | else 183 | { 184 | xReturn = pdTRUE; 185 | } 186 | 187 | return xReturn; 188 | } 189 | 190 | /*-----------------------------------------------------------*/ 191 | 192 | portFORCE_INLINE static void vPortRaiseBASEPRI( void ) 193 | { 194 | uint32_t ulNewBASEPRI; 195 | 196 | __asm volatile 197 | ( 198 | " mov %0, %1 \n" \ 199 | " msr basepri, %0 \n" \ 200 | " isb \n" \ 201 | " dsb \n" \ 202 | :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" 203 | ); 204 | } 205 | 206 | /*-----------------------------------------------------------*/ 207 | 208 | portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) 209 | { 210 | uint32_t ulOriginalBASEPRI, ulNewBASEPRI; 211 | 212 | __asm volatile 213 | ( 214 | " mrs %0, basepri \n" \ 215 | " mov %1, %2 \n" \ 216 | " msr basepri, %1 \n" \ 217 | " isb \n" \ 218 | " dsb \n" \ 219 | :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" 220 | ); 221 | 222 | /* This return will not be reached but is necessary to prevent compiler 223 | warnings. */ 224 | return ulOriginalBASEPRI; 225 | } 226 | /*-----------------------------------------------------------*/ 227 | 228 | portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) 229 | { 230 | __asm volatile 231 | ( 232 | " msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory" 233 | ); 234 | } 235 | /*-----------------------------------------------------------*/ 236 | 237 | 238 | #ifdef __cplusplus 239 | } 240 | #endif 241 | 242 | #endif /* PORTMACRO_H */ 243 | 244 | -------------------------------------------------------------------------------- /src/projdefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.0 3 | * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef PROJDEFS_H 29 | #define PROJDEFS_H 30 | 31 | /* 32 | * Defines the prototype to which task functions must conform. Defined in this 33 | * file to ensure the type is known before portable.h is included. 34 | */ 35 | typedef void (*TaskFunction_t)( void * ); 36 | 37 | /* Converts a time in milliseconds to a time in ticks. This macro can be 38 | overridden by a macro of the same name defined in FreeRTOSConfig.h in case the 39 | definition here is not suitable for your application. */ 40 | #ifndef pdMS_TO_TICKS 41 | #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) 42 | #endif 43 | 44 | #define pdFALSE ( ( BaseType_t ) 0 ) 45 | #define pdTRUE ( ( BaseType_t ) 1 ) 46 | 47 | #define pdPASS ( pdTRUE ) 48 | #define pdFAIL ( pdFALSE ) 49 | #define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) 50 | #define errQUEUE_FULL ( ( BaseType_t ) 0 ) 51 | 52 | /* FreeRTOS error definitions. */ 53 | #define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) 54 | #define errQUEUE_BLOCKED ( -4 ) 55 | #define errQUEUE_YIELD ( -5 ) 56 | 57 | /* Macros used for basic data corruption checks. */ 58 | #ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 59 | #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 60 | #endif 61 | 62 | #if( configUSE_16_BIT_TICKS == 1 ) 63 | #define pdINTEGRITY_CHECK_VALUE 0x5a5a 64 | #else 65 | #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL 66 | #endif 67 | 68 | /* The following errno values are used by FreeRTOS+ components, not FreeRTOS 69 | itself. */ 70 | #define pdFREERTOS_ERRNO_NONE 0 /* No errors */ 71 | #define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ 72 | #define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ 73 | #define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ 74 | #define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ 75 | #define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ 76 | #define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ 77 | #define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ 78 | #define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ 79 | #define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ 80 | #define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ 81 | #define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ 82 | #define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ 83 | #define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ 84 | #define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ 85 | #define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ 86 | #define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ 87 | #define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ 88 | #define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ 89 | #define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ 90 | #define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ 91 | #define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ 92 | #define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ 93 | #define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ 94 | #define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ 95 | #define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ 96 | #define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ 97 | #define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ 98 | #define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ 99 | #define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ 100 | #define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ 101 | #define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ 102 | #define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ 103 | #define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ 104 | #define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ 105 | #define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ 106 | #define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ 107 | #define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ 108 | #define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ 109 | #define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ 110 | 111 | /* The following endian values are used by FreeRTOS+ components, not FreeRTOS 112 | itself. */ 113 | #define pdFREERTOS_LITTLE_ENDIAN 0 114 | #define pdFREERTOS_BIG_ENDIAN 1 115 | 116 | /* Re-defining endian values for generic naming. */ 117 | #define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN 118 | #define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN 119 | 120 | 121 | #endif /* PROJDEFS_H */ 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /src/stack_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.0 3 | * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef STACK_MACROS_H 29 | #define STACK_MACROS_H 30 | 31 | /* 32 | * Call the stack overflow hook function if the stack of the task being swapped 33 | * out is currently overflowed, or looks like it might have overflowed in the 34 | * past. 35 | * 36 | * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check 37 | * the current stack state only - comparing the current top of stack value to 38 | * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 39 | * will also cause the last few stack bytes to be checked to ensure the value 40 | * to which the bytes were set when the task was created have not been 41 | * overwritten. Note this second test does not guarantee that an overflowed 42 | * stack will always be recognised. 43 | */ 44 | 45 | /*-----------------------------------------------------------*/ 46 | 47 | #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) 48 | 49 | /* Only the current stack state is to be checked. */ 50 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 51 | { \ 52 | /* Is the currently saved stack pointer within the stack limit? */ \ 53 | if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ 54 | { \ 55 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 56 | } \ 57 | } 58 | 59 | #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ 60 | /*-----------------------------------------------------------*/ 61 | 62 | #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) 63 | 64 | /* Only the current stack state is to be checked. */ 65 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 66 | { \ 67 | \ 68 | /* Is the currently saved stack pointer within the stack limit? */ \ 69 | if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ 70 | { \ 71 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 72 | } \ 73 | } 74 | 75 | #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ 76 | /*-----------------------------------------------------------*/ 77 | 78 | #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) 79 | 80 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 81 | { \ 82 | const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ 83 | const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ 84 | \ 85 | if( ( pulStack[ 0 ] != ulCheckValue ) || \ 86 | ( pulStack[ 1 ] != ulCheckValue ) || \ 87 | ( pulStack[ 2 ] != ulCheckValue ) || \ 88 | ( pulStack[ 3 ] != ulCheckValue ) ) \ 89 | { \ 90 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 91 | } \ 92 | } 93 | 94 | #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 95 | /*-----------------------------------------------------------*/ 96 | 97 | #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) 98 | 99 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 100 | { \ 101 | int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ 102 | static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 103 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 104 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 105 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 106 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ 107 | \ 108 | \ 109 | pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ 110 | \ 111 | /* Has the extremity of the task stack ever been written over? */ \ 112 | if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ 113 | { \ 114 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 115 | } \ 116 | } 117 | 118 | #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 119 | /*-----------------------------------------------------------*/ 120 | 121 | /* Remove stack overflow macro if not being used. */ 122 | #ifndef taskCHECK_FOR_STACK_OVERFLOW 123 | #define taskCHECK_FOR_STACK_OVERFLOW() 124 | #endif 125 | 126 | 127 | 128 | #endif /* STACK_MACROS_H */ 129 | 130 | -------------------------------------------------------------------------------- /src/threading_alt.h: -------------------------------------------------------------------------------- 1 | #ifndef __THREADING_ALT_H__ 2 | #define __THREADING_ALT_H__ 3 | 4 | 5 | #include "FreeRTOS.h" 6 | #include "semphr.h" 7 | 8 | typedef struct 9 | { 10 | SemaphoreHandle_t mutex; 11 | char is_valid; 12 | } mbedtls_threading_mutex_t; 13 | 14 | extern void mbedtls_threading_set_alt( void ( * mutex_init )( mbedtls_threading_mutex_t * ), 15 | void ( * mutex_free )( mbedtls_threading_mutex_t * ), 16 | int ( * mutex_lock )( mbedtls_threading_mutex_t * ), 17 | int ( * mutex_unlock )( mbedtls_threading_mutex_t * ) ); 18 | 19 | 20 | #endif /* ifndef __THREADING_ALT_H__ */ 21 | --------------------------------------------------------------------------------