├── README.md ├── examples ├── Basic_RTOS_Example │ └── Basic_RTOS_Example.ino ├── Basic_RTOS_Example2 │ └── Basic_RTOS_Example2.ino ├── CompilerAndLinker_Test │ ├── CompilerAndLinker_Test.ino │ ├── GameData.cpp │ ├── GameData.h │ ├── GameMessage.cpp │ ├── GameMessage.h │ ├── GameThing.c │ └── GameThing.h ├── GpioInterrupt_Test │ └── GpioInterrupt_Test.ino ├── RtosCrash_Test │ └── RtosCrash_Test.ino └── TaskLoad_RTOS_Example │ └── TaskLoad_RTOS_Example.ino ├── library.properties ├── src ├── FreeRTOS.h ├── FreeRTOSConfig.h ├── FreeRTOS_SAMD51.h ├── croutine.c ├── croutine.h ├── deprecated_definitions.h ├── error_hooks.cpp ├── error_hooks.h ├── event_groups.c ├── event_groups.h ├── heap_4bis.c ├── idle_hook.c ├── list.c ├── list.h ├── message_buffer.h ├── mpu_prototypes.h ├── mpu_wrappers.h ├── port.c ├── portable.h ├── portmacro.h ├── projdefs.h ├── queue.c ├── queue.h ├── runTimeStats_hooks.c ├── runTimeStats_hooks.h ├── semphr.h ├── stack_macros.h ├── stdint.readme ├── stream_buffer.c ├── stream_buffer.h ├── task.h ├── tasks.c ├── timers.c └── timers.h └── wrapping memory functions └── platform.local.txt /README.md: -------------------------------------------------------------------------------- 1 | ### FreeRTOS V10.2.1 for Arduino Samd51 Boards 2 | 3 | #### This library will allow you to create FreeRtos Projects in the arduino IDE and run them on your Samd51 boards. 4 | 5 | Want FreeRtos for the Samd21? Use this other repository 6 | https://github.com/BriscoeTech/Arduino-FreeRTOS-SAMD21 7 | 8 | *************************************************************************************************************** 9 | #### Tested Boards: 10 | Adafruit Metro M4 Express 11 | *************************************************************************************************************** 12 | 13 | #### Whats new in the recent versions? 14 | 15 | * Added and updated example projects with lessons learned to help you get started setting up a new project. 16 | * Added optional serial printing when the rtos fails, makes tracking down and diagnosing project problems easier. 17 | * Added example project demonstrating the most common rtos failures, and how you might detect them. 18 | * Added example project showing how to change Arduino interrupt priorities to use FreeRtos isr functions. 19 | 20 | *************************************************************************************************************** 21 | 22 | #### Optional Feature: Wrapped Memmory Functions. 23 | 24 | This linker setting change will allow all microcontroller malloc/free/realloc/calloc 25 | operations to be managed by FreeRtos. This could eliminate memory corruption issues on 26 | c++ intensive projects, or projects that might be fragmenting the heap. 27 | 28 | Implementation Guide can be found in: "wrapping memory functions\platform.local.txt" 29 | 30 | *************************************************************************************************************** 31 | 32 | Special thanks to these people for your help and guidance, reference material, and hard work on contributions. 33 | 34 | Richard Barry, for creating FreeRtos and sharing it with the world 35 | www.FreeRtos.org 36 | trlafleur 37 | drewfish 38 | baekgaard 39 | sergiotomasello 40 | godario 41 | TomasRoj 42 | feilipu 43 | greiman -------------------------------------------------------------------------------- /examples/Basic_RTOS_Example/Basic_RTOS_Example.ino: -------------------------------------------------------------------------------- 1 | //************************************************************************** 2 | // FreeRtos on Samd51 3 | // By Scott Briscoe 4 | // 5 | // Project is a simple example of how to get FreeRtos running on a SamD51 processor 6 | // Project can be used as a template to build your projects off of as well 7 | // 8 | //************************************************************************** 9 | 10 | #include 11 | 12 | //************************************************************************** 13 | // Type Defines and Constants 14 | //************************************************************************** 15 | 16 | #define ERROR_LED_PIN 13 //Led Pin: Typical Arduino Board 17 | //#define ERROR_LED_PIN 2 //Led Pin: samd21 xplained board 18 | 19 | #define ERROR_LED_LIGHTUP_STATE HIGH // the state that makes the led light up on your board, either low or high 20 | 21 | // Select the serial port the project should use and communicate over 22 | // Some boards use SerialUSB, some use Serial 23 | //#define SERIAL SerialUSB //Sparkfun Samd51 Boards 24 | #define SERIAL Serial //Adafruit, other Samd51 Boards 25 | 26 | //************************************************************************** 27 | // global variables 28 | //************************************************************************** 29 | TaskHandle_t Handle_aTask; 30 | TaskHandle_t Handle_bTask; 31 | TaskHandle_t Handle_monitorTask; 32 | 33 | //************************************************************************** 34 | // Can use these function for RTOS delays 35 | // Takes into account processor speed 36 | // Use these instead of delay(...) in rtos tasks 37 | //************************************************************************** 38 | void myDelayUs(int us) 39 | { 40 | vTaskDelay( us / portTICK_PERIOD_US ); 41 | } 42 | 43 | void myDelayMs(int ms) 44 | { 45 | vTaskDelay( (ms * 1000) / portTICK_PERIOD_US ); 46 | } 47 | 48 | void myDelayMsUntil(TickType_t *previousWakeTime, int ms) 49 | { 50 | vTaskDelayUntil( previousWakeTime, (ms * 1000) / portTICK_PERIOD_US ); 51 | } 52 | 53 | //***************************************************************** 54 | // Create a thread that prints out A to the screen every two seconds 55 | // this task will delete its self after printing out afew messages 56 | //***************************************************************** 57 | static void threadA( void *pvParameters ) 58 | { 59 | 60 | SERIAL.println("Thread A: Started"); 61 | for(int x=0; x<100; ++x) 62 | { 63 | SERIAL.print("A"); 64 | SERIAL.flush(); 65 | myDelayMs(500); 66 | } 67 | 68 | // delete ourselves. 69 | // Have to call this or the system crashes when you reach the end bracket and then get scheduled. 70 | SERIAL.println("Thread A: Deleting"); 71 | vTaskDelete( NULL ); 72 | } 73 | 74 | //***************************************************************** 75 | // Create a thread that prints out B to the screen every second 76 | // this task will run forever 77 | //***************************************************************** 78 | static void threadB( void *pvParameters ) 79 | { 80 | SERIAL.println("Thread B: Started"); 81 | 82 | while(1) 83 | { 84 | SERIAL.println("B"); 85 | SERIAL.flush(); 86 | myDelayMs(2000); 87 | } 88 | 89 | } 90 | 91 | //***************************************************************** 92 | // Task will periodically print out useful information about the tasks running 93 | // Is a useful tool to help figure out stack sizes being used 94 | // Run time stats are generated from all task timing collected since startup 95 | // No easy way yet to clear the run time stats yet 96 | //***************************************************************** 97 | static char ptrTaskList[400]; //temporary string buffer for task stats 98 | 99 | void taskMonitor(void *pvParameters) 100 | { 101 | int x; 102 | int measurement; 103 | 104 | SERIAL.println("Task Monitor: Started"); 105 | 106 | // run this task afew times before exiting forever 107 | while(1) 108 | { 109 | myDelayMs(10000); // print every 10 seconds 110 | 111 | SERIAL.flush(); 112 | SERIAL.println(""); 113 | SERIAL.println("****************************************************"); 114 | SERIAL.print("Free Heap: "); 115 | SERIAL.print(xPortGetFreeHeapSize()); 116 | SERIAL.println(" bytes"); 117 | 118 | SERIAL.print("Min Heap: "); 119 | SERIAL.print(xPortGetMinimumEverFreeHeapSize()); 120 | SERIAL.println(" bytes"); 121 | SERIAL.flush(); 122 | 123 | SERIAL.println("****************************************************"); 124 | SERIAL.println("Task ABS %Util"); 125 | SERIAL.println("****************************************************"); 126 | 127 | vTaskGetRunTimeStats(ptrTaskList); //save stats to char array 128 | SERIAL.println(ptrTaskList); //prints out already formatted stats 129 | SERIAL.flush(); 130 | 131 | SERIAL.println("****************************************************"); 132 | SERIAL.println("Task State Prio Stack Num Core" ); 133 | SERIAL.println("****************************************************"); 134 | 135 | vTaskList(ptrTaskList); //save stats to char array 136 | SERIAL.println(ptrTaskList); //prints out already formatted stats 137 | SERIAL.flush(); 138 | 139 | SERIAL.println("****************************************************"); 140 | SERIAL.println("[Stacks Free Bytes Remaining] "); 141 | 142 | measurement = uxTaskGetStackHighWaterMark( Handle_aTask ); 143 | SERIAL.print("Thread A: "); 144 | SERIAL.println(measurement); 145 | 146 | measurement = uxTaskGetStackHighWaterMark( Handle_bTask ); 147 | SERIAL.print("Thread B: "); 148 | SERIAL.println(measurement); 149 | 150 | measurement = uxTaskGetStackHighWaterMark( Handle_monitorTask ); 151 | SERIAL.print("Monitor Stack: "); 152 | SERIAL.println(measurement); 153 | 154 | SERIAL.println("****************************************************"); 155 | SERIAL.flush(); 156 | 157 | } 158 | 159 | // delete ourselves. 160 | // Have to call this or the system crashes when you reach the end bracket and then get scheduled. 161 | SERIAL.println("Task Monitor: Deleting"); 162 | vTaskDelete( NULL ); 163 | 164 | } 165 | 166 | 167 | //***************************************************************** 168 | 169 | void setup() 170 | { 171 | 172 | SERIAL.begin(115200); 173 | 174 | delay(1000); // prevents usb driver crash on startup, do not omit this 175 | while (!SERIAL) ; // Wait for serial terminal to open port before starting program 176 | 177 | SERIAL.println(""); 178 | SERIAL.println("******************************"); 179 | SERIAL.println(" Program start "); 180 | SERIAL.println("******************************"); 181 | SERIAL.flush(); 182 | 183 | // Set the led the rtos will blink when we have a fatal rtos error 184 | // RTOS also Needs to know if high/low is the state that turns on the led. 185 | // Error Blink Codes: 186 | // 3 blinks - Fatal Rtos Error, something bad happened. Think really hard about what you just changed. 187 | // 2 blinks - Malloc Failed, Happens when you couldn't create a rtos object. 188 | // Probably ran out of heap. 189 | // 1 blink - Stack overflow, Task needs more bytes defined for its stack! 190 | // Use the taskMonitor thread to help gauge how much more you need 191 | vSetErrorLed(ERROR_LED_PIN, ERROR_LED_LIGHTUP_STATE); 192 | 193 | // sets the serial port to print errors to when the rtos crashes 194 | // if this is not set, serial information is not printed by default 195 | vSetErrorSerial(&SERIAL); 196 | 197 | // Create the threads that will be managed by the rtos 198 | // Sets the stack size and priority of each task 199 | // Also initializes a handler pointer to each task, which are important to communicate with and retrieve info from tasks 200 | xTaskCreate(threadA, "Task A", 256, NULL, tskIDLE_PRIORITY + 3, &Handle_aTask); 201 | xTaskCreate(threadB, "Task B", 256, NULL, tskIDLE_PRIORITY + 2, &Handle_bTask); 202 | xTaskCreate(taskMonitor, "Task Monitor", 256, NULL, tskIDLE_PRIORITY + 1, &Handle_monitorTask); 203 | 204 | // Start the RTOS, this function will never return and will schedule the tasks. 205 | vTaskStartScheduler(); 206 | 207 | // error scheduler failed to start 208 | // should never get here 209 | while(1) 210 | { 211 | SERIAL.println("Scheduler Failed! \n"); 212 | SERIAL.flush(); 213 | delay(1000); 214 | } 215 | 216 | } 217 | 218 | //***************************************************************** 219 | // This is now the rtos idle loop 220 | // No rtos blocking functions allowed! 221 | //***************************************************************** 222 | void loop() 223 | { 224 | // Optional commands, can comment/uncomment below 225 | SERIAL.print("."); //print out dots in terminal, we only do this when the RTOS is in the idle state 226 | SERIAL.flush(); 227 | delay(100); //delay is interrupt friendly, unlike vNopDelayMS 228 | } 229 | 230 | 231 | //***************************************************************** 232 | 233 | -------------------------------------------------------------------------------- /examples/Basic_RTOS_Example2/Basic_RTOS_Example2.ino: -------------------------------------------------------------------------------- 1 | //************************************************************************** 2 | // FreeRtos on Samd51 3 | // By Scott Briscoe 4 | // 5 | // Project is a simple example of how to get FreeRtos running on a SamD51 processor 6 | // Project can be used as a template to build your projects off of as well 7 | // 8 | // This example uses the MemoryFree library by mpflaga, to show how much ram is being used by the rtos and all global objects 9 | // https://github.com/mpflaga/Arduino-MemoryFree 10 | //************************************************************************** 11 | 12 | #include //samd51 13 | #include 14 | 15 | //************************************************************************** 16 | // Type Defines and Constants 17 | //************************************************************************** 18 | 19 | #define ERROR_LED_PIN 13 //Led Pin: Typical Arduino Board 20 | //#define ERROR_LED_PIN 2 //Led Pin: samd21 xplained board 21 | 22 | #define ERROR_LED_LIGHTUP_STATE HIGH // the state that makes the led light up on your board, either low or high 23 | 24 | #define DEVICE_TOTAL_RAM 192000 // bytes of ram for this processor 25 | 26 | // Select the serial port the project should use and communicate over 27 | // Some boards use SerialUSB, some use Serial 28 | //#define SERIAL SerialUSB //Sparkfun Samd21 Boards 29 | #define SERIAL Serial //Adafruit, other Samd21 Boards 30 | 31 | //************************************************************************** 32 | // global variables 33 | //************************************************************************** 34 | TaskHandle_t Handle_aTask; 35 | TaskHandle_t Handle_bTask; 36 | TaskHandle_t Handle_monitorTask; 37 | 38 | //************************************************************************** 39 | // Can use these function for RTOS delays 40 | // Takes into account processor speed 41 | // Use these instead of delay(...) in rtos tasks 42 | //************************************************************************** 43 | void myDelayUs(int us) 44 | { 45 | vTaskDelay( us / portTICK_PERIOD_US ); 46 | } 47 | 48 | void myDelayMs(int ms) 49 | { 50 | vTaskDelay( (ms * 1000) / portTICK_PERIOD_US ); 51 | } 52 | 53 | void myDelayMsUntil(TickType_t *previousWakeTime, int ms) 54 | { 55 | vTaskDelayUntil( previousWakeTime, (ms * 1000) / portTICK_PERIOD_US ); 56 | } 57 | 58 | //************************************************************************** 59 | // Print how much ram is free on the device 60 | // Useful to see how much ram is available at startup with current heap size settings, and after initializing all classes 61 | // freeMemory() gives wrong answers after starting the rtos for unknown reasons, only use before rtos start 62 | //************************************************************************** 63 | void printRamFree() 64 | { 65 | SERIAL.print("Ram Remaining : ("); 66 | SERIAL.print( freeMemory() ); 67 | SERIAL.print(" / "); 68 | SERIAL.print(DEVICE_TOTAL_RAM); 69 | SERIAL.print(") bytes "); 70 | double percentage = ((double)freeMemory() / (double)DEVICE_TOTAL_RAM) * 100; 71 | SERIAL.print( percentage ); 72 | SERIAL.println("%"); 73 | SERIAL.flush(); 74 | } 75 | 76 | //***************************************************************** 77 | // Create a thread that prints out A to the screen every two seconds 78 | // this task will delete its self after printing out afew messages 79 | //***************************************************************** 80 | static void threadA( void *pvParameters ) 81 | { 82 | 83 | SERIAL.println("Thread A: Started"); 84 | for(int x=0; x<20; ++x) 85 | { 86 | SERIAL.print("A"); 87 | SERIAL.flush(); 88 | myDelayMs(500); 89 | } 90 | 91 | // delete ourselves. 92 | // Have to call this or the system crashes when you reach the end bracket and then get scheduled. 93 | SERIAL.println("Thread A: Deleting"); 94 | vTaskDelete( NULL ); 95 | } 96 | 97 | //***************************************************************** 98 | // Create a thread that prints out B to the screen every second 99 | // this task will run forever 100 | //***************************************************************** 101 | static void threadB( void *pvParameters ) 102 | { 103 | SERIAL.println("Thread B: Started"); 104 | 105 | while(1) 106 | { 107 | SERIAL.println("B"); 108 | SERIAL.flush(); 109 | myDelayMs(2000); 110 | } 111 | 112 | } 113 | 114 | //***************************************************************** 115 | // Task will periodically print out useful information about the tasks running 116 | // Is a useful tool to help figure out stack sizes being used 117 | // Run time stats are generated from all task timing collected since startup 118 | // No easy way yet to clear the run time stats yet 119 | //***************************************************************** 120 | static char ptrTaskList[400]; //temporary string buffer for task stats 121 | 122 | void taskMonitor(void *pvParameters) 123 | { 124 | int x; 125 | int measurement; 126 | 127 | SERIAL.println("Task Monitor: Started"); 128 | 129 | // run this task afew times before exiting forever 130 | for(x=0; x<10; ++x) 131 | { 132 | 133 | SERIAL.flush(); 134 | SERIAL.println(""); 135 | SERIAL.println("****************************************************"); 136 | SERIAL.print("Free Heap: "); 137 | SERIAL.print(xPortGetFreeHeapSize()); 138 | SERIAL.println(" bytes"); 139 | 140 | SERIAL.print("Min Heap: "); 141 | SERIAL.print(xPortGetMinimumEverFreeHeapSize()); 142 | SERIAL.println(" bytes"); 143 | SERIAL.flush(); 144 | 145 | SERIAL.println("****************************************************"); 146 | SERIAL.println("Task ABS %Util"); 147 | SERIAL.println("****************************************************"); 148 | 149 | vTaskGetRunTimeStats(ptrTaskList); //save stats to char array 150 | SERIAL.println(ptrTaskList); //prints out already formatted stats 151 | SERIAL.flush(); 152 | 153 | SERIAL.println("****************************************************"); 154 | SERIAL.println("Task State Prio Stack Num Core" ); 155 | SERIAL.println("****************************************************"); 156 | 157 | vTaskList(ptrTaskList); //save stats to char array 158 | SERIAL.println(ptrTaskList); //prints out already formatted stats 159 | SERIAL.flush(); 160 | 161 | SERIAL.println("****************************************************"); 162 | SERIAL.println("[Stacks Free Bytes Remaining] "); 163 | 164 | measurement = uxTaskGetStackHighWaterMark( Handle_aTask ); 165 | SERIAL.print("Thread A: "); 166 | SERIAL.println(measurement); 167 | 168 | measurement = uxTaskGetStackHighWaterMark( Handle_bTask ); 169 | SERIAL.print("Thread B: "); 170 | SERIAL.println(measurement); 171 | 172 | measurement = uxTaskGetStackHighWaterMark( Handle_monitorTask ); 173 | SERIAL.print("Monitor Stack: "); 174 | SERIAL.println(measurement); 175 | 176 | SERIAL.println("****************************************************"); 177 | SERIAL.flush(); 178 | 179 | myDelayMs(10000); // print every 10 seconds 180 | } 181 | 182 | // delete ourselves. 183 | // Have to call this or the system crashes when you reach the end bracket and then get scheduled. 184 | SERIAL.println("Task Monitor: Deleting"); 185 | vTaskDelete( NULL ); 186 | 187 | } 188 | 189 | 190 | //***************************************************************** 191 | 192 | void setup() 193 | { 194 | 195 | SERIAL.begin(115200); 196 | 197 | delay(1000); // prevents usb driver crash on startup, do not omit this 198 | while (!SERIAL) ; // Wait for serial terminal to open port before starting program 199 | 200 | // show the amount of ram free at startup 201 | printRamFree(); 202 | 203 | SERIAL.println(""); 204 | SERIAL.println("******************************"); 205 | SERIAL.println(" Program start "); 206 | SERIAL.println("******************************"); 207 | SERIAL.flush(); 208 | 209 | // Set the led the rtos will blink when we have a fatal rtos error 210 | // RTOS also Needs to know if high/low is the state that turns on the led. 211 | // Error Blink Codes: 212 | // 3 blinks - Fatal Rtos Error, something bad happened. Think really hard about what you just changed. 213 | // 2 blinks - Malloc Failed, Happens when you couldn't create a rtos object. 214 | // Probably ran out of heap. 215 | // 1 blink - Stack overflow, Task needs more bytes defined for its stack! 216 | // Use the taskMonitor thread to help gauge how much more you need 217 | vSetErrorLed(ERROR_LED_PIN, ERROR_LED_LIGHTUP_STATE); 218 | 219 | // sets the serial port to print errors to when the rtos crashes 220 | // if this is not set, serial information is not printed by default 221 | vSetErrorSerial(&SERIAL); 222 | 223 | // Create the threads that will be managed by the rtos 224 | // Sets the stack size and priority of each task 225 | // Also initializes a handler pointer to each task, which are important to communicate with and retrieve info from tasks 226 | xTaskCreate(threadA, "Task A", 256, NULL, tskIDLE_PRIORITY + 3, &Handle_aTask); 227 | xTaskCreate(threadB, "Task B", 256, NULL, tskIDLE_PRIORITY + 2, &Handle_bTask); 228 | xTaskCreate(taskMonitor, "Task Monitor", 256, NULL, tskIDLE_PRIORITY + 1, &Handle_monitorTask); 229 | 230 | // show the amount of ram free after initializations 231 | printRamFree(); 232 | 233 | // Start the RTOS, this function will never return and will schedule the tasks. 234 | vTaskStartScheduler(); 235 | 236 | // error scheduler failed to start 237 | // should never get here 238 | while(1) 239 | { 240 | SERIAL.println("Scheduler Failed! \n"); 241 | SERIAL.flush(); 242 | delay(1000); 243 | } 244 | 245 | } 246 | 247 | //***************************************************************** 248 | // This is now the rtos idle loop 249 | // No rtos blocking functions allowed! 250 | //***************************************************************** 251 | void loop() 252 | { 253 | // Optional commands, can comment/uncomment below 254 | SERIAL.print("."); //print out dots in terminal, we only do this when the RTOS is in the idle state 255 | SERIAL.flush(); 256 | delay(100); //delay is interrupt friendly, unlike vNopDelayMS 257 | } 258 | 259 | 260 | //***************************************************************** 261 | 262 | -------------------------------------------------------------------------------- /examples/CompilerAndLinker_Test/CompilerAndLinker_Test.ino: -------------------------------------------------------------------------------- 1 | 2 | // External Libraries 3 | #include //samd51 4 | 5 | #include "GameMessage.h" 6 | #include "GameData.h" 7 | #include "GameThing.c" 8 | 9 | 10 | // This example project tests that a .ino, c header, or cpp header can include and compile the library 11 | // Keeping this example around to make sure that any library architecture changes will still compile in a arduino project 12 | // Found a obscure compiling error that would occur if the librarys header file did not include the arduino library explicitly 13 | // Also useful to make sure rtos C code is not trying to include Cpp arduino functions 14 | 15 | 16 | //************************************************************************** 17 | void setup() 18 | { 19 | 20 | } 21 | 22 | 23 | //************************************************************************** 24 | void loop() 25 | { 26 | 27 | } 28 | 29 | -------------------------------------------------------------------------------- /examples/CompilerAndLinker_Test/GameData.cpp: -------------------------------------------------------------------------------- 1 | #include "GameData.h" // include this classes header file 2 | 3 | -------------------------------------------------------------------------------- /examples/CompilerAndLinker_Test/GameData.h: -------------------------------------------------------------------------------- 1 | #include //samd51 2 | 3 | 4 | #ifndef GAME_DATA_H 5 | #define GAME_DATA_H 6 | 7 | 8 | 9 | 10 | #endif 11 | 12 | -------------------------------------------------------------------------------- /examples/CompilerAndLinker_Test/GameMessage.cpp: -------------------------------------------------------------------------------- 1 | #include "GameMessage.h" // include this classes header file 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/CompilerAndLinker_Test/GameMessage.h: -------------------------------------------------------------------------------- 1 | 2 | // include the other header files to make this class work 3 | #include //samd51 4 | #include "GameData.h" 5 | 6 | 7 | #ifndef GAME_MESSAGE_H 8 | #define GAME_MESSAGE_H 9 | 10 | 11 | 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /examples/CompilerAndLinker_Test/GameThing.c: -------------------------------------------------------------------------------- 1 | #include "GameThing.h" // include this files header file 2 | -------------------------------------------------------------------------------- /examples/CompilerAndLinker_Test/GameThing.h: -------------------------------------------------------------------------------- 1 | #include //samd51 2 | 3 | #ifndef GAME_THING_H 4 | #define GAME_THING_H 5 | 6 | 7 | 8 | 9 | #endif 10 | 11 | -------------------------------------------------------------------------------- /examples/GpioInterrupt_Test/GpioInterrupt_Test.ino: -------------------------------------------------------------------------------- 1 | //************************************************************************** 2 | // FreeRtos on Samd51 3 | // By Scott Briscoe 4 | // 5 | // Project is a simple example of how to get FreeRtos running on a SamD51 processor 6 | // Project can be used as a template to build your projects off of as well 7 | // 8 | // This projects sets up a external gpio interrupt to send task messages to a task 9 | // 10 | //************************************************************************** 11 | 12 | #include 13 | 14 | //************************************************************************** 15 | // Type Defines and Constants 16 | //************************************************************************** 17 | 18 | #define ERROR_LED_PIN 13 //Led Pin: Typical Arduino Board 19 | //#define ERROR_LED_PIN 2 //Led Pin: samd21 xplained board 20 | 21 | #define BUTTON_PIN 9 22 | #define BUTTON_PIN_IRQ EIC_4_IRQn //irq number for pin 9 interrupt. Refer to samd51j19a.h and variant.cpp to find correct enum 23 | 24 | #define ERROR_LED_LIGHTUP_STATE HIGH // the state that makes the led light up on your board, either low or high 25 | 26 | // Select the serial port the project should use and communicate over 27 | // Some boards use SerialUSB, some use Serial 28 | //#define SERIAL SerialUSB //Sparkfun Samd51 Boards 29 | #define SERIAL Serial //Adafruit, other Samd51 Boards 30 | 31 | //************************************************************************** 32 | // global variables 33 | //************************************************************************** 34 | TaskHandle_t Handle_aTask; 35 | TaskHandle_t Handle_bTask; 36 | TaskHandle_t Handle_monitorTask; 37 | 38 | //************************************************************************** 39 | // Can use these function for RTOS delays 40 | // Takes into account processor speed 41 | // Use these instead of delay(...) in rtos tasks 42 | //************************************************************************** 43 | void myDelayUs(int us) 44 | { 45 | vTaskDelay( us / portTICK_PERIOD_US ); 46 | } 47 | 48 | void myDelayMs(int ms) 49 | { 50 | vTaskDelay( (ms * 1000) / portTICK_PERIOD_US ); 51 | } 52 | 53 | void myDelayMsUntil(TickType_t *previousWakeTime, int ms) 54 | { 55 | vTaskDelayUntil( previousWakeTime, (ms * 1000) / portTICK_PERIOD_US ); 56 | } 57 | 58 | //***************************************************************** 59 | // Create a thread that prints out A to the screen 60 | //***************************************************************** 61 | static void threadA( void *pvParameters ) 62 | { 63 | 64 | SERIAL.println("Thread A: Started"); 65 | while(1) 66 | { 67 | SERIAL.println("A"); 68 | SERIAL.flush(); 69 | myDelayMs(2000); 70 | } 71 | } 72 | 73 | //************************************************************************** 74 | // interrupt handler function 75 | //************************************************************************** 76 | 77 | //#define ENABLE_DEBUG_OUTPUT_ISR 78 | 79 | void Interrupt_MyHandler_IRQ() 80 | { 81 | 82 | #ifdef ENABLE_DEBUG_OUTPUT_ISR 83 | SERIAL.print(F("[")); 84 | #endif 85 | 86 | BaseType_t xHigherPriorityTaskWoken = pdFALSE; 87 | 88 | // release task to handle the radios read data 89 | vTaskNotifyGiveFromISR( Handle_bTask, &xHigherPriorityTaskWoken ); 90 | portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); 91 | 92 | #ifdef ENABLE_DEBUG_OUTPUT_ISR 93 | SERIAL.print(F("]")); 94 | SERIAL.flush(); 95 | #endif 96 | 97 | } 98 | 99 | //***************************************************************** 100 | // Create a thread that prints out B when we receive a gpio interrupt 101 | // this task will run forever 102 | //***************************************************************** 103 | 104 | #include "wiring_private.h" //for NVIC_SetPriority function 105 | 106 | static void threadB( void *pvParameters ) 107 | { 108 | SERIAL.println("Thread B: Started"); 109 | 110 | // setup the hardware as a input to listen to 111 | pinMode(BUTTON_PIN, INPUT_PULLUP); 112 | attachInterrupt( BUTTON_PIN, Interrupt_MyHandler_IRQ, FALLING ); 113 | 114 | // change the interrupt priority, this is required to prevent freertos assert and rtos problems 115 | // https://www.freertos.org/RTOS-Cortex-M3-M4.html 116 | // arduino default priority is zero, and freertos does not allow zero priority interrupts to use isr messages 117 | // do this after attaching interrupt 118 | NVIC_SetPriority(BUTTON_PIN_IRQ, configLIBRARY_LOWEST_INTERRUPT_PRIORITY); 119 | 120 | while(1) 121 | { 122 | 123 | // wait for a interrupt to release the task 124 | while (ulTaskNotifyTake( pdTRUE, portMAX_DELAY ) != pdPASS) 125 | { 126 | // do nothing 127 | } 128 | 129 | SERIAL.print("B"); 130 | SERIAL.flush(); 131 | 132 | //myDelayMs(200); // help debounce the interrupt handling 133 | } 134 | 135 | } 136 | 137 | //***************************************************************** 138 | // Task will periodically print out useful information about the tasks running 139 | // Is a useful tool to help figure out stack sizes being used 140 | // Run time stats are generated from all task timing collected since startup 141 | // No easy way yet to clear the run time stats yet 142 | //***************************************************************** 143 | static char ptrTaskList[400]; //temporary string buffer for task stats 144 | 145 | void taskMonitor(void *pvParameters) 146 | { 147 | int x; 148 | int measurement; 149 | 150 | SERIAL.println("Task Monitor: Started"); 151 | 152 | // run this task afew times before exiting forever 153 | while(1) 154 | { 155 | myDelayMs(10000); // print every 10 seconds 156 | 157 | SERIAL.flush(); 158 | SERIAL.println(""); 159 | SERIAL.println("****************************************************"); 160 | SERIAL.print("Free Heap: "); 161 | SERIAL.print(xPortGetFreeHeapSize()); 162 | SERIAL.println(" bytes"); 163 | 164 | SERIAL.print("Min Heap: "); 165 | SERIAL.print(xPortGetMinimumEverFreeHeapSize()); 166 | SERIAL.println(" bytes"); 167 | SERIAL.flush(); 168 | 169 | SERIAL.println("****************************************************"); 170 | SERIAL.println("Task ABS %Util"); 171 | SERIAL.println("****************************************************"); 172 | 173 | vTaskGetRunTimeStats(ptrTaskList); //save stats to char array 174 | SERIAL.println(ptrTaskList); //prints out already formatted stats 175 | SERIAL.flush(); 176 | 177 | SERIAL.println("****************************************************"); 178 | SERIAL.println("Task State Prio Stack Num Core" ); 179 | SERIAL.println("****************************************************"); 180 | 181 | vTaskList(ptrTaskList); //save stats to char array 182 | SERIAL.println(ptrTaskList); //prints out already formatted stats 183 | SERIAL.flush(); 184 | 185 | SERIAL.println("****************************************************"); 186 | SERIAL.println("[Stacks Free Bytes Remaining] "); 187 | 188 | measurement = uxTaskGetStackHighWaterMark( Handle_aTask ); 189 | SERIAL.print("Thread A: "); 190 | SERIAL.println(measurement); 191 | 192 | measurement = uxTaskGetStackHighWaterMark( Handle_bTask ); 193 | SERIAL.print("Thread B: "); 194 | SERIAL.println(measurement); 195 | 196 | measurement = uxTaskGetStackHighWaterMark( Handle_monitorTask ); 197 | SERIAL.print("Monitor Stack: "); 198 | SERIAL.println(measurement); 199 | 200 | SERIAL.println("****************************************************"); 201 | SERIAL.flush(); 202 | 203 | } 204 | 205 | // delete ourselves. 206 | // Have to call this or the system crashes when you reach the end bracket and then get scheduled. 207 | SERIAL.println("Task Monitor: Deleting"); 208 | vTaskDelete( NULL ); 209 | 210 | } 211 | 212 | 213 | //***************************************************************** 214 | 215 | void setup() 216 | { 217 | 218 | SERIAL.begin(115200); 219 | 220 | delay(1000); // prevents usb driver crash on startup, do not omit this 221 | while (!SERIAL) ; // Wait for serial terminal to open port before starting program 222 | 223 | SERIAL.println(""); 224 | SERIAL.println("******************************"); 225 | SERIAL.println(" Program start "); 226 | SERIAL.println("******************************"); 227 | SERIAL.flush(); 228 | 229 | // Set the led the rtos will blink when we have a fatal rtos error 230 | // RTOS also Needs to know if high/low is the state that turns on the led. 231 | // Error Blink Codes: 232 | // 3 blinks - Fatal Rtos Error, something bad happened. Think really hard about what you just changed. 233 | // 2 blinks - Malloc Failed, Happens when you couldn't create a rtos object. 234 | // Probably ran out of heap. 235 | // 1 blink - Stack overflow, Task needs more bytes defined for its stack! 236 | // Use the taskMonitor thread to help gauge how much more you need 237 | vSetErrorLed(ERROR_LED_PIN, ERROR_LED_LIGHTUP_STATE); 238 | 239 | // sets the serial port to print errors to when the rtos crashes 240 | // if this is not set, serial information is not printed by default 241 | vSetErrorSerial(&SERIAL); 242 | 243 | // Create the threads that will be managed by the rtos 244 | // Sets the stack size and priority of each task 245 | // Also initializes a handler pointer to each task, which are important to communicate with and retrieve info from tasks 246 | xTaskCreate(threadA, "Task A", 256, NULL, tskIDLE_PRIORITY + 3, &Handle_aTask); 247 | xTaskCreate(threadB, "Task B", 256, NULL, tskIDLE_PRIORITY + 2, &Handle_bTask); 248 | xTaskCreate(taskMonitor, "Task Monitor", 256, NULL, tskIDLE_PRIORITY + 1, &Handle_monitorTask); 249 | 250 | // Start the RTOS, this function will never return and will schedule the tasks. 251 | vTaskStartScheduler(); 252 | 253 | // error scheduler failed to start 254 | // should never get here 255 | while(1) 256 | { 257 | SERIAL.println("Scheduler Failed! \n"); 258 | SERIAL.flush(); 259 | delay(1000); 260 | } 261 | 262 | } 263 | 264 | //***************************************************************** 265 | // This is now the rtos idle loop 266 | // No rtos blocking functions allowed! 267 | //***************************************************************** 268 | void loop() 269 | { 270 | // Optional commands, can comment/uncomment below 271 | SERIAL.print("."); //print out dots in terminal, we only do this when the RTOS is in the idle state 272 | SERIAL.flush(); 273 | delay(100); //delay is interrupt friendly, unlike vNopDelayMS 274 | } 275 | 276 | 277 | //***************************************************************** 278 | 279 | -------------------------------------------------------------------------------- /examples/RtosCrash_Test/RtosCrash_Test.ino: -------------------------------------------------------------------------------- 1 | //************************************************************************** 2 | // FreeRtos on Samd51 3 | // By Scott Briscoe 4 | // 5 | // Project is a simple test to make sure the different rtos failure detections 6 | // are caught and the error led to blink properly. 7 | // 8 | // A great demo to also explore the common reasons the rtos crashes and how 9 | // to avoid them 10 | // 11 | //************************************************************************** 12 | 13 | #include 14 | 15 | //************************************************************************** 16 | // Type Defines and Constants 17 | //************************************************************************** 18 | 19 | // change this to cause different errors to be compiled and run 20 | #define ERROR_CHECKING 2 //0 for off, 1-6 to select failure mode to compile 21 | 22 | 23 | #define ERROR_LED_PIN 13 //Led Pin: Typical Arduino Board 24 | //#define ERROR_LED_PIN 2 //Led Pin: samd21 xplained board 25 | 26 | #define ERROR_LED_LIGHTUP_STATE HIGH // the state that makes the led light up on your board, either low or high 27 | 28 | // Select the serial port the project should use and communicate over 29 | // Some boards use SerialUSB, some use Serial 30 | //#define SERIAL SerialUSB //Sparkfun Samd51 Boards 31 | #define SERIAL Serial //Adafruit, other Samd51 Boards 32 | 33 | //************************************************************************** 34 | // global variables 35 | //************************************************************************** 36 | TaskHandle_t Handle_aTask; 37 | TaskHandle_t Handle_bTask; 38 | TaskHandle_t Handle_monitorTask; 39 | 40 | //************************************************************************** 41 | // Can use these function for RTOS delays 42 | // Takes into account processor speed 43 | // Use these instead of delay(...) in rtos tasks 44 | //************************************************************************** 45 | void myDelayUs(int us) 46 | { 47 | vTaskDelay( us / portTICK_PERIOD_US ); 48 | } 49 | 50 | void myDelayMs(int ms) 51 | { 52 | vTaskDelay( (ms * 1000) / portTICK_PERIOD_US ); 53 | } 54 | 55 | void myDelayMsUntil(TickType_t *previousWakeTime, int ms) 56 | { 57 | vTaskDelayUntil( previousWakeTime, (ms * 1000) / portTICK_PERIOD_US ); 58 | } 59 | 60 | 61 | #if ERROR_CHECKING == 2 62 | void endlessRecursion(int l) 63 | { 64 | int a[l]; 65 | long sum = 0; 66 | 67 | for(int x=0; x 11 | 12 | //************************************************************************** 13 | // Type Defines and Constants 14 | //************************************************************************** 15 | 16 | #define ERROR_LED_PIN 13 //Led Pin: Typical Arduino Board 17 | //#define ERROR_LED_PIN 2 //Led Pin: samd21 xplained board 18 | 19 | #define ERROR_LED_LIGHTUP_STATE HIGH // the state that makes the led light up on your board, either low or high 20 | 21 | // Select the serial port the project should use and communicate over 22 | // Some boards use SerialUSB, some use Serial 23 | //#define SERIAL SerialUSB //Sparkfun Samd51 Boards 24 | #define SERIAL Serial //Adafruit, other Samd51 Boards 25 | 26 | //************************************************************************** 27 | // global variables 28 | //************************************************************************** 29 | TaskHandle_t Handle_aTask; 30 | TaskHandle_t Handle_bTask; 31 | TaskHandle_t Handle_cTask; 32 | TaskHandle_t Handle_monitorTask; 33 | 34 | //************************************************************************** 35 | // Can use these function for RTOS delays 36 | // Takes into account processor speed 37 | // Use these instead of delay(...) in rtos tasks 38 | //************************************************************************** 39 | void myDelayUs(int us) 40 | { 41 | vTaskDelay( us / portTICK_PERIOD_US ); 42 | } 43 | 44 | void myDelayMs(int ms) 45 | { 46 | vTaskDelay( (ms * 1000) / portTICK_PERIOD_US ); 47 | } 48 | 49 | void myDelayMsUntil(TickType_t *previousWakeTime, int ms) 50 | { 51 | vTaskDelayUntil( previousWakeTime, (ms * 1000) / portTICK_PERIOD_US ); 52 | } 53 | 54 | //***************************************************************** 55 | // Create a thread that prints out A to the screen every two seconds 56 | // this task will delete its self after printing out afew messages 57 | //***************************************************************** 58 | static void threadA( void *pvParameters ) 59 | { 60 | 61 | SERIAL.println("Thread A: Started"); 62 | for(int x=0; x<100; ++x) 63 | { 64 | SERIAL.print("A"); 65 | SERIAL.flush(); 66 | myDelayMs(500); 67 | } 68 | 69 | // delete ourselves. 70 | // Have to call this or the system crashes when you reach the end bracket and then get scheduled. 71 | SERIAL.println("Thread A: Deleting"); 72 | vTaskDelete( NULL ); 73 | } 74 | 75 | //***************************************************************** 76 | // Create a thread that prints out B to the screen every second 77 | // this task will run forever 78 | //***************************************************************** 79 | static void threadB( void *pvParameters ) 80 | { 81 | SERIAL.println("Thread B: Started"); 82 | 83 | while(1) 84 | { 85 | SERIAL.println("B"); 86 | SERIAL.flush(); 87 | myDelayMs(2000); 88 | } 89 | 90 | } 91 | 92 | //***************************************************************** 93 | // Create a thread that just crunches alot of numbers 94 | // This thread should eat up a noticeable amount of processor time 95 | // this task will run forever 96 | //***************************************************************** 97 | volatile double variable; 98 | static void threadC( void *pvParameters ) 99 | { 100 | 101 | // Initialize the xLastWakeTime variable with the current time. 102 | TickType_t lastWakeTime = xTaskGetTickCount(); 103 | 104 | SERIAL.println("Thread C: Started"); 105 | 106 | while(1) 107 | { 108 | SERIAL.print("C"); 109 | SERIAL.flush(); 110 | 111 | // do some complicated math to fill up period 112 | // creates a duty cycle of processing 113 | for(long x=0; x<(50*32000); ++x) 114 | { 115 | variable *= PI; 116 | } 117 | 118 | // will sleep for the rest of this period window 119 | myDelayMsUntil(&lastWakeTime, 3100); 120 | } 121 | 122 | } 123 | 124 | //***************************************************************** 125 | // Task will periodically print out useful information about the tasks running 126 | // Is a useful tool to help figure out stack sizes being used 127 | // Run time stats are generated from all task timing collected since startup 128 | // No easy way yet to clear the run time stats yet 129 | //***************************************************************** 130 | static char ptrTaskList[400]; //temporary string buffer for task stats 131 | 132 | void taskMonitor(void *pvParameters) 133 | { 134 | int x; 135 | int measurement; 136 | 137 | SERIAL.println("Task Monitor: Started"); 138 | 139 | // run this task afew times before exiting forever 140 | while(1) 141 | { 142 | myDelayMs(10000); // print every 10 seconds 143 | 144 | SERIAL.flush(); 145 | SERIAL.println(""); 146 | SERIAL.println("****************************************************"); 147 | SERIAL.print("Free Heap: "); 148 | SERIAL.print(xPortGetFreeHeapSize()); 149 | SERIAL.println(" bytes"); 150 | 151 | SERIAL.print("Min Heap: "); 152 | SERIAL.print(xPortGetMinimumEverFreeHeapSize()); 153 | SERIAL.println(" bytes"); 154 | SERIAL.flush(); 155 | 156 | SERIAL.println("****************************************************"); 157 | SERIAL.println("Task ABS %Util"); 158 | SERIAL.println("****************************************************"); 159 | 160 | vTaskGetRunTimeStats(ptrTaskList); //save stats to char array 161 | SERIAL.println(ptrTaskList); //prints out already formatted stats 162 | SERIAL.flush(); 163 | 164 | SERIAL.println("****************************************************"); 165 | SERIAL.println("Task State Prio Stack Num Core" ); 166 | SERIAL.println("****************************************************"); 167 | 168 | vTaskList(ptrTaskList); //save stats to char array 169 | SERIAL.println(ptrTaskList); //prints out already formatted stats 170 | SERIAL.flush(); 171 | 172 | SERIAL.println("****************************************************"); 173 | SERIAL.println("[Stacks Free Bytes Remaining] "); 174 | 175 | measurement = uxTaskGetStackHighWaterMark( Handle_aTask ); 176 | SERIAL.print("Thread A: "); 177 | SERIAL.println(measurement); 178 | 179 | measurement = uxTaskGetStackHighWaterMark( Handle_bTask ); 180 | SERIAL.print("Thread B: "); 181 | SERIAL.println(measurement); 182 | 183 | measurement = uxTaskGetStackHighWaterMark( Handle_cTask ); 184 | SERIAL.print("Thread C: "); 185 | SERIAL.println(measurement); 186 | 187 | measurement = uxTaskGetStackHighWaterMark( Handle_monitorTask ); 188 | SERIAL.print("Monitor Stack: "); 189 | SERIAL.println(measurement); 190 | 191 | SERIAL.println("****************************************************"); 192 | SERIAL.flush(); 193 | 194 | } 195 | 196 | // delete ourselves. 197 | // Have to call this or the system crashes when you reach the end bracket and then get scheduled. 198 | SERIAL.println("Task Monitor: Deleting"); 199 | vTaskDelete( NULL ); 200 | 201 | } 202 | 203 | 204 | //***************************************************************** 205 | 206 | void setup() 207 | { 208 | 209 | SERIAL.begin(115200); 210 | 211 | delay(1000); // prevents usb driver crash on startup, do not omit this 212 | while (!SERIAL) ; // Wait for serial terminal to open port before starting program 213 | 214 | SERIAL.println(""); 215 | SERIAL.println("******************************"); 216 | SERIAL.println(" Program start "); 217 | SERIAL.println("******************************"); 218 | SERIAL.flush(); 219 | 220 | // Set the led the rtos will blink when we have a fatal rtos error 221 | // RTOS also Needs to know if high/low is the state that turns on the led. 222 | // Error Blink Codes: 223 | // 3 blinks - Fatal Rtos Error, something bad happened. Think really hard about what you just changed. 224 | // 2 blinks - Malloc Failed, Happens when you couldn't create a rtos object. 225 | // Probably ran out of heap. 226 | // 1 blink - Stack overflow, Task needs more bytes defined for its stack! 227 | // Use the taskMonitor thread to help gauge how much more you need 228 | vSetErrorLed(ERROR_LED_PIN, ERROR_LED_LIGHTUP_STATE); 229 | 230 | // sets the serial port to print errors to when the rtos crashes 231 | // if this is not set, serial information is not printed by default 232 | vSetErrorSerial(&SERIAL); 233 | 234 | // Create the threads that will be managed by the rtos 235 | // Sets the stack size and priority of each task 236 | // Also initializes a handler pointer to each task, which are important to communicate with and retrieve info from tasks 237 | xTaskCreate(threadA, "Task A", 256, NULL, tskIDLE_PRIORITY + 4, &Handle_aTask); 238 | xTaskCreate(threadB, "Task B", 256, NULL, tskIDLE_PRIORITY + 3, &Handle_bTask); 239 | xTaskCreate(threadC, "Task C", 256, NULL, tskIDLE_PRIORITY + 2, &Handle_cTask); 240 | xTaskCreate(taskMonitor, "Task Monitor", 256, NULL, tskIDLE_PRIORITY + 1, &Handle_monitorTask); 241 | 242 | // Start the RTOS, this function will never return and will schedule the tasks. 243 | vTaskStartScheduler(); 244 | 245 | // error scheduler failed to start 246 | // should never get here 247 | while(1) 248 | { 249 | SERIAL.println("Scheduler Failed! \n"); 250 | SERIAL.flush(); 251 | delay(1000); 252 | } 253 | 254 | } 255 | 256 | //***************************************************************** 257 | // This is now the rtos idle loop 258 | // No rtos blocking functions allowed! 259 | //***************************************************************** 260 | void loop() 261 | { 262 | // Optional commands, can comment/uncomment below 263 | SERIAL.print("."); //print out dots in terminal, we only do this when the RTOS is in the idle state 264 | SERIAL.flush(); 265 | delay(100); //delay is interrupt friendly, unlike vNopDelayMS 266 | } 267 | 268 | 269 | //***************************************************************** 270 | 271 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=FreeRTOS_SAMD51 2 | version=1.3.0 3 | author=BriscoeTech <> 4 | maintainer=BriscoeTech <> 5 | sentence=FreeRTOS ported for Arduino SAMD51 processors 6 | paragraph=FreeRTOS ported for Arduino SAMD51 processors 7 | category=Device Control 8 | url=https://github.com/BriscoeTech/Arduino-FreeRTOS-SAMD51 9 | architectures=samd 10 | repository=https://github.com/BriscoeTech/Arduino-FreeRTOS-SAMD51.git 11 | -------------------------------------------------------------------------------- /src/FreeRTOSConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.1 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 FREERTOS_CONFIG_H 30 | #define FREERTOS_CONFIG_H 31 | 32 | /*----------------------------------------------------------- 33 | * Application specific definitions. 34 | * 35 | * These definitions should be adjusted for your particular hardware and 36 | * application requirements. 37 | * 38 | * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE 39 | * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. 40 | * 41 | * See http://www.freertos.org/a00110.html 42 | *----------------------------------------------------------*/ 43 | 44 | /* Ensure stdint is only used by the compiler, and not the assembler. */ 45 | #ifdef __ICCARM__ 46 | #include 47 | #endif 48 | 49 | #define configUSE_PREEMPTION 1 50 | #define configUSE_IDLE_HOOK 1 51 | #define configUSE_TICK_HOOK 0 52 | #define configCPU_CLOCK_HZ ( ( unsigned long ) F_CPU ) 53 | #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) 54 | #define configMAX_PRIORITIES ( 9 ) 55 | #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 150 ) 56 | #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 20 * 1024 ) ) 57 | #define configMAX_TASK_NAME_LEN ( 16 ) //includes string null terminator 58 | #define configUSE_TRACE_FACILITY 1 59 | #define configUSE_16_BIT_TICKS 0 60 | #define configIDLE_SHOULD_YIELD 1 61 | #define configUSE_MUTEXES 1 62 | #define configQUEUE_REGISTRY_SIZE 8 63 | #define configCHECK_FOR_STACK_OVERFLOW 2 64 | #define configUSE_RECURSIVE_MUTEXES 1 65 | #define configUSE_MALLOC_FAILED_HOOK 1 66 | #define configUSE_APPLICATION_TASK_TAG 0 67 | #define configUSE_COUNTING_SEMAPHORES 1 68 | #define configUSE_QUEUE_SETS 1 69 | #define configSUPPORT_STATIC_ALLOCATION 0 70 | #define configSUPPORT_DYNAMIC_ALLOCATION 1 71 | 72 | /* Run time stats related definitions. */ 73 | #define configGENERATE_RUN_TIME_STATS 1 74 | 75 | /* Arduino framework integration */ 76 | #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vMainConfigureTimerForRunTimeStats() // see runTimeStats_hooks.h 77 | #define portGET_RUN_TIME_COUNTER_VALUE() ulMainGetRunTimeCounterValue() // see runTimeStats_hooks.h 78 | 79 | /* This demo makes use of one or more example stats formatting functions. These 80 | format the raw data provided by the uxTaskGetSystemState() function in to human 81 | readable ASCII form. See the notes in the implementation of vTaskList() within 82 | FreeRTOS/Source/tasks.c for limitations. */ 83 | #define configUSE_STATS_FORMATTING_FUNCTIONS 1 84 | 85 | #define configUSE_MUTEXES 1 86 | #define INCLUDE_uxTaskGetStackHighWaterMark 1 87 | #define INCLUDE_xTaskGetIdleTaskHandle 1 88 | #define configUSE_MALLOC_FAILED_HOOK 1 89 | 90 | /* Co-routine definitions. */ 91 | #define configUSE_CO_ROUTINES 0 92 | #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) 93 | 94 | /* Software timer definitions. */ 95 | #define configUSE_TIMERS 1 96 | #define configTIMER_TASK_PRIORITY ( 2 ) 97 | #define configTIMER_QUEUE_LENGTH 10 98 | #define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE ) 99 | 100 | /* Set the following definitions to 1 to include the API function, or zero 101 | to exclude the API function. */ 102 | #define INCLUDE_xTaskGetCurrentTaskHandle 1 103 | #define INCLUDE_vTaskPrioritySet 1 104 | #define INCLUDE_uxTaskPriorityGet 1 105 | #define INCLUDE_vTaskDelete 1 106 | #define INCLUDE_vTaskCleanUpResources 1 107 | #define INCLUDE_vTaskSuspend 1 108 | #define INCLUDE_vTaskDelayUntil 1 109 | #define INCLUDE_vTaskDelay 1 110 | #define INCLUDE_eTaskGetState 1 111 | 112 | /* Arduino framework integration */ 113 | // calibration factor for vNopDelayMS in error_hooks.c 114 | // used to set accuracy of nopDelayMS function 115 | // this was experimentally chosen from a samd51 processor 116 | #define configCAL_FACTOR (F_CPU/6000) 117 | 118 | /* Arduino framework integration */ 119 | #if 0 120 | // disable interrupts and blink error code 121 | extern void rtosFatalError(void); // see error_hooks.h 122 | #define configASSERT( x ) \ 123 | if( ( x ) == 0 ) { rtosFatalError(); } 124 | #else 125 | // print a error file and line number out user specified serial port 126 | // disable interrupts and blink error code 127 | extern void rtosFatalErrorSerial(unsigned long ulLine, const char * const pcFileName); // see error_hooks.h 128 | extern const char* removePath(const char* path); // see error_hooks.h 129 | #define configASSERT( x ) \ 130 | if( ( x ) == 0 ) { rtosFatalErrorSerial( __LINE__, removePath(__FILE__) ); } 131 | 132 | // assert you can use to also print the value that caused the failure 133 | // Useful for debugging, but not FreeRtos standard 134 | #define configPrintASSERT( x, v1, s, v2 ) \ 135 | if( ( x ) == 0 ) { rtosFatalErrorSerialPrint( __LINE__, removePath(__FILE__), v1, s, v2 ); } 136 | #endif 137 | 138 | /* Arduino framework integration */ 139 | // article to help wade through and figure out proper interrupt settings: 140 | // https://community.arm.com/developer/ip-products/system/b/embedded-blog/posts/cutting-through-the-confusion-with-arm-cortex-m-interrupt-priorities 141 | 142 | /* Cortex-M specific definitions. */ 143 | #define configPRIO_BITS 3 // SAMD51 has only 8 priority levels. pg64 of datasheet. 144 | 145 | /* The lowest interrupt priority that can be used in a call to a "set priority" 146 | function. */ 147 | #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x07 // lowest priority 148 | 149 | /* The highest interrupt priority that can be used by any interrupt service 150 | routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL 151 | INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER 152 | PRIORITY THAN THIS! (higher priorities are lower numeric values. */ 153 | // See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. 154 | #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 0x05 // highest priority 155 | 156 | /* Interrupt priorities used by the kernel port layer itself. These are generic 157 | to all Cortex-M ports, and do not rely on any particular library functions. */ 158 | #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) 159 | /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! 160 | See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ 161 | #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) 162 | 163 | /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS 164 | standard names. */ 165 | #define vPortSVCHandler SVC_Handler 166 | #define xPortPendSVHandler PendSV_Handler 167 | //#define xPortSysTickHandler SysTick_Handler 168 | 169 | /* The size of the global output buffer that is available for use when there 170 | are multiple command interpreters running at once (for example, one on a UART 171 | and one on TCP/IP). This is done to prevent an output buffer being defined by 172 | each implementation - which would waste RAM. In this case, there is only one 173 | command interpreter running. */ 174 | #define configCOMMAND_INT_MAX_OUTPUT_SIZE 2048 175 | 176 | #endif /* FREERTOS_CONFIG_H */ 177 | 178 | -------------------------------------------------------------------------------- /src/FreeRTOS_SAMD51.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef FREE_RTOS_SAMD21_H 4 | #define FREE_RTOS_SAMD21_H 5 | 6 | #include //required to prevent a compiling error when a cpp header file tries to include this library 7 | 8 | // Rtos core library 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | // hardware specific port files 26 | #include 27 | #include 28 | 29 | // added helper filed for Arduino support 30 | #include 31 | #include 32 | 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/croutine.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.1 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 | #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/deprecated_definitions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.1 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/error_hooks.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "error_hooks.h" 3 | #include "FreeRTOSConfig.h" //for configCAL_FACTOR 4 | #include 5 | 6 | //************************************************************************ 7 | // global variables 8 | 9 | int ErrorLed_Pin = 13; //default arduino led pin 10 | int ErrorLed_ActiveState = HIGH; 11 | 12 | Stream *errorSerial = NULL; 13 | //************************************************************************ 14 | 15 | 16 | // set the error led to use by the rtos 17 | void vSetErrorLed(uint8_t pin, uint8_t activeState) 18 | { 19 | ErrorLed_Pin = pin; 20 | ErrorLed_ActiveState = activeState; 21 | } 22 | 23 | 24 | // set the error serial port for debugging asserts and crashes 25 | void vSetErrorSerial(Stream *serial) 26 | { 27 | errorSerial = serial; 28 | } 29 | 30 | 31 | //************************************************************************ 32 | 33 | 34 | // remove a linux or windows path from the file name 35 | const char* removePath(const char* path) 36 | { 37 | const char* lastname = path; 38 | for (const char* p=path; *p; ++p) 39 | { 40 | if ( (*p == '/' || *p == '\\') && *(p+1) ) 41 | { 42 | lastname = p+1; 43 | } 44 | 45 | } 46 | return lastname; 47 | } 48 | 49 | //************************************************************************ 50 | 51 | //called on fatal error (interrupts disabled already) 52 | void rtosFatalError(void) 53 | { 54 | taskDISABLE_INTERRUPTS(); 55 | 56 | while (1) 57 | { 58 | errorBlink(3); 59 | } 60 | 61 | } 62 | 63 | // fatal error print out what file assert failed 64 | void rtosFatalErrorSerial(unsigned long ulLine, const char *pcFileName) 65 | { 66 | if(errorSerial != NULL) 67 | { 68 | errorSerial->flush(); 69 | errorSerial->println(F("")); 70 | errorSerial->println(F("Fatal Rtos Error")); 71 | 72 | errorSerial->print(F("File: ")); 73 | errorSerial->println(pcFileName); 74 | 75 | errorSerial->print(F("Line: ")); 76 | errorSerial->println(ulLine); 77 | 78 | // allow serial port to flush 79 | errorSerial->flush(); 80 | delay(100); 81 | } 82 | 83 | // proceed the same as other fatal rtos error 84 | rtosFatalError(); 85 | } 86 | 87 | void rtosFatalErrorSerialPrint(unsigned long ulLine, const char *pcFileName, uint8_t valueA, const char* evaluation, uint8_t valueB) 88 | { 89 | if(errorSerial != NULL) 90 | { 91 | errorSerial->flush(); 92 | errorSerial->println(F("")); 93 | errorSerial->println(F("Fatal Rtos Error")); 94 | 95 | errorSerial->print(F("File: ")); 96 | errorSerial->println(pcFileName); 97 | 98 | errorSerial->print(F("Line: ")); 99 | errorSerial->println(ulLine); 100 | 101 | errorSerial->print(valueA); 102 | errorSerial->print(" "); 103 | errorSerial->print(evaluation); 104 | errorSerial->print(" "); 105 | errorSerial->print(valueB); 106 | errorSerial->println(); 107 | 108 | // allow serial port to flush 109 | errorSerial->flush(); 110 | delay(100); 111 | } 112 | 113 | // proceed the same as other fatal rtos error 114 | rtosFatalError(); 115 | } 116 | 117 | // called on full heap or malloc failure 118 | void vApplicationMallocFailedHook(void) 119 | { 120 | 121 | if(errorSerial != NULL) 122 | { 123 | errorSerial->println(F("")); 124 | errorSerial->println(F("Malloc Failed")); 125 | 126 | // allow serial port to flush 127 | errorSerial->flush(); 128 | delay(100); 129 | } 130 | 131 | while (1) 132 | { 133 | errorBlink(1); 134 | } 135 | } 136 | 137 | // called on full stack 138 | void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName ) 139 | { 140 | 141 | if(errorSerial != NULL) 142 | { 143 | errorSerial->println(F("")); 144 | errorSerial->print(F("Stack Overflow: ")); 145 | errorSerial->println(pcTaskName); 146 | 147 | // allow serial port to flush 148 | errorSerial->flush(); 149 | delay(100); 150 | } 151 | 152 | while (1) 153 | { 154 | errorBlink(2); 155 | } 156 | } 157 | 158 | //************************************************************************ 159 | 160 | 161 | // blink an error code out the default led when the rtos has crashed 162 | void errorBlink(int errorNumber) 163 | { 164 | pinMode(ErrorLed_Pin, OUTPUT); 165 | 166 | for(int x=0; x 3 | #include "FreeRTOS.h" 4 | #include "task.h" 5 | 6 | #ifndef ERROR_HOOKS_H 7 | #define ERROR_HOOKS_H 8 | 9 | #ifdef __cplusplus 10 | 11 | //************************************************** 12 | // Cpp function prototypes 13 | //************************************************** 14 | 15 | // set the error serial port for debugging asserts and crashes 16 | void vSetErrorSerial(Stream *serial); 17 | 18 | extern "C" 19 | { 20 | #endif 21 | 22 | //************************************************** 23 | // defines 24 | //************************************************** 25 | 26 | 27 | //************************************************** 28 | // C function prototypes 29 | //************************************************** 30 | 31 | // set the error led to use by the rtos 32 | void vSetErrorLed(uint8_t pin, uint8_t activeState); 33 | 34 | // remove a linux or windows path from a file path 35 | // will leave file name remaining 36 | const char* removePath(const char* path); 37 | 38 | // called on fatal error (interrupts disabled already) 39 | void rtosFatalError(void); 40 | 41 | // fatal error print out what file assert failed 42 | void rtosFatalErrorSerialPrint(unsigned long ulLine, const char *pcFileName, uint8_t valueA, const char* evaluation, uint8_t valueB); 43 | 44 | // called on full heap or malloc failure 45 | void vApplicationMallocFailedHook(void); 46 | 47 | // called on full stack 48 | void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName ); 49 | 50 | 51 | 52 | // blink an error code out the default led when the rtos has crashed 53 | void errorBlink(int errorNumber); 54 | 55 | // will delay the processors using nops 56 | // this is used when the rtos has crashed and we cannot use more advanced timing 57 | void vNopDelayMS(unsigned long millis); 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/heap_4bis.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.1 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 | * A sample implementation of pvPortMalloc() and vPortFree() that combines 30 | * (coalescences) adjacent memory blocks as they are freed, and in so doing 31 | * limits memory fragmentation. 32 | * 33 | * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the 34 | * memory management pages of http://www.FreeRTOS.org for more information. 35 | */ 36 | #include 37 | 38 | /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 39 | all the API functions to use the MPU wrappers. That should only be done when 40 | task.h is included from an application file. */ 41 | #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 42 | 43 | #include "FreeRTOS.h" 44 | #include "task.h" 45 | 46 | #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 47 | 48 | #if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) 49 | #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 50 | #endif 51 | 52 | /* Block sizes must not get too small. */ 53 | #define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) 54 | 55 | /* Assumes 8bit bytes! */ 56 | #define heapBITS_PER_BYTE ( ( size_t ) 8 ) 57 | 58 | /* Allocate the memory for the heap. */ 59 | #if( configAPPLICATION_ALLOCATED_HEAP == 1 ) 60 | /* The application writer has already defined the array used for the RTOS 61 | heap - probably so it can be placed in a special segment or address. */ 62 | extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 63 | #else 64 | static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 65 | #endif /* configAPPLICATION_ALLOCATED_HEAP */ 66 | 67 | /* Define the linked list structure. This is used to link free blocks in order 68 | of their memory address. */ 69 | typedef struct A_BLOCK_LINK 70 | { 71 | struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ 72 | size_t xBlockSize; /*<< The size of the free block. */ 73 | } BlockLink_t; 74 | 75 | /*-----------------------------------------------------------*/ 76 | 77 | /* 78 | * Inserts a block of memory that is being freed into the correct position in 79 | * the list of free memory blocks. The block being freed will be merged with 80 | * the block in front it and/or the block behind it if the memory blocks are 81 | * adjacent to each other. 82 | */ 83 | static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ); 84 | 85 | /* 86 | * Called automatically to setup the required heap structures the first time 87 | * pvPortMalloc() is called. 88 | */ 89 | static void prvHeapInit( void ); 90 | 91 | /*-----------------------------------------------------------*/ 92 | 93 | /* The size of the structure placed at the beginning of each allocated memory 94 | block must by correctly byte aligned. */ 95 | static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); 96 | 97 | /* Create a couple of list links to mark the start and end of the list. */ 98 | static BlockLink_t xStart, *pxEnd = NULL; 99 | 100 | /* Keeps track of the number of free bytes remaining, but says nothing about 101 | fragmentation. */ 102 | static size_t xFreeBytesRemaining = 0U; 103 | static size_t xMinimumEverFreeBytesRemaining = 0U; 104 | 105 | /* Gets set to the top bit of an size_t type. When this bit in the xBlockSize 106 | member of an BlockLink_t structure is set then the block belongs to the 107 | application. When the bit is free the block is still part of the free heap 108 | space. */ 109 | static size_t xBlockAllocatedBit = 0; 110 | 111 | /*-----------------------------------------------------------*/ 112 | 113 | void *pvPortMalloc( size_t xWantedSize ) 114 | { 115 | BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; 116 | void *pvReturn = NULL; 117 | 118 | vTaskSuspendAll(); 119 | { 120 | /* If this is the first call to malloc then the heap will require 121 | initialisation to setup the list of free blocks. */ 122 | if( pxEnd == NULL ) 123 | { 124 | prvHeapInit(); 125 | } 126 | else 127 | { 128 | mtCOVERAGE_TEST_MARKER(); 129 | } 130 | 131 | /* Check the requested block size is not so large that the top bit is 132 | set. The top bit of the block size member of the BlockLink_t structure 133 | is used to determine who owns the block - the application or the 134 | kernel, so it must be free. */ 135 | if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) 136 | { 137 | /* The wanted size is increased so it can contain a BlockLink_t 138 | structure in addition to the requested amount of bytes. */ 139 | if( xWantedSize > 0 ) 140 | { 141 | xWantedSize += xHeapStructSize; 142 | 143 | /* Ensure that blocks are always aligned to the required number 144 | of bytes. */ 145 | if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) 146 | { 147 | /* Byte alignment required. */ 148 | xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); 149 | configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 ); 150 | } 151 | else 152 | { 153 | mtCOVERAGE_TEST_MARKER(); 154 | } 155 | } 156 | else 157 | { 158 | mtCOVERAGE_TEST_MARKER(); 159 | } 160 | 161 | if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) 162 | { 163 | /* Traverse the list from the start (lowest address) block until 164 | one of adequate size is found. */ 165 | pxPreviousBlock = &xStart; 166 | pxBlock = xStart.pxNextFreeBlock; 167 | while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) 168 | { 169 | pxPreviousBlock = pxBlock; 170 | pxBlock = pxBlock->pxNextFreeBlock; 171 | } 172 | 173 | /* If the end marker was reached then a block of adequate size 174 | was not found. */ 175 | if( pxBlock != pxEnd ) 176 | { 177 | /* Return the memory space pointed to - jumping over the 178 | BlockLink_t structure at its start. */ 179 | pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); 180 | 181 | /* This block is being returned for use so must be taken out 182 | of the list of free blocks. */ 183 | pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; 184 | 185 | /* If the block is larger than required it can be split into 186 | two. */ 187 | if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) 188 | { 189 | /* This block is to be split into two. Create a new 190 | block following the number of bytes requested. The void 191 | cast is used to prevent byte alignment warnings from the 192 | compiler. */ 193 | pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); 194 | configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 ); 195 | 196 | /* Calculate the sizes of two blocks split from the 197 | single block. */ 198 | pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; 199 | pxBlock->xBlockSize = xWantedSize; 200 | 201 | /* Insert the new block into the list of free blocks. */ 202 | prvInsertBlockIntoFreeList( pxNewBlockLink ); 203 | } 204 | else 205 | { 206 | mtCOVERAGE_TEST_MARKER(); 207 | } 208 | 209 | xFreeBytesRemaining -= pxBlock->xBlockSize; 210 | 211 | if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) 212 | { 213 | xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; 214 | } 215 | else 216 | { 217 | mtCOVERAGE_TEST_MARKER(); 218 | } 219 | 220 | /* The block is being returned - it is allocated and owned 221 | by the application and has no "next" block. */ 222 | pxBlock->xBlockSize |= xBlockAllocatedBit; 223 | pxBlock->pxNextFreeBlock = NULL; 224 | } 225 | else 226 | { 227 | mtCOVERAGE_TEST_MARKER(); 228 | } 229 | } 230 | else 231 | { 232 | mtCOVERAGE_TEST_MARKER(); 233 | } 234 | } 235 | else 236 | { 237 | mtCOVERAGE_TEST_MARKER(); 238 | } 239 | 240 | traceMALLOC( pvReturn, xWantedSize ); 241 | } 242 | ( void ) xTaskResumeAll(); 243 | 244 | #if( configUSE_MALLOC_FAILED_HOOK == 1 ) 245 | { 246 | if( pvReturn == NULL ) 247 | { 248 | extern void vApplicationMallocFailedHook( void ); 249 | vApplicationMallocFailedHook(); 250 | } 251 | else 252 | { 253 | mtCOVERAGE_TEST_MARKER(); 254 | } 255 | } 256 | #endif 257 | 258 | configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 ); 259 | return pvReturn; 260 | } 261 | /*-----------------------------------------------------------*/ 262 | 263 | void vPortFree( void *pv ) 264 | { 265 | uint8_t *puc = ( uint8_t * ) pv; 266 | BlockLink_t *pxLink; 267 | 268 | if( pv != NULL ) 269 | { 270 | /* The memory being freed will have an BlockLink_t structure immediately 271 | before it. */ 272 | puc -= xHeapStructSize; 273 | 274 | /* This casting is to keep the compiler from issuing warnings. */ 275 | pxLink = ( void * ) puc; 276 | 277 | /* Check the block is actually allocated. */ 278 | configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); 279 | configASSERT( pxLink->pxNextFreeBlock == NULL ); 280 | 281 | if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) 282 | { 283 | if( pxLink->pxNextFreeBlock == NULL ) 284 | { 285 | /* The block is being returned to the heap - it is no longer 286 | allocated. */ 287 | pxLink->xBlockSize &= ~xBlockAllocatedBit; 288 | 289 | vTaskSuspendAll(); 290 | { 291 | /* Add this block to the list of free blocks. */ 292 | xFreeBytesRemaining += pxLink->xBlockSize; 293 | traceFREE( pv, pxLink->xBlockSize ); 294 | prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); 295 | } 296 | ( void ) xTaskResumeAll(); 297 | } 298 | else 299 | { 300 | mtCOVERAGE_TEST_MARKER(); 301 | } 302 | } 303 | else 304 | { 305 | mtCOVERAGE_TEST_MARKER(); 306 | } 307 | } 308 | } 309 | /*-----------------------------------------------------------*/ 310 | 311 | size_t xPortGetFreeHeapSize( void ) 312 | { 313 | return xFreeBytesRemaining; 314 | } 315 | /*-----------------------------------------------------------*/ 316 | 317 | size_t xPortGetMinimumEverFreeHeapSize( void ) 318 | { 319 | return xMinimumEverFreeBytesRemaining; 320 | } 321 | /*-----------------------------------------------------------*/ 322 | 323 | void vPortInitialiseBlocks( void ) 324 | { 325 | /* This just exists to keep the linker quiet. */ 326 | } 327 | /*-----------------------------------------------------------*/ 328 | 329 | static void prvHeapInit( void ) 330 | { 331 | BlockLink_t *pxFirstFreeBlock; 332 | uint8_t *pucAlignedHeap; 333 | size_t uxAddress; 334 | size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; 335 | 336 | /* Ensure the heap starts on a correctly aligned boundary. */ 337 | uxAddress = ( size_t ) ucHeap; 338 | 339 | if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) 340 | { 341 | uxAddress += ( portBYTE_ALIGNMENT - 1 ); 342 | uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); 343 | xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; 344 | } 345 | 346 | pucAlignedHeap = ( uint8_t * ) uxAddress; 347 | 348 | /* xStart is used to hold a pointer to the first item in the list of free 349 | blocks. The void cast is used to prevent compiler warnings. */ 350 | xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; 351 | xStart.xBlockSize = ( size_t ) 0; 352 | 353 | /* pxEnd is used to mark the end of the list of free blocks and is inserted 354 | at the end of the heap space. */ 355 | uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; 356 | uxAddress -= xHeapStructSize; 357 | uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); 358 | pxEnd = ( void * ) uxAddress; 359 | pxEnd->xBlockSize = 0; 360 | pxEnd->pxNextFreeBlock = NULL; 361 | 362 | /* To start with there is a single free block that is sized to take up the 363 | entire heap space, minus the space taken by pxEnd. */ 364 | pxFirstFreeBlock = ( void * ) pucAlignedHeap; 365 | pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; 366 | pxFirstFreeBlock->pxNextFreeBlock = pxEnd; 367 | 368 | /* Only one block exists - and it covers the entire usable heap space. */ 369 | xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; 370 | xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; 371 | 372 | /* Work out the position of the top bit in a size_t variable. */ 373 | xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); 374 | } 375 | /*-----------------------------------------------------------*/ 376 | 377 | static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) 378 | { 379 | BlockLink_t *pxIterator; 380 | uint8_t *puc; 381 | 382 | /* Iterate through the list until a block is found that has a higher address 383 | than the block being inserted. */ 384 | for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) 385 | { 386 | /* Nothing to do here, just iterate to the right position. */ 387 | } 388 | 389 | /* Do the block being inserted, and the block it is being inserted after 390 | make a contiguous block of memory? */ 391 | puc = ( uint8_t * ) pxIterator; 392 | if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) 393 | { 394 | pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; 395 | pxBlockToInsert = pxIterator; 396 | } 397 | else 398 | { 399 | mtCOVERAGE_TEST_MARKER(); 400 | } 401 | 402 | /* Do the block being inserted, and the block it is being inserted before 403 | make a contiguous block of memory? */ 404 | puc = ( uint8_t * ) pxBlockToInsert; 405 | if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) 406 | { 407 | if( pxIterator->pxNextFreeBlock != pxEnd ) 408 | { 409 | /* Form one big block from the two blocks. */ 410 | pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; 411 | pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; 412 | } 413 | else 414 | { 415 | pxBlockToInsert->pxNextFreeBlock = pxEnd; 416 | } 417 | } 418 | else 419 | { 420 | pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; 421 | } 422 | 423 | /* If the block being inserted plugged a gab, so was merged with the block 424 | before and the block after, then it's pxNextFreeBlock pointer will have 425 | already been set, and should not be set here as that would make it point 426 | to itself. */ 427 | if( pxIterator != pxBlockToInsert ) 428 | { 429 | pxIterator->pxNextFreeBlock = pxBlockToInsert; 430 | } 431 | else 432 | { 433 | mtCOVERAGE_TEST_MARKER(); 434 | } 435 | } 436 | 437 | // non standard contributed feature that can be enabled 438 | #define ENABLE_CALLOC_REALLOC 0 439 | 440 | #if ENABLE_CALLOC_REALLOC 441 | 442 | void *pvPortRealloc (void* ptr, size_t _size) 443 | { 444 | void *retVal = NULL; 445 | if (ptr == NULL && _size > 0) 446 | { 447 | retVal = pvPortMalloc(_size); 448 | } 449 | else if (ptr != NULL && _size == 0) 450 | { 451 | vPortFree(ptr); 452 | retVal = NULL; 453 | } 454 | else if (ptr != NULL && _size > 0) 455 | { 456 | vTaskSuspendAll(); //thread safety 457 | { 458 | if( pxEnd == NULL ) 459 | { 460 | prvHeapInit(); 461 | } 462 | else 463 | { 464 | mtCOVERAGE_TEST_MARKER(); 465 | } 466 | 467 | 468 | BlockLink_t *pxBlock = (BlockLink_t *)(ptr - xHeapStructSize); 469 | size_t oldSize = (uint16_t)(pxBlock->xBlockSize - xHeapStructSize); //size of BlockLink + heap region aligned by portBYTE_ALIGNMENT 470 | 471 | if (_size > oldSize && _size < xFreeBytesRemaining) 472 | { 473 | _size += xHeapStructSize; 474 | 475 | /* Ensure that blocks are always aligned to the required number 476 | of bytes. */ 477 | if ( ( _size & portBYTE_ALIGNMENT_MASK ) != 0x00 ) 478 | { 479 | /* Byte alignment required. */ 480 | _size += ( portBYTE_ALIGNMENT - ( _size & portBYTE_ALIGNMENT_MASK ) ); 481 | configASSERT( ( _size & portBYTE_ALIGNMENT_MASK ) == 0 ); 482 | } 483 | else 484 | { 485 | mtCOVERAGE_TEST_MARKER(); 486 | } 487 | uint8_t *newHeapRegion = (uint8_t *)pvPortMalloc(_size - xHeapStructSize); 488 | for (uint32_t i = 0; i < _size - xHeapStructSize; i++) 489 | { 490 | newHeapRegion[i] = ((uint8_t *)ptr)[i]; 491 | } 492 | vPortFree(ptr); //libero il blocco precedentemente allocato 493 | retVal = newHeapRegion; 494 | 495 | } 496 | else if (_size < oldSize) 497 | { 498 | BlockLink_t *pxNewBlockLink; 499 | _size += xHeapStructSize; 500 | if ( ( _size & portBYTE_ALIGNMENT_MASK ) != 0x00 ) 501 | { 502 | /* Byte alignment required. */ 503 | _size += ( portBYTE_ALIGNMENT - ( _size & portBYTE_ALIGNMENT_MASK ) ); 504 | configASSERT( ( _size & portBYTE_ALIGNMENT_MASK ) == 0 ); 505 | } 506 | else 507 | { 508 | mtCOVERAGE_TEST_MARKER(); 509 | } 510 | 511 | if ( (uint16_t)( pxBlock->xBlockSize - _size ) >= heapMINIMUM_BLOCK_SIZE ) //Possono essere ricavati due blocchi distinti - importantissimo il cast forzato! 512 | { 513 | pxNewBlockLink = ( BlockLink_t * ) ( ( ( uint8_t * ) pxBlock ) + _size); 514 | pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - _size; 515 | pxNewBlockLink->xBlockSize &= ~xBlockAllocatedBit; 516 | 517 | configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 ); 518 | 519 | pxBlock->xBlockSize = _size; 520 | pxBlock->xBlockSize |= xBlockAllocatedBit; 521 | pxBlock->pxNextFreeBlock = NULL; 522 | 523 | /* Insert the new block into the list of free blocks. */ 524 | xFreeBytesRemaining += (uint16_t)pxNewBlockLink->xBlockSize; 525 | prvInsertBlockIntoFreeList( pxNewBlockLink ); 526 | } 527 | else 528 | { 529 | mtCOVERAGE_TEST_MARKER(); 530 | } 531 | retVal = ptr; 532 | 533 | } 534 | else //_size == oldSize 535 | { 536 | retVal = ptr; 537 | } 538 | } 539 | (void)xTaskResumeAll(); 540 | } 541 | else if (ptr == NULL && _size == 0) 542 | { 543 | retVal = NULL; 544 | } 545 | 546 | return retVal; 547 | } 548 | 549 | void * pvPortCalloc(size_t nmemb, size_t _size) 550 | { 551 | uint8_t *ptr = NULL; 552 | vTaskSuspendAll(); //thread safety 553 | { 554 | ptr = (uint8_t *)pvPortMalloc(nmemb * _size); 555 | for (uint32_t i = 0; i < nmemb; i++) 556 | { 557 | ptr[i] = 0; 558 | } 559 | } 560 | (void)xTaskResumeAll(); 561 | return (void *)ptr; 562 | } 563 | 564 | #endif 565 | 566 | /*------------------------------------------------------------*/ 567 | /*-------------------------WRAPPING---------------------------*/ 568 | /*------------------------------------------------------------*/ 569 | void * __wrap_malloc (size_t _size) 570 | { 571 | return pvPortMalloc(_size); 572 | } 573 | 574 | void *__real_malloc(size_t); 575 | 576 | /*------------------------------------------------------------*/ 577 | 578 | void __wrap_free (void *ptr) 579 | { 580 | vPortFree(ptr); 581 | } 582 | 583 | void __real_free(void *); 584 | 585 | /*------------------------------------------------------------*/ 586 | 587 | #if ENABLE_CALLOC_REALLOC 588 | 589 | void * __wrap_realloc (void* ptr, size_t _size) 590 | { 591 | return pvPortRealloc(ptr, _size); 592 | } 593 | 594 | void * __real_realloc (void *, size_t); 595 | 596 | /*------------------------------------------------------------*/ 597 | 598 | void * __wrap_calloc(size_t nmemb, size_t _size) 599 | { 600 | return pvPortCalloc(nmemb, _size); 601 | } 602 | 603 | void * __real_calloc(size_t, size_t); 604 | 605 | #endif 606 | -------------------------------------------------------------------------------- /src/idle_hook.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | 6 | // this is referring to the loop function of your arduino project 7 | extern void loop(void); 8 | 9 | void __attribute__((weak)) vApplicationIdleHook( void ) 10 | { 11 | loop(); //will use your projects loop function as the rtos idle loop 12 | } 13 | -------------------------------------------------------------------------------- /src/list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.1 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.1 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/mpu_prototypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.1 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.1 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.1 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 *pvPortRealloc(void* ptr, size_t _size) PRIVILEGED_FUNCTION; 148 | void *pvPortCalloc(size_t nmemb, size_t _size) PRIVILEGED_FUNCTION; 149 | void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; 150 | size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; 151 | size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; 152 | 153 | /* 154 | * Setup the hardware ready for the scheduler to take control. This generally 155 | * sets up a tick interrupt and sets timers for the correct tick frequency. 156 | */ 157 | BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; 158 | 159 | /* 160 | * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so 161 | * the hardware is left in its original condition after the scheduler stops 162 | * executing. 163 | */ 164 | void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; 165 | 166 | /* 167 | * The structures and methods of manipulating the MPU are contained within the 168 | * port layer. 169 | * 170 | * Fills the xMPUSettings structure with the memory region information 171 | * contained in xRegions. 172 | */ 173 | #if( portUSING_MPU_WRAPPERS == 1 ) 174 | struct xMEMORY_REGION; 175 | void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; 176 | #endif 177 | 178 | #ifdef __cplusplus 179 | } 180 | #endif 181 | 182 | #endif /* PORTABLE_H */ 183 | 184 | -------------------------------------------------------------------------------- /src/portmacro.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.1 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 portTICK_PERIOD_US ( ( TickType_t ) 1000000 / configTICK_RATE_HZ ) 76 | #define portBYTE_ALIGNMENT 8 77 | /*-----------------------------------------------------------*/ 78 | 79 | /* Scheduler utilities. */ 80 | #define portYIELD() \ 81 | { \ 82 | /* Set a PendSV to request a context switch. */ \ 83 | portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ 84 | \ 85 | /* Barriers are normally not required but do ensure the code is completely \ 86 | within the specified behaviour for the architecture. */ \ 87 | __asm volatile( "dsb" ::: "memory" ); \ 88 | __asm volatile( "isb" ); \ 89 | } 90 | 91 | #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) 92 | #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) 93 | #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD() 94 | #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) 95 | /*-----------------------------------------------------------*/ 96 | 97 | /* Critical section management. */ 98 | extern void vPortEnterCritical( void ); 99 | extern void vPortExitCritical( void ); 100 | #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() 101 | #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x) 102 | #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() 103 | #define portENABLE_INTERRUPTS() vPortSetBASEPRI(0) 104 | #define portENTER_CRITICAL() vPortEnterCritical() 105 | #define portEXIT_CRITICAL() vPortExitCritical() 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 | #define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) 238 | 239 | #ifdef __cplusplus 240 | } 241 | #endif 242 | 243 | #endif /* PORTMACRO_H */ 244 | 245 | -------------------------------------------------------------------------------- /src/projdefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.1 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/runTimeStats_hooks.c: -------------------------------------------------------------------------------- 1 | 2 | #include "runTimeStats_hooks.h" 3 | 4 | //************************************************************************ 5 | 6 | // setup the hardware timer to use as a counter 7 | void vMainConfigureTimerForRunTimeStats( void ) 8 | { 9 | // do nothing, will use the arduino systick timer 10 | // can change this if you want 11 | } 12 | 13 | // will return the counter value to generate run time stats 14 | unsigned long ulMainGetRunTimeCounterValue( void ) 15 | { 16 | return micros(); //use already setup arduino systick timer 17 | } 18 | 19 | //************************************************************************ 20 | 21 | -------------------------------------------------------------------------------- /src/runTimeStats_hooks.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "FreeRTOS.h" 4 | 5 | #ifndef RUN_TIME_STATS_HOOKS_H 6 | #define RUN_TIME_STATS_HOOKS_H 7 | 8 | #ifdef __cplusplus 9 | extern "C" 10 | { 11 | #endif 12 | 13 | //************************************************** 14 | // function prototypes 15 | //************************************************** 16 | 17 | void vMainConfigureTimerForRunTimeStats( void ); 18 | unsigned long ulMainGetRunTimeCounterValue( void ); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif // end RUN_TIME_STATS_HOOKS_H 25 | -------------------------------------------------------------------------------- /src/stack_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.2.1 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/stdint.readme: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FREERTOS_STDINT 3 | #define FREERTOS_STDINT 4 | 5 | /******************************************************************************* 6 | * THIS IS NOT A FULL stdint.h IMPLEMENTATION - It only contains the definitions 7 | * necessary to build the FreeRTOS code. It is provided to allow FreeRTOS to be 8 | * built using compilers that do not provide their own stdint.h definition. 9 | * 10 | * To use this file: 11 | * 12 | * 1) Copy this file into the directory that contains your FreeRTOSConfig.h 13 | * header file, as that directory will already be in the compilers include 14 | * path. 15 | * 16 | * 2) Rename the copied file stdint.h. 17 | * 18 | */ 19 | 20 | typedef signed char int8_t; 21 | typedef unsigned char uint8_t; 22 | typedef short int16_t; 23 | typedef unsigned short uint16_t; 24 | typedef long int32_t; 25 | typedef unsigned long uint32_t; 26 | 27 | #endif /* FREERTOS_STDINT */ 28 | -------------------------------------------------------------------------------- /wrapping memory functions/platform.local.txt: -------------------------------------------------------------------------------- 1 | ####################################################################### 2 | # For wrapping freertos malloc/free/realloc/calloc functions 3 | ####################################################################### 4 | # Description: 5 | 6 | # This linker setting change will allow all microcontroller malloc/free/realloc/calloc 7 | # operations to be managed by FreeRtos. This could eliminate memory corruption issues on 8 | # c++ intensive projects, or projects that might be fragmenting the heap. 9 | 10 | ####################################################################### 11 | # Setup Arduino IDE: 12 | 13 | # Copy this file (platform.local.txt) to the same directory as the already existing platform.txt file you want to override with these compiler settings. 14 | 15 | # Example: To add this feature to a sparkfun samd21 board, put the file in this location 16 | # C:\Users\UserName\AppData\Local\Arduino15\packages\SparkFun\hardware\samd\1.5.4 17 | 18 | # Example: To add this feature to a adafruit m0 board, put the file in this location 19 | # C:\Users\UserName\AppData\Local\Arduino15\packages\adafruit\hardware\samd\1.2.9 20 | 21 | ####################################################################### 22 | # Setup Sloeber IDE: 23 | 24 | # If using Sloaber Ide, the platform.local.txt file is not implemented or recognised. 25 | # Follow the manual setup section instead. 26 | 27 | ####################################################################### 28 | # Setup Manual: 29 | 30 | # If you want wrap the `malloc`, `free`, `realloc` and `calloc` system functions with those provided by FreeRTOS, simply use the *--wrap* option 31 | # passed to the gcc linker, by appending the following line to the `compiler.ldflags=` line of the [**platform.txt**](https://github.com/arduino/ArduinoCore-samd/blob/master/platform.txt) file: 32 | # -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=calloc -Wl,--wrap=realloc 33 | 34 | 35 | ####################################################################### 36 | # Compiling Non FreeRtos Arduino Projects 37 | 38 | # These compiler flags will only work for FreeRtos arduino projects. Compiling a basic (Non FreeRtos) arduino project will give you compiler errors saying: 39 | undefined reference to `__wrap_malloc' 40 | undefined reference to `__wrap_free' 41 | 42 | # In order to compile a normal arduino project again: 43 | # A) Remove or rename platform.local.txt. I usually rename it to platform.local.txt.disabled so I can turn the feature back on at a later date. 44 | # B) If you performed manual setup, remove the added linker options. 45 | 46 | ####################################################################### 47 | # Override compiler setting 48 | 49 | compiler.ldflags=-mcpu={build.mcu} -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=calloc -Wl,--wrap=realloc 50 | --------------------------------------------------------------------------------