├── attack.png ├── 2023-11-27_Worldswitch.png ├── 2023-11-27_Worldswitch_Code.png ├── Demo ├── kernelpanic.h ├── kernelpanic.c ├── TrustZone │ ├── selfhealing.h │ ├── interrupts.h │ ├── trustzone.h │ ├── trustzone.c │ ├── TZIC.h │ └── selfhealing.c ├── Drivers │ ├── mxc_serial.h │ ├── IO.h │ ├── IO.c │ ├── mxc_serial.c │ └── config.h ├── Analysis │ ├── timing.h │ └── timing.c ├── Tasks │ ├── controltasks.h │ └── controltasks.c ├── exceptions.h ├── exceptions.c └── main.c ├── .gitignore ├── attack.sh ├── setupsd.sh ├── FreeRTOS └── Source │ ├── readme.txt │ ├── include │ ├── stdint.readme │ ├── FreeRTOSConfig.h │ ├── projdefs.h │ ├── StackMacros.h │ ├── mpu_wrappers.h │ ├── portable.h │ └── deprecated_definitions.h │ ├── portable │ ├── MemMang │ │ ├── heap_3.c │ │ ├── heap_1.c │ │ └── heap_2.c │ └── GCC │ │ ├── portisr.c │ │ ├── portmacro.h │ │ └── port.c │ └── list.c ├── kernel.ld ├── imximage.cfg ├── Makefile ├── README.md ├── 2023-11-27_Worldswitch_Code.drawio └── 2023-11-27_Worldswitch.drawio /attack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdenzel/self-healing_FreeRTOS/HEAD/attack.png -------------------------------------------------------------------------------- /2023-11-27_Worldswitch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdenzel/self-healing_FreeRTOS/HEAD/2023-11-27_Worldswitch.png -------------------------------------------------------------------------------- /2023-11-27_Worldswitch_Code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdenzel/self-healing_FreeRTOS/HEAD/2023-11-27_Worldswitch_Code.png -------------------------------------------------------------------------------- /Demo/kernelpanic.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Kernel panic functionality if something goes horribly wrong. 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | #ifndef __KERNEL_PANIC_ 12 | #define __KERNEL_PANIC_ 13 | 14 | void kernelpanic(const char* const message); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Debug files 32 | *.dSYM/ 33 | *.su 34 | 35 | # Build directory 36 | build/ 37 | kernel.img 38 | kernel.imx 39 | -------------------------------------------------------------------------------- /Demo/kernelpanic.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Kernel panic functionality if something goes horribly wrong. 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | #include "kernelpanic.h" 12 | #include "mxc_serial.h" 13 | #include "interrupts.h" 14 | 15 | void kernelpanic(const char* const string){ 16 | //print error message (with additional newline) 17 | cprintf("%s", string); 18 | cprintf("\n"); 19 | 20 | //stop everything 21 | __asm volatile("SMC #13\n"); 22 | } 23 | -------------------------------------------------------------------------------- /Demo/TrustZone/selfhealing.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Self-healing functionality 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | #ifndef _SELFHEALING_H_ 12 | #define _SELFHEALING_H_ 13 | 14 | //helper function 15 | int is_currentTCB_restoration(); 16 | 17 | //detection routine: checks pxCurrentTCB and maybe exchanges it with a restoration task 18 | int detection(); 19 | 20 | //restoration routine: restores given task 21 | void restoration(void* task); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /Demo/Drivers/mxc_serial.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Printing functionality (via serial cable). 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | * 10 | * XXX: file is based on code from 11 | * Dongli Zhang https://github.com/finallyjustice/imx53qsb-code "trustzone-smc" 12 | **/ 13 | 14 | #ifndef __MXC_SERIAL_H__ 15 | #define __MXC_SERIAL_H__ 16 | 17 | //init 18 | void iomuxc_init(void); 19 | void mxc_serial_init(void); 20 | 21 | //read/write 22 | void cprintf(char *fmt, ...); 23 | unsigned int readline(char* const buf, const unsigned int size); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Demo/Analysis/timing.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Definitions for a timing analysis on FreeRTOS (TrustZone) task swtich. 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | #ifndef __TIMING_H_ 12 | #define __TIMING_H_ 13 | 14 | //Module with a simple timer 15 | 16 | #define TIME_AVERAGE 60 //average print every X seconds 17 | 18 | //keep module small to not affect performance too much 19 | void init_timer(); 20 | void start_timer(); 21 | unsigned int stop_timer(); 22 | unsigned int timer_average(); 23 | unsigned int timer_num(); 24 | unsigned int get_timer_overhead(); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /Demo/Tasks/controltasks.h: -------------------------------------------------------------------------------- 1 | /** 2 | * A few tasks to demonstrate self-healing FreeRTOS. 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | #ifndef __CONTROLTASKS_H_ 12 | #define __CONTROLTASKS_H_ 13 | 14 | // --- UTILITY --- 15 | void ListTasks(); 16 | 17 | // --- OWN TASK IMPLEMENTATION --- 18 | //task management 19 | #ifdef TIMING 20 | #define NUM_TASKS 4 21 | #else 22 | #define NUM_TASKS 3 23 | #endif 24 | extern char* const TASK_NAMES[]; 25 | extern const unsigned int TASK_PRIOS[]; 26 | extern void (*TASK_FUNCTIONS[])(void*); 27 | 28 | //functions 29 | void controltask(void *pParam); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /Demo/exceptions.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition of the exception handlers. 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | #ifndef __EXCEPTIONS_H_ 12 | #define __EXCEPTIONS_H_ 13 | 14 | // -- EXCEPTION HANDLERS --- 15 | //secure world 16 | void secure_undef(); 17 | void secure_swi(const unsigned int nIRQ); 18 | void secure_pabort(); 19 | void secure_dabort(); 20 | void secure_irq(); 21 | void secure_fiq(); 22 | 23 | //normal world 24 | void ns_reset(); 25 | void ns_undef(); 26 | void ns_swi(const unsigned int nIRQ); 27 | void ns_pa(); 28 | void ns_da(); 29 | void ns_irq(); 30 | void ns_fiq(); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /attack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # An example attack to demonstrate self-healing functionality of adjusted FreeRTOS. 5 | # 6 | # @author: Michael Denzel 7 | # @contact: https://github.com/mdenzel 8 | # @license: GNU General Public License 2.0 or later 9 | # @date: 2017-03-17 10 | # @version: 0.1 11 | # 12 | 13 | ### CONFIG ### 14 | io=/dev/ttyUSB0 #the serial connection to the i.MX53 Quick Start Board 15 | ############## 16 | 17 | if [ $# -eq 1 ]; then 18 | hex=`echo "obase=16; $1" | bc` #cast the temperature into base 16 19 | echo -e "update 1234561234567890\x$hex" > $io #overflow buffer and write the new temperature 20 | echo -e "status" > $io #send a status to show self-healing 21 | else 22 | echo "Usage: $0 " 23 | fi 24 | -------------------------------------------------------------------------------- /setupsd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Shellscript to flash a compiled kernel image (kernel.img) to an sd-card. 5 | # (/dev/sda is rejected as input as this is usually the own harddrive - adjust if needed) 6 | # 7 | # @author: Michael Denzel 8 | # @contact: https://github.com/mdenzel 9 | # @license: GNU General Public License 2.0 or later 10 | # @date: 2017-03-17 11 | # @version: 0.1 12 | # 13 | 14 | 15 | if [ $# -ne 1 ]; then 16 | echo "setupsd.sh " 17 | exit -1 18 | fi 19 | 20 | if [ $1 == "/dev/sda" ]; then 21 | echo "reject $1" 22 | exit -1 23 | fi 24 | 25 | #create image 26 | mkimage -n imximage.cfg -T imximage -e 0x97800000 -d kernel.img kernel.imx 27 | 28 | #flash it to SD card 29 | dd if=kernel.imx of=$1 bs=512 seek=2 30 | 31 | sync 32 | -------------------------------------------------------------------------------- /FreeRTOS/Source/readme.txt: -------------------------------------------------------------------------------- 1 | Each real time kernel port consists of three files that contain the core kernel 2 | components and are common to every port, and one or more files that are 3 | specific to a particular microcontroller and or compiler. 4 | 5 | + The FreeRTOS/Source directory contains the three files that are common to 6 | every port - list.c, queue.c and tasks.c. The kernel is contained within these 7 | three files. croutine.c implements the optional co-routine functionality - which 8 | is normally only used on very memory limited systems. 9 | 10 | + The FreeRTOS/Source/Portable directory contains the files that are specific to 11 | a particular microcontroller and or compiler. 12 | 13 | + The FreeRTOS/Source/include directory contains the real time kernel header 14 | files. 15 | 16 | See the readme file in the FreeRTOS/Source/Portable directory for more 17 | information. -------------------------------------------------------------------------------- /Demo/Drivers/IO.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Definitions for a LED driver on the i.MX53 board and a simulated driver for a 3 | * temperature sensor. 4 | * 5 | * @author: Michael Denzel 6 | * @contact: https://github.com/mdenzel 7 | * @license: GNU General Public License 2.0 or later 8 | * @date: 2017-03-17 9 | * @version: 0.1 10 | **/ 11 | 12 | #ifndef __IO_H_ 13 | #define __IO_H_ 14 | 15 | // --- LED driver --- 16 | typedef enum LEDvalues { 17 | ON, 18 | OFF 19 | } LEDvalues; 20 | 21 | void set_led(LEDvalues val); 22 | LEDvalues get_led(); 23 | 24 | // --- Thermal sensor --- 25 | typedef struct temperature{ 26 | char info[16]; //to introduce a buffer overflow 27 | int max; 28 | int min; 29 | } temperature; 30 | void reset_temperature(); 31 | int check_temperature(); 32 | temperature get_config_temperature(); 33 | void set_config_temperature(char* str); //to introduce a buffer overflow 34 | 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/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 | -------------------------------------------------------------------------------- /kernel.ld: -------------------------------------------------------------------------------- 1 | /** 2 | * Linker Script for the Cortex-A8 (location 0x97800000) 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | ENTRY(_start) 12 | 13 | SECTIONS 14 | { 15 | . = 0x97800000; 16 | /*. = ALIGN(4);*/ 17 | .text : { *(.text) } 18 | 19 | . = ALIGN(4); 20 | .data : { *(.data) } 21 | 22 | . = ALIGN(4); 23 | __bss_start = .; 24 | .bss : { *(.bss*) } 25 | __bss_end = .; 26 | 27 | /* 28 | * heap trick (XXX: see also Demo/main.c) 29 | * source: Francesco Balducci https://balau82.wordpress.com/2010/12/16/using-newlib-in-arm-bare-metal-programs/ 30 | */ 31 | . = ALIGN(8); 32 | heap_low = .; /* for _sbrk */ 33 | . = . + 0x10000; /* 64kB of heap memory */ 34 | heap_top = .; /* for _sbrk */ 35 | 36 | /* 37 | * stack 38 | */ 39 | . = 0xa0000000; 40 | .stack : 41 | { 42 | STACK_ADDR = . ; 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /Demo/TrustZone/interrupts.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tiny Interrupt Manager (with modifications) 3 | * 4 | * original author: James Walmsley 5 | * https://github.com/jameswalmsley/RaspberryPi-FreeRTOS 6 | * 7 | * modifications: 8 | * @author: Michael Denzel 9 | * @contact: https://github.com/mdenzel 10 | * @license: GNU General Public License 2.0 or later 11 | * @date: 2017-03-17 12 | * @version: 0.1 13 | **/ 14 | 15 | #ifndef _INTERRUPTS_H_ 16 | #define _INTERRUPTS_H_ 17 | 18 | typedef void (*FN_INTERRUPT_HANDLER)(unsigned int nIRQ, void *pParam); 19 | 20 | typedef struct { 21 | FN_INTERRUPT_HANDLER pfnHandler; //function handling IRQn 22 | void* pParam; //special parameter to pass to the IRQ 23 | } INTERRUPT_VECTOR; 24 | 25 | void InitInterruptController (); 26 | 27 | int RegisterInterrupt (const unsigned int nIRQ, FN_INTERRUPT_HANDLER pfnHandler, void *pParam); 28 | void AcknowledgeInterrupt (const unsigned int nIRQ); 29 | int EnableInterrupt (const unsigned int nIRQ); 30 | int DisableInterrupt (const unsigned int nIRQ); 31 | int TriggerInterrupt (const unsigned int nIRQ); 32 | 33 | void EnableInterrupts (); 34 | void DisableInterrupts (); 35 | void ClearAllInterrupts (); 36 | void PrintPendingInterrupts (); 37 | 38 | unsigned int CheckIRQ (); 39 | unsigned int CheckFIQ (); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /Demo/TrustZone/trustzone.h: -------------------------------------------------------------------------------- 1 | /** 2 | * TrustZone related functionality. 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | #ifndef _TRUSTZONE_H_ 12 | #define _TRUSTZONE_H_ 13 | 14 | /* 15 | * ARM mode of operation 16 | */ 17 | typedef enum MODE { 18 | USER = 0b10000, //usual ARM program (only unprivileged one) 19 | FIQ = 0b10001, //for handling fast interrupts 20 | IRQ = 0b10010, //for handling interrutps 21 | SUPERVISOR = 0b10011, //protected mode for OS 22 | ABORT = 0b10111, //mode after data/prefetch abort 23 | UNDEF = 0b11011, //on undefined instruction (e.g. 24 | // read TrustZone from normal world) 25 | SYSTEM = 0b11111, //privileged user mode for OS 26 | MONITOR = 0b10110 //secure mode for monitor 27 | } MODE; 28 | 29 | /* 30 | * Functions 31 | */ 32 | //ARM mode of operation 33 | MODE get_MODE(); 34 | void print_MODE(); 35 | void print_SMC(unsigned int smc); 36 | void print_WORLD(); 37 | //ARM TrustZone worlds 38 | unsigned int get_control_register(); 39 | unsigned int SMC_is_secure_world(); //calls monitor and therefore also possible in normal world (but only after monitor is setup!) 40 | unsigned int is_secure_world(); //throws undef. instruction exception if called from normal world! 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /Demo/exceptions.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Functionality to catch all possible exceptions. 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | #include "exceptions.h" 12 | #include "mxc_serial.h" 13 | #include "kernelpanic.h" 14 | 15 | //external functions 16 | extern void irqHandler(); 17 | 18 | //secure world 19 | void secure_undef(){ 20 | kernelpanic("secure world undef\n"); 21 | } 22 | void secure_swi(const unsigned int nIRQ){ 23 | cprintf("secure world SWI %d\n", nIRQ); 24 | } 25 | void secure_pabort(){ 26 | kernelpanic("secure world pabort\n"); 27 | } 28 | void secure_dabort(){ 29 | kernelpanic("secure world dabort\n"); 30 | } 31 | void secure_irq(){ 32 | #ifdef DEBUG 33 | cprintf("secure world IRQ\n"); 34 | #endif 35 | irqHandler(); 36 | #ifdef DEBUG 37 | cprintf("secure world IRQ done\n"); 38 | #endif 39 | } 40 | void secure_fiq(){ 41 | #ifdef DEBUG 42 | cprintf("secure world FIQ\n"); 43 | #endif 44 | irqHandler(); 45 | #ifdef DEBUG 46 | cprintf("secure world FIQ done\n"); 47 | #endif 48 | } 49 | 50 | //normal world 51 | void ns_reset(){ 52 | cprintf("normal world reset\n"); 53 | } 54 | void ns_undef(){ 55 | kernelpanic("normal world Undef\n"); 56 | } 57 | void ns_swi(const unsigned int nIRQ){ 58 | cprintf("normal world SWI %d\n", nIRQ); 59 | } 60 | void ns_pa(){ 61 | kernelpanic("normal world PA\n"); 62 | } 63 | void ns_da(){ 64 | kernelpanic("normal world DA\n"); 65 | } 66 | void ns_irq(){ 67 | #ifdef DEBUG 68 | cprintf("normal world IRQ\n"); 69 | #endif 70 | irqHandler(); 71 | #ifdef DEBUG 72 | cprintf("normal world IRQ done\n"); 73 | #endif 74 | } 75 | -------------------------------------------------------------------------------- /imximage.cfg: -------------------------------------------------------------------------------- 1 | # 2 | # XXX: file originally from 3 | # Dongli Zhang https://github.com/finallyjustice/imx53qsb-code "trustzone-smc" 4 | # 5 | 6 | # 1 "board/freescale/mx53loco/imximage.cfg" 7 | # 1 "" 8 | # 1 "" 9 | # 1 "board/freescale/mx53loco/imximage.cfg" 10 | # 14 "board/freescale/mx53loco/imximage.cfg" 11 | IMAGE_VERSION 2 12 | 13 | 14 | 15 | 16 | 17 | BOOT_FROM sd 18 | # 33 "board/freescale/mx53loco/imximage.cfg" 19 | DATA 4 0x53fa8554 0x00300000 20 | DATA 4 0x53fa8558 0x00300040 21 | DATA 4 0x53fa8560 0x00300000 22 | DATA 4 0x53fa8564 0x00300040 23 | DATA 4 0x53fa8568 0x00300040 24 | DATA 4 0x53fa8570 0x00300000 25 | DATA 4 0x53fa8574 0x00300000 26 | DATA 4 0x53fa8578 0x00300000 27 | DATA 4 0x53fa857c 0x00300040 28 | DATA 4 0x53fa8580 0x00300040 29 | DATA 4 0x53fa8584 0x00300000 30 | DATA 4 0x53fa8588 0x00300000 31 | DATA 4 0x53fa8590 0x00300040 32 | DATA 4 0x53fa8594 0x00300000 33 | DATA 4 0x53fa86f0 0x00300000 34 | DATA 4 0x53fa86f4 0x00000000 35 | DATA 4 0x53fa86fc 0x00000000 36 | DATA 4 0x53fa8714 0x00000000 37 | DATA 4 0x53fa8718 0x00300000 38 | DATA 4 0x53fa871c 0x00300000 39 | DATA 4 0x53fa8720 0x00300000 40 | DATA 4 0x53fa8724 0x04000000 41 | DATA 4 0x53fa8728 0x00300000 42 | DATA 4 0x53fa872c 0x00300000 43 | DATA 4 0x63fd9088 0x35343535 44 | DATA 4 0x63fd9090 0x4d444c44 45 | DATA 4 0x63fd907c 0x01370138 46 | DATA 4 0x63fd9080 0x013b013c 47 | DATA 4 0x63fd9018 0x00011740 48 | DATA 4 0x63fd9000 0xc3190000 49 | DATA 4 0x63fd900c 0x9f5152e3 50 | DATA 4 0x63fd9010 0xb68e8a63 51 | DATA 4 0x63fd9014 0x01ff00db 52 | DATA 4 0x63fd902c 0x000026d2 53 | DATA 4 0x63fd9030 0x009f0e21 54 | DATA 4 0x63fd9008 0x12273030 55 | DATA 4 0x63fd9004 0x0002002d 56 | DATA 4 0x63fd901c 0x00008032 57 | DATA 4 0x63fd901c 0x00008033 58 | DATA 4 0x63fd901c 0x00028031 59 | DATA 4 0x63fd901c 0x052080b0 60 | DATA 4 0x63fd901c 0x04008040 61 | DATA 4 0x63fd901c 0x0000803a 62 | DATA 4 0x63fd901c 0x0000803b 63 | DATA 4 0x63fd901c 0x00028039 64 | DATA 4 0x63fd901c 0x05208138 65 | DATA 4 0x63fd901c 0x04008048 66 | DATA 4 0x63fd9020 0x00005800 67 | DATA 4 0x63fd9040 0x05380003 68 | DATA 4 0x63fd9058 0x00022227 69 | DATA 4 0x63fd901c 0x00000000 70 | -------------------------------------------------------------------------------- /Demo/Analysis/timing.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Timing analysis on FreeRTOS (TrustZone) task swtich. 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | //own includes 12 | #include "timing.h" 13 | //FreeRTOS includes 14 | #include "FreeRTOSConfig.h" 15 | 16 | // --- Variables --- 17 | //timing 18 | static unsigned int timing_overhead = 0; 19 | static unsigned int timing = 0; 20 | //incremental average 21 | static unsigned int num_timings = 0; 22 | static unsigned int average = 0; 23 | 24 | // --- FUNCTIONS --- 25 | 26 | void init_timer(){ 27 | //enable user-mode access 28 | __asm volatile("MCR p15, 0, %0, c9, c14, 0\n\t" :: "r"(1)); 29 | //disable overflow interrupt 30 | __asm volatile("MCR p15, 0, %0, c9, c14, 2\n\t" :: "r"(0x8000000f)); 31 | 32 | unsigned int value = 1; //enable all counters 33 | value |= 2; //reset all counters to zero 34 | value |= 4; //reset cycle counter to zero 35 | //value |= 8; // enable "by 64" divider for CCNT (for long times) 36 | value |= 16; 37 | __asm volatile("MCR p15, 0, %0, c9, c12, 0\t\n" :: "r"(value)); 38 | 39 | //enable all counters 40 | __asm volatile ("MCR p15, 0, %0, c9, c12, 1\t\n" :: "r"(0x8000000f)); 41 | //clear overflows 42 | __asm volatile ("MCR p15, 0, %0, c9, c12, 3\t\n" :: "r"(0x8000000f)); 43 | 44 | //overhead 45 | start_timer(); 46 | timing_overhead = stop_timer(); 47 | } 48 | 49 | void start_timer(){ 50 | //FreeRTOS implmentation (xTaskGetTickCount) only works after scheduler was started 51 | //read CCNT (cycle count) Register => CPU 1GHz => nano seconds 52 | __asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(timing)); 53 | } 54 | 55 | unsigned int stop_timer(){ 56 | //read CCNT Register 57 | unsigned int val = 0; 58 | __asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(val)); 59 | val = (val - timing - timing_overhead); 60 | //update average 61 | ++num_timings; 62 | average = ((num_timings-1) * average + val) / num_timings; 63 | return val; 64 | } 65 | 66 | unsigned int timer_average(){ 67 | return average; 68 | } 69 | 70 | unsigned int timer_num(){ 71 | return num_timings; 72 | } 73 | 74 | unsigned int get_timer_overhead(){ 75 | return timing_overhead; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /Demo/TrustZone/trustzone.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Wrapper file around TrustZone (assembly) functionality. 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | #include "trustzone.h" 12 | #include "mxc_serial.h" 13 | 14 | 15 | //check which mode we are in 16 | MODE get_MODE(){ 17 | //get CPSR (programm status register) 18 | unsigned int reg = 0; 19 | __asm volatile("MRS %[Rd], CPSR" : [Rd] "=r" (reg)); 20 | //mode of operation = lowest 5 bits 21 | reg = reg & 0b11111; 22 | 23 | return (MODE)reg; 24 | } 25 | 26 | void print_MODE(){ 27 | MODE m = get_MODE(); 28 | switch(m){ 29 | case USER: 30 | cprintf("USER mode\n"); 31 | break; 32 | case FIQ: 33 | cprintf("FIQ mode\n"); 34 | break; 35 | case IRQ: 36 | cprintf("IRQ mode\n"); 37 | break; 38 | case SUPERVISOR: 39 | cprintf("SUPERVISOR mode\n"); 40 | break; 41 | case ABORT: 42 | cprintf("ABORT mode\n"); 43 | break; 44 | case UNDEF: 45 | cprintf("UNDEF mode\n"); 46 | break; 47 | case SYSTEM: 48 | cprintf("SYSTEM mode\n"); 49 | break; 50 | case MONITOR: 51 | cprintf("MONITOR mode\n"); 52 | break; 53 | default: 54 | cprintf("ERROR: unknown mode: %d", (int)m); 55 | } 56 | } 57 | 58 | void print_SMC(unsigned int smc){ 59 | cprintf("-- SMC %d --\n", smc); 60 | } 61 | 62 | //check which world we are in 63 | void print_WORLD(){ 64 | #ifdef TRUSTZONE 65 | if(SMC_is_secure_world()){ 66 | cprintf("Secure world\n"); 67 | }else{ 68 | cprintf("Normal world\n"); 69 | } 70 | #else 71 | cprintf("TrustZone disabled\n"); 72 | #endif 73 | } 74 | 75 | //check function for trustzone 76 | unsigned int get_control_register(){ 77 | /* 78 | * ARM1176JZF-S CPU: 79 | * MRC p15, 0, , c1, c0, 0 ; Read Control Register configuration data 80 | * MCR p15, 0, , c1, c0, 0 ; Write Control Register configuration data 81 | * Cortex-A8 CPU: 82 | * MRC p15, 0, , c1, c1, 0 ; Read Control Register configuration data 83 | * MCR p15, 0, , c1, c1, 0 ; Write Control Register configuration data 84 | * 85 | * c1: 86 | * [31:7] SBZ - should be zero; unpredictable when read 87 | * [6] nET - early termination (not implemented in ARM1176JZF-S) 88 | * [5] AW - determines if A bit in CPSR can be modified when in the Non-secure world 89 | * [4] FW - determines if F bit in CPSR can be modified when in the Non-secure world 90 | * [3] EA - external abort (see FIQ/IRQ) 91 | * [2] FIQ - FIQ behaviour: 0 = branch to FIQ mode; 1 = branch to Secure Monitor mode 92 | * [1] IRQ - IRQ behaviour: 0 = branch to IRQ mode; 1 = branch to Secure Monitor mode 93 | * [0] NS - world of processor: 0 = secure; 1 = non-secure 94 | */ 95 | unsigned int reg = 0; 96 | #ifdef ARM1176JZF_S 97 | __asm volatile("MRC p15, 0, %[Rd], c1, c0, 0" : [Rd] "=r" (reg)); 98 | #elif CORTEX_A8 99 | __asm volatile("MRC p15, 0, %[Rd], c1, c1, 0" : [Rd] "=r" (reg)); 100 | #else 101 | #error "Unknown CPU" 102 | #endif 103 | reg &= 127; //0b01111111 104 | 105 | return reg; 106 | } 107 | 108 | unsigned int SMC_is_secure_world(){ 109 | //query monitor about world via monitor-call 110 | unsigned int world = 0; 111 | __asm volatile("SMC #2\n\t"); 112 | __asm volatile("mov %0, r0" : "=r" (world)); 113 | return !(world & 1); 114 | } 115 | 116 | unsigned int is_secure_world(){ 117 | //check NS bit 118 | //=> NS == 1 means non-secure world or trustzone "off" 119 | //=> invert bit to show trustzone (NS = !trustzone) 120 | return !(get_control_register() & 1); 121 | } 122 | -------------------------------------------------------------------------------- /Demo/Drivers/IO.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Implemenation of a LED driver on the i.MX53 board and a simulated driver for 3 | * a temperature sensor. 4 | * 5 | * @author: Michael Denzel 6 | * @contact: https://github.com/mdenzel 7 | * @license: GNU General Public License 2.0 or later 8 | * @date: 2017-03-17 9 | * @version: 0.1 10 | **/ 11 | 12 | //C 13 | #include //for rand 14 | #include 15 | 16 | // own includes 17 | #include "IO.h" 18 | #include "mxc_serial.h" 19 | 20 | 21 | // --- LED driver --- 22 | void set_led(LEDvalues led){ 23 | //constants 24 | const unsigned int SW_MUX_BASE_ADDR = 0x53FA8000; 25 | const unsigned int IOMUXC_SW_MUX_CTL_PAD_PATA_DA_1 = (SW_MUX_BASE_ADDR + 0x294); 26 | const unsigned int GPIO7 = 0x53FE4000; 27 | const unsigned int gpio_base = GPIO7; 28 | const unsigned int bit = 7; 29 | 30 | //save IOMUX state 31 | const unsigned int iomux_state = (*(volatile unsigned int*)(IOMUXC_SW_MUX_CTL_PAD_PATA_DA_1)); 32 | 33 | //set ALT1 for GPIO7 => GPIO7 = GPIO7[7] = USR LED 34 | (*(volatile unsigned int*)(IOMUXC_SW_MUX_CTL_PAD_PATA_DA_1)) = 0x1; 35 | 36 | //set to output mode 37 | (*(volatile unsigned int*)(gpio_base + 0x4)) = 1 << bit; 38 | unsigned int val = (*(volatile unsigned int*)(gpio_base+0x0)); 39 | 40 | if(led == ON){ 41 | //turn LED on 42 | (*(volatile unsigned int*)(gpio_base+0x0)) = val | (1 << bit); 43 | #ifdef DEBUG 44 | cprintf("LED on\n"); 45 | #endif 46 | }else{ 47 | //turn LED off 48 | (*(volatile unsigned int*)(gpio_base+0x0)) = val & ~(1 << bit); 49 | #ifdef DEBUG 50 | cprintf("LED off\n"); 51 | #endif 52 | } 53 | 54 | //restore IOMUX state 55 | (*(volatile unsigned int*)(IOMUXC_SW_MUX_CTL_PAD_PATA_DA_1)) = iomux_state; 56 | } 57 | 58 | LEDvalues get_led(){ 59 | //constants 60 | const unsigned int SW_MUX_BASE_ADDR = 0x53FA8000; 61 | const unsigned int IOMUXC_SW_MUX_CTL_PAD_PATA_DA_1 = (SW_MUX_BASE_ADDR + 0x294); 62 | const unsigned int GPIO7 = 0x53FE4000; 63 | const unsigned int gpio_base = GPIO7; 64 | const unsigned int bit = 7; 65 | 66 | //save IOMUX state 67 | const unsigned int iomux_state = (*(volatile unsigned int*)(IOMUXC_SW_MUX_CTL_PAD_PATA_DA_1)); 68 | 69 | //set ALT1 for GPIO7 => GPIO7 = GPIO7[7] = USR LED 70 | (*(volatile unsigned int*)(IOMUXC_SW_MUX_CTL_PAD_PATA_DA_1)) = 0x1; 71 | 72 | //set to output mode 73 | (*(volatile unsigned int*)(gpio_base + 0x4)) = 1 << bit; 74 | //get LED value 75 | unsigned int val = (*(volatile unsigned int*)(gpio_base+0x0)) & (1 << bit); 76 | 77 | //check LED status 78 | LEDvalues ret; 79 | if(val == 0){ 80 | ret = ON; 81 | }else{ 82 | ret = OFF; 83 | } 84 | 85 | //restore IOMUX state 86 | (*(volatile unsigned int*)(IOMUXC_SW_MUX_CTL_PAD_PATA_DA_1)) = iomux_state; 87 | 88 | //return LED status 89 | return ret; 90 | } 91 | 92 | 93 | 94 | // --- Thermal sensor --- 95 | static temperature temp_config = {"init", 100, 0}; 96 | static int temp = 50; 97 | 98 | void reset_temperature(){ 99 | strcpy(temp_config.info, "init"); 100 | temp_config.max = 100; 101 | temp_config.min = 0; 102 | } 103 | 104 | int check_temperature(){ 105 | //IMPROVE: "read" temperature from sensor 106 | int r = ((rand() % 4) - 1) * 5; //[-5; 0; +5; +10] 107 | temp += r; 108 | 109 | if(temp < temp_config.min){ 110 | //IMPROVE: "update" actuator 111 | cprintf("heating...\n"); 112 | temp += 10; 113 | } 114 | else if(temp > temp_config.max){ 115 | //IMPROVE: "update" actuator 116 | cprintf("cooling...\n"); 117 | temp -= 10; 118 | } 119 | 120 | return temp; 121 | } 122 | 123 | temperature get_config_temperature(){ 124 | return temp_config; 125 | } 126 | 127 | void set_config_temperature(char* str){ 128 | #ifdef BUFFEROVERFLOW 129 | strcpy(temp_config.info, str); //buffer overflow (on purpose)!!! 130 | #else 131 | strncpy(temp_config.info, str, 15); 132 | #endif 133 | } 134 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile to compile the self-healing TrustZone based FreeRTOS 3 | # 4 | # @author: Michael Denzel 5 | # @contact: https://github.com/mdenzel 6 | # @license: GNU General Public License 2.0 or later 7 | # @date: 2017-03-17 8 | # @version: 0.1 9 | # 10 | 11 | # --- INIT --- 12 | CROSS_PREFIX= arm-none-eabi- 13 | AS = $(CROSS_PREFIX)as 14 | CC = $(CROSS_PREFIX)gcc 15 | LD = $(CROSS_PREFIX)ld 16 | OBJCOPY = $(CROSS_PREFIX)objcopy 17 | OBJDUMP = $(CROSS_PREFIX)objdump 18 | 19 | # --- OBJECTS --- 20 | BUILD_DIR = build 21 | OBJS += $(BUILD_DIR)/entry.o #has to be the first entry! 22 | OBJS += $(BUILD_DIR)/main.o 23 | #Drivers 24 | OBJS += $(BUILD_DIR)/mxc_serial.o 25 | OBJS += $(BUILD_DIR)/IO.o 26 | #Analysis 27 | OBJS += $(BUILD_DIR)/timing.o 28 | #Interrupts/TrustZone 29 | OBJS += $(BUILD_DIR)/interrupts.o 30 | OBJS += $(BUILD_DIR)/trustzone.o 31 | #Self-healing 32 | OBJS += $(BUILD_DIR)/selfhealing.o 33 | #General 34 | OBJS += $(BUILD_DIR)/kernelpanic.o 35 | OBJS += $(BUILD_DIR)/exceptions.o 36 | #Tasks 37 | OBJS += $(BUILD_DIR)/controltasks.o 38 | # FreeRTOS Core 39 | OBJS += $(BUILD_DIR)/FreeRTOS/croutine.o 40 | OBJS += $(BUILD_DIR)/FreeRTOS/list.o 41 | OBJS += $(BUILD_DIR)/FreeRTOS/queue.o 42 | OBJS += $(BUILD_DIR)/FreeRTOS/tasks.o 43 | # Selected HEAP implementation for FreeRTOS 44 | OBJS += $(BUILD_DIR)/FreeRTOS/MemMang/heap_4.o 45 | # FreeRTOS portable layer 46 | OBJS += $(BUILD_DIR)/FreeRTOS/GCC/port.o 47 | OBJS += $(BUILD_DIR)/FreeRTOS/GCC/portisr.o 48 | 49 | 50 | 51 | # --- FLAGS --- 52 | override CFLAGS += -Wall -nostdlib -nostartfiles -ffreestanding -mcpu=cortex-a8 -DCORTEX_A8 -I Demo -I Demo/Drivers -I Demo/TrustZone -I Demo/Tasks -I Demo/Analysis -I FreeRTOS/Source/include -I FreeRTOS/Source/portable/GCC -I FreeRTOS/Source/portable/MemMang -std=c99 -DTRUSTZONE 53 | ASFLAGS = -Wall -mcpu=cortex-a8 54 | CPPFLAGS = -DTRUSTZONE 55 | LDFLAGS = -L "/usr/lib/gcc/arm-none-eabi/5.2.0" -lgcc -L "/usr/arm-none-eabi/lib" -lc 56 | 57 | # --- Compilation --- 58 | .phony: all noTZ dir clean debug smc info timingTz timingNoTz 59 | 60 | all: clean dir kernel.img 61 | 62 | noTz: CFLAGS:=$(filter-out -DTRUSTZONE,$(CFLAGS)) 63 | noTz: CPPFLAGS:=$(filter-out -DTRUSTZONE,$(CPPFLAGS)) 64 | noTz: all 65 | 66 | debug: CFLAGS += -DDEBUG 67 | debug: CPPFLAGS += -DDEBUG 68 | debug: info 69 | 70 | smc: CFLAGS += -DPRINTSMC 71 | smc: CPPFLAGS += -DPRINTSMC 72 | smc: info 73 | 74 | info: CFLAGS += -DINFO 75 | info: CPPFLAGS += -DINFO 76 | info: all 77 | 78 | timingTz: CFLAGS += -DTIMING 79 | timingTz: CPPFLAGS += -DTIMING 80 | timingTz: all 81 | 82 | timingNoTz: CFLAGS += -DTIMING 83 | timingNoTz: CFLAGS:=$(filter-out -DTRUSTZONE,$(CFLAGS)) 84 | timingNoTz: CPPFLAGS += -DTIMING 85 | timingNoTz: CPPFLAGS:=$(filter-out -DTRUSTZONE,$(CPPFLAGS)) 86 | timingNoTz: all 87 | 88 | dir: 89 | @mkdir -p $(BUILD_DIR) 90 | @mkdir -p $(BUILD_DIR)/FreeRTOS 91 | @mkdir -p $(BUILD_DIR)/FreeRTOS/GCC 92 | @mkdir -p $(BUILD_DIR)/FreeRTOS/MemMang 93 | 94 | clean: 95 | @rm -f $(BUILD_DIR)/*.o $(BUILD_DIR)/*.elf $(BUILD_DIR)/*.asm *.img 96 | @rm -fr $(BUILD_DIR) 97 | 98 | # --- RULES --- 99 | 100 | #application 101 | $(BUILD_DIR)/%.o: Demo/%.s 102 | # call the c preprocessor also on asm files 103 | @cpp $(CPPFLAGS) $< > $(BUILD_DIR)/$*.s 104 | @$(AS) $(ASFLAGS) $(BUILD_DIR)/$*.s -o $@ >/dev/null 105 | 106 | $(BUILD_DIR)/%.o: Demo/%.c 107 | @$(CC) $(CFLAGS) -c $< -o $@ 108 | 109 | $(BUILD_DIR)/%.o: Demo/Analysis/%.c 110 | @$(CC) $(CFLAGS) -c $< -o $@ 111 | 112 | $(BUILD_DIR)/%.o: Demo/Drivers/%.c 113 | @$(CC) $(CFLAGS) -c $< -o $@ 114 | 115 | $(BUILD_DIR)/%.o: Demo/TrustZone/%.c 116 | @$(CC) $(CFLAGS) -c $< -o $@ 117 | 118 | $(BUILD_DIR)/%.o: Demo/Tasks/%.c 119 | @$(CC) $(CFLAGS) -c $< -o $@ 120 | 121 | #FreeRTOS 122 | $(BUILD_DIR)/FreeRTOS/%.o: FreeRTOS/Source/%.c 123 | @$(CC) $(CFLAGS) -c $< -o $@ 124 | 125 | $(BUILD_DIR)/FreeRTOS/GCC/%.o: FreeRTOS/Source/portable/GCC/%.c 126 | @$(CC) $(CFLAGS) -c $< -o $@ 127 | 128 | $(BUILD_DIR)/FreeRTOS/MemMang/%.o: FreeRTOS/Source/portable/MemMang/%.c 129 | @$(CC) $(CFLAGS) -c $< -o $@ 130 | 131 | 132 | # --- TARGET --- 133 | kernel.img: kernel.ld $(OBJS) 134 | @$(CC) $(OBJS) -Wl,-T kernel.ld -Wl,$(LDFLAGS) -nostartfiles -o $(BUILD_DIR)/kernel.elf 135 | @$(OBJDUMP) -D $(BUILD_DIR)/kernel.elf > $(BUILD_DIR)/kernel.asm #for debugging purposes 136 | @$(OBJCOPY) $(BUILD_DIR)/kernel.elf -O binary kernel.img 137 | -------------------------------------------------------------------------------- /Demo/TrustZone/TZIC.h: -------------------------------------------------------------------------------- 1 | /** 2 | * TrustZone Interrupt Controller (TZIC) registers for i.MX53 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | #ifndef _TZIC_INTC_H_ 12 | #define _TZIC_INTC_H_ 13 | 14 | //REMARK: iMX53 has no GIC (generic interrupt controller) 15 | // only TZIC (trustzone interrupt controller) 16 | 17 | #define __REG(x) (*((volatile unsigned int *)(x))) 18 | 19 | #define TZIC_TOTAL_IRQ 128 20 | 21 | #define TZIC_BASE (0x0FFFC000) 22 | 23 | //Basic Controls 24 | #define TZIC_INTCTRL (TZIC_BASE + 0x000) 25 | #define TZIC_INTTYPE (TZIC_BASE + 0x004) 26 | //according to documentation 0x008 is skipped! 27 | #define TZIC_PRIOMASK (TZIC_BASE + 0x00C) 28 | 29 | #define TZIC_SYNCCTRL (TZIC_BASE + 0x010) 30 | #define TZIC_DSMINT (TZIC_BASE + 0x014) 31 | 32 | //Interrupt Security FIQ 33 | #define TZIC_INTSEC0 (TZIC_BASE + 0x080) 34 | #define TZIC_INTSEC1 (TZIC_BASE + 0x084) 35 | #define TZIC_INTSEC2 (TZIC_BASE + 0x088) 36 | #define TZIC_INTSEC3 (TZIC_BASE + 0x08C) 37 | 38 | //Enable Set/Clear Register 39 | #define TZIC_ENSET0 (TZIC_BASE + 0x100) 40 | #define TZIC_ENSET1 (TZIC_BASE + 0x104) 41 | #define TZIC_ENSET2 (TZIC_BASE + 0x108) 42 | #define TZIC_ENSET3 (TZIC_BASE + 0x10C) 43 | #define TZIC_ENCLEAR0 (TZIC_BASE + 0x180) 44 | #define TZIC_ENCLEAR1 (TZIC_BASE + 0x184) 45 | #define TZIC_ENCLEAR2 (TZIC_BASE + 0x188) 46 | #define TZIC_ENCLEAR3 (TZIC_BASE + 0x18C) 47 | 48 | //Source Set/Clear Register 49 | #define TZIC_SRCSET0 (TZIC_BASE + 0x200) 50 | #define TZIC_SRCSET1 (TZIC_BASE + 0x204) 51 | #define TZIC_SRCSET2 (TZIC_BASE + 0x208) 52 | #define TZIC_SRCSET3 (TZIC_BASE + 0x20C) 53 | #define TZIC_SRCCLEAR0 (TZIC_BASE + 0x280) 54 | #define TZIC_SRCCLEAR1 (TZIC_BASE + 0x284) 55 | #define TZIC_SRCCLEAR2 (TZIC_BASE + 0x288) 56 | #define TZIC_SRCCLEAR3 (TZIC_BASE + 0x28C) 57 | 58 | //Priority Register 59 | #define TZIC_PRIORITY0 (TZIC_BASE + 0x400) 60 | #define TZIC_PRIORITY1 (TZIC_BASE + 0x404) 61 | #define TZIC_PRIORITY2 (TZIC_BASE + 0x408) 62 | #define TZIC_PRIORITY3 (TZIC_BASE + 0x40C) 63 | #define TZIC_PRIORITY4 (TZIC_BASE + 0x410) 64 | #define TZIC_PRIORITY5 (TZIC_BASE + 0x414) 65 | #define TZIC_PRIORITY6 (TZIC_BASE + 0x418) 66 | #define TZIC_PRIORITY7 (TZIC_BASE + 0x41C) 67 | #define TZIC_PRIORITY8 (TZIC_BASE + 0x420) 68 | #define TZIC_PRIORITY9 (TZIC_BASE + 0x424) 69 | #define TZIC_PRIORITY10 (TZIC_BASE + 0x428) 70 | #define TZIC_PRIORITY11 (TZIC_BASE + 0x42C) 71 | #define TZIC_PRIORITY12 (TZIC_BASE + 0x430) 72 | #define TZIC_PRIORITY13 (TZIC_BASE + 0x434) 73 | #define TZIC_PRIORITY14 (TZIC_BASE + 0x438) 74 | #define TZIC_PRIORITY15 (TZIC_BASE + 0x43C) 75 | #define TZIC_PRIORITY16 (TZIC_BASE + 0x440) 76 | #define TZIC_PRIORITY17 (TZIC_BASE + 0x444) 77 | #define TZIC_PRIORITY18 (TZIC_BASE + 0x448) 78 | #define TZIC_PRIORITY19 (TZIC_BASE + 0x44C) 79 | #define TZIC_PRIORITY20 (TZIC_BASE + 0x450) 80 | #define TZIC_PRIORITY21 (TZIC_BASE + 0x454) 81 | #define TZIC_PRIORITY22 (TZIC_BASE + 0x458) 82 | #define TZIC_PRIORITY23 (TZIC_BASE + 0x45C) 83 | #define TZIC_PRIORITY24 (TZIC_BASE + 0x460) 84 | #define TZIC_PRIORITY25 (TZIC_BASE + 0x464) 85 | #define TZIC_PRIORITY26 (TZIC_BASE + 0x468) 86 | #define TZIC_PRIORITY27 (TZIC_BASE + 0x46C) 87 | #define TZIC_PRIORITY28 (TZIC_BASE + 0x470) 88 | #define TZIC_PRIORITY29 (TZIC_BASE + 0x474) 89 | #define TZIC_PRIORITY30 (TZIC_BASE + 0x478) 90 | #define TZIC_PRIORITY31 (TZIC_BASE + 0x47C) 91 | 92 | //Pending Register 93 | //low priority 94 | #define TZIC_PND0 (TZIC_BASE + 0xD00) 95 | #define TZIC_PND1 (TZIC_BASE + 0xD04) 96 | #define TZIC_PND2 (TZIC_BASE + 0xD08) 97 | #define TZIC_PND3 (TZIC_BASE + 0xD0C) 98 | //high priority 99 | #define TZIC_HIPND0 (TZIC_BASE + 0xD80) 100 | #define TZIC_HIPND1 (TZIC_BASE + 0xD84) 101 | #define TZIC_HIPND2 (TZIC_BASE + 0xD88) 102 | #define TZIC_HIPND3 (TZIC_BASE + 0xD8C) 103 | 104 | //Wakeup Config Register 105 | #define TZIC_WAKEUP0 (TZIC_BASE + 0xE00) 106 | #define TZIC_WAKEUP1 (TZIC_BASE + 0xE04) 107 | #define TZIC_WAKEUP2 (TZIC_BASE + 0xE08) 108 | #define TZIC_WAKEUP3 (TZIC_BASE + 0xE0C) 109 | 110 | //Software Interrupt Trigger Register 111 | #define TZIC_SWINT (TZIC_BASE + 0xF00) 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /Demo/Drivers/mxc_serial.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Printing functionality (via serial cable). 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | * 10 | * XXX: file is based on code from (but then changed quite heavily) 11 | * Dongli Zhang https://github.com/finallyjustice/imx53qsb-code "trustzone-smc" 12 | **/ 13 | 14 | //own 15 | #include "config.h" 16 | #include "mxc_serial.h" 17 | //C includes 18 | #include //for vsnprintf 19 | #include //for var args 20 | 21 | // set the iomuxc policy to enable serial port I/O 22 | void iomuxc_init(void){ 23 | //enable ALT2 in CSI0_DAT10 for TXD_MUX 24 | __REG(IOMUXC_BASE_ADDR + IOMUXC_CSI0_DAT10) = 0b00010; //SION=0, ALT2 25 | 26 | //enable ALT2 in CSI0_DAT11 for RXD_MUX 27 | __REG(IOMUXC_BASE_ADDR + IOMUXC_CSI0_DAT11) = 0b00010; //SION=0, ALT2 28 | 29 | //daisy chain setup 30 | // IOMUXC_UART1_IPP_UART_RXD_MUX_SELECT_INPUT = 0x878 31 | __REG(IOMUXC_BASE_ADDR + 0x878) = 0x1; 32 | } 33 | 34 | static void mxc_serial_putc(const char c){ 35 | //write character 36 | __REG(UART_PHYS + UTXD) = c; 37 | 38 | //wait until character was consumed 39 | while(!(__REG(UART_PHYS + UTS) & UTS_TXEMPTY)); 40 | 41 | if(c == '\n'){ 42 | mxc_serial_putc('\r'); 43 | } 44 | } 45 | 46 | static int mxc_serial_getc(char* const c){ 47 | //check if there is something to read 48 | if(__REG(UART_PHYS + UTS) & UTS_RXEMPTY){ 49 | return -1; 50 | } 51 | 52 | //get value and check for errors 53 | int r = __REG(UART_PHYS + URXD); 54 | if((r & 0xFC00) != 0x8000){ //ready bit should be set 55 | return r; 56 | } 57 | 58 | //read character 59 | *c = (char)(r & 0xFF); 60 | return 0; 61 | } 62 | 63 | unsigned int readline(char* const buf, const unsigned int size){ 64 | //variables 65 | unsigned int i = 0; 66 | int err = 0; 67 | 68 | //while buf still has space and no error 69 | while(i < size-1 && err == 0){ 70 | //get char 71 | err = mxc_serial_getc(&buf[i]); 72 | 73 | //check errors 74 | if(err == 0){ 75 | //stop at newline 76 | if(buf[i] == '\n' || buf[i] == '\r'){ 77 | break; 78 | } 79 | 80 | //next value 81 | ++i; 82 | } 83 | else if(err == -1){ 84 | //empty input 85 | if(i == 0){ 86 | //nothing read yet => stop 87 | break; 88 | }else{ 89 | //some characters were already read => wait for the rest of them 90 | err = 0; 91 | continue; 92 | } 93 | }else{ 94 | //serious error => stop reading 95 | cprintf("getc error: %x\n", err); 96 | break; 97 | } 98 | } 99 | 100 | buf[i] = '\0'; 101 | return i; 102 | } 103 | 104 | void mxc_serial_init(void){ 105 | //wait until UART transmission is empty 106 | //while(!(__REG(UART_PHYS + UTS) & UTS_TXEMPTY)); 107 | 108 | //disable UART 109 | __REG(UART_PHYS + UCR1) &= ~UCR1_UARTEN; 110 | //reset 111 | __REG(UART_PHYS + UCR1) = 0x0; 112 | __REG(UART_PHYS + UCR2) = 0x0; 113 | while(!(__REG(UART_PHYS + UCR2) & UCR2_SRST)); //wait for software reset (SRST) 114 | 115 | //enable uart 116 | __REG(UART_PHYS + UCR1) = UCR1_UARTEN; 117 | 118 | // set to 8N1 (no parity) 119 | __REG(UART_PHYS + UCR2) &= ~UCR2_PREN; //disable parity check "N" 120 | __REG(UART_PHYS + UCR2) |= UCR2_WS; //word size 8 121 | __REG(UART_PHYS + UCR2) &= ~UCR2_STPB; //1 stop bit 122 | //ignore RTS (req to send => always just send) 123 | __REG(UART_PHYS + UCR2) |= UCR2_IRTS; 124 | //set CTS control not needed 125 | //enable FIFOs = enable read; enable write; no reset 126 | __REG(UART_PHYS + UCR2) |= UCR2_TXEN | UCR2_RXEN | UCR2_SRST; 127 | 128 | //DSR|DCD|RI; RXDMUXSEL (must be 1) 129 | __REG(UART_PHYS + UCR3) = 0x0704; 130 | //CTS trigger level does not matter 131 | __REG(UART_PHYS + UCR4) = 0x8000; 132 | //uart escape character (2b = '+') 133 | __REG(UART_PHYS + UESC) = 0x002b; 134 | //escape timer max 2ms 135 | __REG(UART_PHYS + UTIM) = 0x0; 136 | //reset UTS 137 | __REG(UART_PHYS + UTS) = 0x0060; //TXEMPTY and RXEMPTY = 1 138 | 139 | //set frequency 140 | const unsigned int clk = 33300000; //33.3MHz 141 | __REG(UART_PHYS + UFCR) = 0x0A1E; //TxFIFO int <2 chars; divide input clock by 2 (RFDIV 0b100 = RFDIV 2); RxFIFO int 30 chars 142 | __REG(UART_PHYS + ONEMS) = clk / 2 / 1000; // frequency / RFDIV / 1000 143 | __REG(UART_PHYS + UBIR) = 0xf; //clock 33.3 MHz => baudrate = clk / (16 * (UBMR+1) / (UBIR+1)) 144 | __REG(UART_PHYS + UBMR) = 0x121; 145 | 146 | //clear status flags 147 | __REG(UART_PHYS + USR2) |= USR2_ADET | USR2_IDLE | USR2_IRINT | USR2_WAKE | USR2_RTSF; 148 | __REG(UART_PHYS + USR2) |= USR2_BRCD | USR2_ORE | USR2_RDR; 149 | 150 | //enable controller (XXX: FIFO Interrupts would be IRQ 31) 151 | __REG(UART_PHYS + UCR1) = UCR1_UARTEN; 152 | 153 | return; 154 | } 155 | 156 | void cprintf(char *fmt, ...) 157 | { 158 | const unsigned int len = 256; 159 | char s[len]; 160 | va_list ap; 161 | 162 | //get var args and print them to s 163 | va_start(ap, fmt); 164 | vsnprintf(s, len-1, fmt, ap); 165 | va_end(ap); 166 | 167 | //print s 168 | for(unsigned int i = 0; i < len; ++i){ 169 | if(s[i] == '\0'){ 170 | break; 171 | } 172 | mxc_serial_putc(s[i]); 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | This repository was archived and is no longer maintained. 3 | 4 | 5 | # Self-healing FreeRTOS 6 | 7 | ``` 8 | @author: Michael Denzel 9 | @license: GNU General Public License 2.0 or later 10 | ``` 11 | 12 | A **_proof-of-concept implementation_** of an ARM TrustZone port of FreeRTOS 13 | V9.0.0rc1 which can automatically self-heal from certain attacks and runs on top 14 | of ARM TrustZone. 15 | 16 | Source code includes code from: 17 | - FreeRTOS V9.0.0rc1 -- www.freertos.org 18 | - Dongli Zhang -- https://github.com/finallyjustice/imx53qsb-code "trustzone-smc" 19 | - James Walmsley -- https://github.com/jameswalmsley/RaspberryPi-FreeRTOS 20 | - Francesco Balducci -- https://balau82.wordpress.com/2010/12/16/using-newlib-in-arm-bare-metal-program 21 | 22 | 23 | 24 | ## Quickstart 25 | 26 | Compile the tool using: 27 | 28 | ``` 29 | $ make 30 | $ ./setupsd.sh /dev/sdX 31 | ``` 32 | 33 | `/dev/sdX` is the path to the SD-card which should be flashed with the image. 34 | 35 | **Test system: Freescale i.MX53 Quick Start Board _ARM Cortex-A8_** 36 | 37 | Required tools: 38 | - arm-none-eabi-gcc (worked with version 5.2.0, arm-none-eabi-as/-ld 2.27) 39 | - arm-none-eabi-binutils 40 | - arm-none-eabi-newlib 41 | - uboot-utils (for mkimage, worked with version 2016.05) 42 | - (minicom or similar) 43 | 44 | To connect to the board: 45 | ``` 46 | $ minicom -s -c on 47 | 48 | goto Serial port setup and set the following: 49 | Serial Device: /dev/ttyUSB0 (or where mounted) 50 | Callin Program: (empty) 51 | Callout Program: (empty) 52 | Bps/Par/Bits: 115200 8N1 53 | Hardware Flow Control: No (important!) 54 | Software Flow Control: No 55 | 56 | (start) 57 | ``` 58 | 59 | 60 | ## Makefile Options 61 | 62 | There are a couple of Makefile options: 63 | 64 | ### Cleanup 65 | 66 | Use `make clean` to clean the compiled files. 67 | 68 | ### Logging and Printing 69 | 70 | - `make info` - print some logging information 71 | - `make smc` - print also the secure monitor calls (includes `info`) 72 | - `make debug` - very verbose logging level (includes `info` and `smc`) 73 | 74 | ### Timing analysis 75 | 76 | - `make timingTz` - will compile a special image used for timing TrustZone 77 | - `make timingNoTz` - will compile a special image used for timing the system without TrustZone 78 | 79 | ### TrustZone 80 | 81 | Normally the operating system will always be compiled for TrustZone. If that is 82 | not desired, there is the option to compile using `make noTz`, even though we 83 | recommend to compile with TrustZone. 84 | 85 | #### World Switches 86 | 87 | TrustZone is split into two worlds (`normal world` and `secure world`) which are 88 | separated by the so-called monitor. The following drawings demonstrate the switches 89 | in the implemented Trustzone FreeRTOS: 90 | 91 | ![World Switch](./2023-11-27_Worldswitch.png "World Switch") 92 | 93 | ![World Switch Code](./2023-11-27_Worldswitch_Code.png "World Switch Code") 94 | 95 | 96 | ## Attack and Self-healing 97 | 98 | **Remark: by default the buffer overflow was turned off. To turn it on, one has 99 | to supply the compilation flag `BUFFEROVERFLOW`. See also file 100 | `./Demo/Drivers/IO.c`. Note that there is no Makefile option to supply this 101 | flag directly to prevent accidentally compiling a vulnerable image.** 102 | 103 | ### Background 104 | 105 | To test the self-healing capabilities of our adjusted FreeRTOS operating system, 106 | we simulated a simple temperature sensor and included a buffer overflow using 107 | the vulnerable C function `strcpy` (see `./Demo/Drivers/IO.c`). 108 | 109 | The function `set_config_temperature` can update the struct of the temperature 110 | sensor with a new "info" string. However, the buffer is only 16 bytes long and 111 | can be overflowed. This enables an attacker to change the `max` and `min` 112 | temperature fields (and of course various other memory attacks). 113 | 114 | Our self-healing capability (see `./Demo/TrustZone/selfhealing.c::detection()`) 115 | checks that the `max` temperature is below 100 degrees for task3. **Note: this 116 | is just a proof-of-concept implementation, a full implementation would have to 117 | check also the `min` temperature, the variables of task1 and task2, that no 118 | further tasks exists, and so on. But, this should be enough to demonstrate the 119 | basic idea of self-healing** 120 | 121 | ### Example Run 122 | 123 | The following picture shows an example run of `./attack.sh` which overwrites the 124 | `max` temperature with 150 degrees. User inputs are highlighted in green, these 125 | are in this case the actual attack input. 126 | 127 | ![Attack example](./attack.png "Attack example") 128 | 129 | Explanations: 130 | 131 | After all three tasks are started, the attacker updates the "info" string to 132 | 1234561234567890 plus the binary number for 150. On can see three lines later 133 | that FreeRTOS reports back the temperature as `[0; 150]`. Immediately 134 | afterwards, self-healing takes place which can be seen at the reset task3 (it 135 | says again "task3 start" because task3 was deleted and restarted). When the 136 | attacker sends the next `status` command, the system already reset the 137 | temperature to the initial value `[0; 100]` and "info" to the initial value 138 | "init". 139 | 140 | This implementation is not bulletproof of course. An adversary could still 141 | attack the self-healing functionality directly or circumvent it another way. 142 | However, since the self-healing functionality is part of the ARM TrustZone 143 | secure world, this is considerably more effort. 144 | 145 | 146 | ## Known Issues 147 | 148 | - bug in the interrupt system 149 | -------------------------------------------------------------------------------- /Demo/Tasks/controltasks.c: -------------------------------------------------------------------------------- 1 | /** 2 | * A few tasks to demonstrate self-healing FreeRTOS. 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | //lib 12 | #include 13 | #include 14 | #include //for atoi 15 | #include //strcpy 16 | 17 | //own includes 18 | #include "controltasks.h" 19 | #include "mxc_serial.h" 20 | #include "IO.h" 21 | #include "interrupts.h" 22 | #include "trustzone.h" //for print_WORLD and print_MODE 23 | #include "timing.h" 24 | 25 | // --- TASKS --- 26 | char* const TASK_NAMES[NUM_TASKS] = {"task1", "task2", "task3"}; 27 | const unsigned int TASK_PRIOS[NUM_TASKS] = {configMAX_PRIORITIES, 1, 2}; 28 | void (*TASK_FUNCTIONS[NUM_TASKS])(void*) = {controltask, controltask, controltask}; 29 | 30 | 31 | // --- UTILITY --- 32 | void ListTasks(){ 33 | //roughly 40bytes per task => 64 bytes per task should be sufficient 34 | //(plus IDLE plus restoration) 35 | char* tasklist = malloc(64*uxTaskGetNumberOfTasks()); 36 | vTaskList(tasklist); 37 | cprintf("\ntasklist:\n"); 38 | cprintf("task\t\tstate\tprio\tstack\ttasknum\n"); 39 | cprintf("---------------------------------------------------\n"); 40 | cprintf(tasklist); 41 | cprintf("('B'locked, 'R'eady, 'D'eleted, 'S'uspended)\n"); 42 | cprintf("\n"); 43 | free(tasklist); 44 | tasklist = NULL; 45 | } 46 | 47 | // --- OWN TASK IMPLEMENTATION --- 48 | void controltask(void *pParam){ 49 | cprintf("%s start\n", (char*)pParam); 50 | 51 | //init 52 | const unsigned int num = atoi( ((char*)pParam)+4 ); 53 | 54 | //local variables 55 | const portTickType delay = num /*seconds*/ * portTICK_PERIOD_MS; 56 | 57 | //run 58 | while(1) { 59 | //functionality 60 | #ifdef INFO 61 | cprintf("%s IRQ: %d, FIQ: %d\n", (char*)pParam, CheckIRQ(), CheckFIQ()); 62 | print_MODE(); 63 | print_WORLD(); 64 | #endif 65 | 66 | switch(num){ 67 | case 1: 68 | //task 1: toggle LED every second 69 | set_led(OFF); 70 | vTaskDelay(delay*2); 71 | set_led(ON); 72 | vTaskDelay(delay*2); 73 | break; 74 | case 2: 75 | //task 2: first attacks 76 | /* 77 | //timer IRQ 78 | cprintf("trying to register IRQ 40\n"); 79 | cprintf("result: %d\n", RegisterInterrupt(40, NULL, NULL)); 80 | 81 | //undefined SMC 82 | cprintf("undefined SMC\n"); 83 | __asm volatile("SMC #14"); 84 | 85 | //reset interrupt controller 86 | cprintf("reset interrupt controller\n"); 87 | InitInterruptController(); 88 | 89 | //set temp 90 | cprintf("overheating...\n"); 91 | char attack[21]; //overflow by 5 bytes (=int for max temp + '\0') 92 | strcpy(attack, "1234567890123456"); //fill buffer 93 | *((int*)(attack+16)) = 150; //overflow => set max temp integer 94 | attack[20] = '\0'; //null-termination (will affect min temp if min temp != 0) 95 | set_config_temperature(attack); 96 | cprintf("max: %d\n", get_config_temperature().max); 97 | 98 | //DoS 99 | //FIXME: DoS actually works against FreeRTOS: the idle task is suppose to clean up the tasklist and free memory 100 | //FIXME: it is possible that tasks starve with the FreeRTOS scheduler! (it apparently relies on tasks to be somewhat cooperative => they have to call vTaskDelay at some point if they have a high priority) 101 | //cprintf("DoS\n"); 102 | //while(1); 103 | */ 104 | 105 | /* 106 | ; 107 | init_timer(); 108 | const unsigned int s = 88; //sizeof(struct tskTaskControlBlock) = 88 109 | for(unsigned int i = 0; i < 1530; ++i){ 110 | start_timer(); 111 | void* p = malloc(s); 112 | unsigned int t = stop_timer(); 113 | cprintf("malloc %u: %u ns\n", i, t); 114 | free(p); 115 | } 116 | */ 117 | 118 | cprintf("temperature logging: %d\n", check_temperature()); 119 | vTaskDelay(delay * 2); 120 | 121 | 122 | break; 123 | case 3: 124 | //task 3: read user input 125 | { 126 | //variables 127 | const unsigned int size = 128; 128 | char buf[size]; 129 | buf[0] = '\0'; 130 | #ifdef INFO 131 | cprintf("%s reading user input\n", (char*)pParam); 132 | #endif 133 | //blocking read 134 | if(readline(buf, size) != 0){ 135 | //user input in colour 136 | cprintf("\e[1;32muser input: '%s'\e[0m\n", buf); 137 | 138 | //handle user input 139 | if(strcmp(buf, "status") == 0){ 140 | //print status 141 | temperature conf = get_config_temperature(); 142 | int t = check_temperature(); 143 | cprintf("config: '%s'\n[%d; %d]\ntemp: %d\n", conf.info, conf.min, conf.max, t); 144 | } 145 | else if(strncmp(buf, "update ", 7) == 0){ 146 | //update sensor.info (incl. a buffer overflow depending on compilation) 147 | cprintf("updating\n"); 148 | set_config_temperature(buf+7); 149 | temperature conf = get_config_temperature(); 150 | cprintf("config: '%s'\n[%d; %d]\n", conf.info, conf.min, conf.max); 151 | } 152 | //else: ignore 153 | } 154 | //sleep 155 | vTaskDelay(delay); 156 | } 157 | break; 158 | 159 | default: 160 | #ifdef INFO 161 | cprintf("%s going to sleep\n", (char*)pParam); 162 | #endif 163 | //sleep 164 | vTaskDelay(10 * portTICK_PERIOD_MS); 165 | } 166 | } 167 | 168 | //should never happen, just for safety 169 | vTaskDelete(NULL); 170 | } 171 | -------------------------------------------------------------------------------- /FreeRTOS/Source/portable/MemMang/heap_3.c: -------------------------------------------------------------------------------- 1 | /* 2 | FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd. 3 | All rights reserved 4 | 5 | VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 6 | 7 | This file is part of the FreeRTOS distribution. 8 | 9 | FreeRTOS is free software; you can redistribute it and/or modify it under 10 | the terms of the GNU General Public License (version 2) as published by the 11 | Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. 12 | 13 | *************************************************************************** 14 | >>! NOTE: The modification to the GPL is included to allow you to !<< 15 | >>! distribute a combined work that includes FreeRTOS without being !<< 16 | >>! obliged to provide the source code for proprietary components !<< 17 | >>! outside of the FreeRTOS kernel. !<< 18 | *************************************************************************** 19 | 20 | FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 22 | FOR A PARTICULAR PURPOSE. Full license text is available on the following 23 | link: http://www.freertos.org/a00114.html 24 | 25 | *************************************************************************** 26 | * * 27 | * FreeRTOS provides completely free yet professionally developed, * 28 | * robust, strictly quality controlled, supported, and cross * 29 | * platform software that is more than just the market leader, it * 30 | * is the industry's de facto standard. * 31 | * * 32 | * Help yourself get started quickly while simultaneously helping * 33 | * to support the FreeRTOS project by purchasing a FreeRTOS * 34 | * tutorial book, reference manual, or both: * 35 | * http://www.FreeRTOS.org/Documentation * 36 | * * 37 | *************************************************************************** 38 | 39 | http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 40 | the FAQ page "My application does not run, what could be wrong?". Have you 41 | defined configASSERT()? 42 | 43 | http://www.FreeRTOS.org/support - In return for receiving this top quality 44 | embedded software for free we request you assist our global community by 45 | participating in the support forum. 46 | 47 | http://www.FreeRTOS.org/training - Investing in training allows your team to 48 | be as productive as possible as early as possible. Now you can receive 49 | FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 50 | Ltd, and the world's leading authority on the world's leading RTOS. 51 | 52 | http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 53 | including FreeRTOS+Trace - an indispensable productivity tool, a DOS 54 | compatible FAT file system, and our tiny thread aware UDP/IP stack. 55 | 56 | http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 57 | Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 58 | 59 | http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 60 | Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 61 | licenses offer ticketed support, indemnification and commercial middleware. 62 | 63 | http://www.SafeRTOS.com - High Integrity Systems also provide a safety 64 | engineered and independently SIL3 certified version for use in safety and 65 | mission critical applications that require provable dependability. 66 | 67 | 1 tab == 4 spaces! 68 | */ 69 | 70 | 71 | /* 72 | * Implementation of pvPortMalloc() and vPortFree() that relies on the 73 | * compilers own malloc() and free() implementations. 74 | * 75 | * This file can only be used if the linker is configured to to generate 76 | * a heap memory area. 77 | * 78 | * See heap_1.c, heap_2.c and heap_4.c for alternative implementations, and the 79 | * memory management pages of http://www.FreeRTOS.org for more information. 80 | */ 81 | 82 | #include 83 | 84 | /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 85 | all the API functions to use the MPU wrappers. That should only be done when 86 | task.h is included from an application file. */ 87 | #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 88 | 89 | #include "FreeRTOS.h" 90 | #include "task.h" 91 | 92 | #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 93 | 94 | /*-----------------------------------------------------------*/ 95 | 96 | void *pvPortMalloc( size_t xWantedSize ) 97 | { 98 | void *pvReturn; 99 | 100 | vTaskSuspendAll(); 101 | { 102 | pvReturn = malloc( xWantedSize ); 103 | traceMALLOC( pvReturn, xWantedSize ); 104 | } 105 | ( void ) xTaskResumeAll(); 106 | 107 | #if( configUSE_MALLOC_FAILED_HOOK == 1 ) 108 | { 109 | if( pvReturn == NULL ) 110 | { 111 | extern void vApplicationMallocFailedHook( void ); 112 | vApplicationMallocFailedHook(); 113 | } 114 | } 115 | #endif 116 | 117 | return pvReturn; 118 | } 119 | /*-----------------------------------------------------------*/ 120 | 121 | void vPortFree( void *pv ) 122 | { 123 | if( pv ) 124 | { 125 | vTaskSuspendAll(); 126 | { 127 | free( pv ); 128 | traceFREE( pv, 0 ); 129 | } 130 | ( void ) xTaskResumeAll(); 131 | } 132 | } 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /Demo/main.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Main file loading TrustZone, starting FreeRTOS, and running an example of 3 | * self-healing tasks (for i.MX53 board). 4 | * 5 | * @author: Michael Denzel 6 | * @contact: https://github.com/mdenzel 7 | * @license: GNU General Public License 2.0 or later 8 | * @date: 2017-03-17 9 | * @version: 0.1 10 | * 11 | * XXX: file includes code from 12 | * Dongli Zhang https://github.com/finallyjustice/imx53qsb-code "trustzone-smc" 13 | * and 14 | * James Walmsley https://github.com/jameswalmsley/RaspberryPi-FreeRTOS 15 | * and 16 | * Francesco Balducci https://balau82.wordpress.com/2010/12/16/using-newlib-in-arm-bare-metal-programs/ 17 | **/ 18 | 19 | //lib 20 | #include 21 | #include 22 | #include //for _sbrk 23 | #include //for malloc 24 | #include //for sprintf 25 | 26 | //own includes 27 | //Drivers 28 | #include "mxc_serial.h" 29 | #include "kernelpanic.h" 30 | #include "IO.h" 31 | //TrustZone 32 | #include "interrupts.h" 33 | #include "trustzone.h" 34 | #include "selfhealing.h" 35 | //Tasks 36 | #include "controltasks.h" 37 | 38 | //Timing 39 | #ifdef TIMING 40 | #include "timing.h" 41 | #endif 42 | 43 | //globals 44 | #define R32 (volatile unsigned long *) 45 | #define CSU_BASE_ADDR 0x63F9C000 46 | 47 | //external variables 48 | extern TaskHandle_t restoration_task; 49 | 50 | //external functions 51 | extern void InitTrustzone(); 52 | extern void InitSecureWorldWithoutTrustZone(); 53 | 54 | enum{ 55 | CSL0 = CSU_BASE_ADDR + 0x00, 56 | CSL1 = CSU_BASE_ADDR + 0x04, 57 | CSL2 = CSU_BASE_ADDR + 0x08, // GPIO7 58 | CSL3 = CSU_BASE_ADDR + 0x0c, 59 | CSL4 = CSU_BASE_ADDR + 0x10, 60 | CSL5 = CSU_BASE_ADDR + 0x14, 61 | CSL6 = CSU_BASE_ADDR + 0x18, 62 | CSL7 = CSU_BASE_ADDR + 0x1c, 63 | CSL8 = CSU_BASE_ADDR + 0x20, 64 | CSL9 = CSU_BASE_ADDR + 0x24, 65 | CSL10 = CSU_BASE_ADDR + 0x28, 66 | CSL11 = CSU_BASE_ADDR + 0x2c, 67 | CSL12 = CSU_BASE_ADDR + 0x30, // GPIO7 68 | CSL13 = CSU_BASE_ADDR + 0x34, 69 | CSL14 = CSU_BASE_ADDR + 0x38, 70 | CSL15 = CSU_BASE_ADDR + 0x3c, 71 | CSL16 = CSU_BASE_ADDR + 0x40, 72 | CSL17 = CSU_BASE_ADDR + 0x44, 73 | CSL18 = CSU_BASE_ADDR + 0x48, 74 | CSL19 = CSU_BASE_ADDR + 0x4c, 75 | CSL20 = CSU_BASE_ADDR + 0x50, 76 | CSL21 = CSU_BASE_ADDR + 0x54, 77 | CSL22 = CSU_BASE_ADDR + 0x58, 78 | CSL23 = CSU_BASE_ADDR + 0x5c, 79 | CSL24 = CSU_BASE_ADDR + 0x60, 80 | CSL25 = CSU_BASE_ADDR + 0x64, // ESDHC 81 | CSL26 = CSU_BASE_ADDR + 0x68, 82 | CSL27 = CSU_BASE_ADDR + 0x6c, 83 | CSL28 = CSU_BASE_ADDR + 0x70, // ESDHC 84 | CSL29 = CSU_BASE_ADDR + 0x74, 85 | CSL30 = CSU_BASE_ADDR + 0x78, 86 | CSL31 = CSU_BASE_ADDR + 0x7c, 87 | }; 88 | 89 | void enable_hwfirewall(void){ 90 | *R32 CSL0 = 0x00ff00ff; 91 | *R32 CSL1 = 0x00ff00ff; 92 | *R32 CSL2 = 0x00ff00ff; 93 | *R32 CSL3 = 0x00ff00ff; 94 | *R32 CSL4 = 0x00ff00ff; 95 | *R32 CSL5 = 0x00ff00ff; 96 | *R32 CSL6 = 0x00ff00ff; 97 | *R32 CSL7 = 0x00ff00ff; 98 | *R32 CSL8 = 0x00ff00ff; 99 | *R32 CSL9 = 0x00ff00ff; 100 | *R32 CSL10 = 0x00ff00ff; 101 | *R32 CSL11 = 0x00ff00ff; 102 | *R32 CSL12 = 0x00ff00ff; 103 | *R32 CSL13 = 0x00ff00ff; 104 | *R32 CSL14 = 0x00ff00ff; 105 | *R32 CSL15 = 0x00ff00ff; 106 | *R32 CSL16 = 0x00ff00ff; 107 | *R32 CSL17 = 0x00ff00ff; 108 | *R32 CSL18 = 0x00ff00ff; 109 | *R32 CSL19 = 0x00ff00ff; 110 | *R32 CSL20 = 0x00ff00ff; 111 | *R32 CSL21 = 0x00ff00ff; 112 | *R32 CSL22 = 0x00ff00ff; 113 | *R32 CSL23 = 0x00ff00ff; 114 | *R32 CSL24 = 0x00ff00ff; 115 | *R32 CSL25 = 0x003b003b; 116 | *R32 CSL26 = 0x00ff00ff; 117 | *R32 CSL27 = 0x00ff00ff; 118 | *R32 CSL28 = 0x003b003b; 119 | *R32 CSL29 = 0x00ff00ff; 120 | *R32 CSL30 = 0x00ff00ff; 121 | *R32 CSL31 = 0x00ff00ff; 122 | } 123 | 124 | 125 | //XXX: heap trick from https://balau82.wordpress.com/2010/12/16/using-newlib-in-arm-bare-metal-programs/ 126 | char *heap_end = 0; 127 | caddr_t _sbrk(int incr) { 128 | extern char heap_low; //defined by the linker 129 | extern char heap_top; //defined by the linker 130 | char *prev_heap_end; 131 | 132 | if (heap_end == 0) { 133 | heap_end = &heap_low; 134 | } 135 | prev_heap_end = heap_end; 136 | 137 | if (heap_end + incr > &heap_top) { 138 | //heap and stack collision 139 | return (caddr_t)0; 140 | } 141 | 142 | heap_end += incr; 143 | return (caddr_t) prev_heap_end; 144 | } 145 | 146 | 147 | /** 148 | * Main entry point for system 149 | **/ 150 | void bootmain(void){ 151 | // --- INIT --- 152 | #ifdef TIMING 153 | //setup and start timer 154 | init_timer(); 155 | start_timer(); 156 | #endif 157 | //enable_hwfirewall allows printf in Normal World 158 | enable_hwfirewall(); 159 | //setup serial console 160 | iomuxc_init(); 161 | mxc_serial_init(); 162 | set_led(OFF); 163 | #ifdef TRUSTZONE 164 | //setup trustzone 165 | cprintf("init TrustZone\n"); 166 | InitTrustzone(); 167 | #else 168 | //setup secure world 169 | cprintf("init secure world without TrustZone\n"); 170 | InitSecureWorldWithoutTrustZone(); 171 | #endif 172 | //setup interrupts 173 | cprintf("init TZIC\n"); 174 | InitInterruptController(); //TrustZone Interrupt Controller TZIC 175 | ClearAllInterrupts(); 176 | #ifdef TIMING 177 | cprintf("startup time: %d ns\n", stop_timer()); 178 | cprintf("timing overhead: %d ns\n", get_timer_overhead()); 179 | #endif 180 | 181 | 182 | cprintf("\n============================\n=========== MAIN ===========\n============================\n"); 183 | print_MODE(); 184 | #ifdef TRUSTZONE 185 | //check trustzone 186 | if(SMC_is_secure_world() == 1){ 187 | cprintf("secure world\n"); 188 | }else{ 189 | kernelpanic("normal world even though trustzone enabled\n"); 190 | } 191 | #else 192 | cprintf("trustzone disabled\n"); 193 | #endif 194 | //print interrupts 195 | cprintf("IRQ: %d, FIQ: %d\n", CheckIRQ(), CheckFIQ()); 196 | 197 | // --- FreeRTOS --- 198 | cprintf("\n--- FreeRTOS (%s) ---\n", tskKERNEL_VERSION_NUMBER); 199 | //create tasks 200 | //idle task is automatically created by scheduler 201 | for(unsigned int i = 0; i < NUM_TASKS; ++i){ 202 | //xTaskCreate(function, name, stacksize, parameter, priority, handle); 203 | if(xTaskCreate(TASK_FUNCTIONS[i], TASK_NAMES[i], 256, 204 | TASK_NAMES[i], TASK_PRIOS[i], NULL) != pdPASS){ 205 | char* err = malloc(32); 206 | sprintf(err, "could not create task %u\n", i); 207 | kernelpanic(err); 208 | } 209 | } 210 | 211 | //list tasks 212 | ListTasks(); 213 | 214 | //start scheduling 215 | cprintf("scheduler\n"); 216 | vTaskStartScheduler(); 217 | 218 | //we should never return from the main! 219 | kernelpanic("main returned\n"); 220 | } 221 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/FreeRTOSConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd. 3 | 4 | 5 | *************************************************************************** 6 | * * 7 | * FreeRTOS tutorial books are available in pdf and paperback. * 8 | * Complete, revised, and edited pdf reference manuals are also * 9 | * available. * 10 | * * 11 | * Purchasing FreeRTOS documentation will not only help you, by * 12 | * ensuring you get running as quickly as possible and with an * 13 | * in-depth knowledge of how to use FreeRTOS, it will also help * 14 | * the FreeRTOS project to continue with its mission of providing * 15 | * professional grade, cross platform, de facto standard solutions * 16 | * for microcontrollers - completely free of charge! * 17 | * * 18 | * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * 19 | * * 20 | * Thank you for using FreeRTOS, and thank you for your support! * 21 | * * 22 | *************************************************************************** 23 | 24 | 25 | This file is part of the FreeRTOS distribution. 26 | 27 | FreeRTOS is free software; you can redistribute it and/or modify it under 28 | the terms of the GNU General Public License (version 2) as published by the 29 | Free Software Foundation AND MODIFIED BY the FreeRTOS exception. 30 | >>>NOTE<<< The modification to the GPL is included to allow you to 31 | distribute a combined work that includes FreeRTOS without being obliged to 32 | provide the source code for proprietary components outside of the FreeRTOS 33 | kernel. FreeRTOS is distributed in the hope that it will be useful, but 34 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 35 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 36 | more details. You should have received a copy of the GNU General Public 37 | License and the FreeRTOS license exception along with FreeRTOS; if not it 38 | can be viewed here: http://www.freertos.org/a00114.html and also obtained 39 | by writing to Richard Barry, contact details for whom are available on the 40 | FreeRTOS WEB site. 41 | 42 | 1 tab == 4 spaces! 43 | 44 | *************************************************************************** 45 | * * 46 | * Having a problem? Start by reading the FAQ "My application does * 47 | * not run, what could be wrong? * 48 | * * 49 | * http://www.FreeRTOS.org/FAQHelp.html * 50 | * * 51 | *************************************************************************** 52 | 53 | 54 | http://www.FreeRTOS.org - Documentation, training, latest information, 55 | license and contact details. 56 | 57 | http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 58 | including FreeRTOS+Trace - an indispensable productivity tool. 59 | 60 | Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell 61 | the code with commercial support, indemnification, and middleware, under 62 | the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also 63 | provide a safety engineered and independently SIL3 certified version under 64 | the SafeRTOS brand: http://www.SafeRTOS.com. 65 | */ 66 | 67 | #ifndef FREERTOS_CONFIG_H 68 | #define FREERTOS_CONFIG_H 69 | 70 | /*----------------------------------------------------------- 71 | * Application specific definitions. 72 | * 73 | * These definitions should be adjusted for your particular hardware and 74 | * application requirements. 75 | * 76 | * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE 77 | * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. 78 | * 79 | * See http://www.freertos.org/a00110.html. 80 | *----------------------------------------------------------*/ 81 | 82 | #define configUSE_PREEMPTION 1 83 | #define configUSE_IDLE_HOOK 0 84 | #define configUSE_TICK_HOOK 0 85 | //CPU = 1 GHz 86 | #define configCPU_CLOCK_HZ ( ( unsigned long ) 1000000000 ) 87 | //frequency of the timer interrupt 88 | #define configTICK_RATE_HZ ( ( portTickType ) 1000 ) 89 | #define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) 90 | #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) 91 | #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 0x10000 ) ) //from kernel.ld 92 | #define configMAX_TASK_NAME_LEN ( 16 ) 93 | #define configUSE_TRACE_FACILITY 1 94 | #define configUSE_STATS_FORMATTING_FUNCTIONS 1 95 | #define configUSE_16_BIT_TICKS 0 96 | #define configIDLE_SHOULD_YIELD 1 97 | #define configUSE_APPLICATION_TASK_TAG 1 98 | 99 | /* Co-routine definitions. */ 100 | #define configUSE_CO_ROUTINES 0 101 | #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) 102 | 103 | /* Set the following definitions to 1 to include the API function, or zero 104 | to exclude the API function. */ 105 | 106 | #define INCLUDE_vTaskPrioritySet 1 107 | #define INCLUDE_uxTaskPriorityGet 1 108 | #define INCLUDE_vTaskDelete 1 109 | #define INCLUDE_vTaskCleanUpResources 0 110 | #define INCLUDE_vTaskSuspend 1 111 | #define INCLUDE_vTaskDelayUntil 1 112 | #define INCLUDE_vTaskDelay 1 113 | #define INCLUDE_xTaskGetCurrentTaskHandle 1 114 | 115 | /* This is the raw value as per the Cortex-M3 NVIC. Values can be 255 116 | (lowest) to 0 (1?) (highest). */ 117 | #define configKERNEL_INTERRUPT_PRIORITY 255 118 | /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! 119 | See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ 120 | #define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */ 121 | 122 | 123 | /* This is the value being used as per the ST library which permits 16 124 | priority values, 0 to 15. This must correspond to the 125 | configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest 126 | NVIC value of 255. */ 127 | #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 128 | 129 | #endif /* FREERTOS_CONFIG_H */ 130 | 131 | -------------------------------------------------------------------------------- /Demo/TrustZone/selfhealing.c: -------------------------------------------------------------------------------- 1 | /** 2 | * TrustZone functionality to self-heal failed or misbehaving tasks. 3 | * 4 | * @author: Michael Denzel 5 | * @contact: https://github.com/mdenzel 6 | * @license: GNU General Public License 2.0 or later 7 | * @date: 2017-03-17 8 | * @version: 0.1 9 | **/ 10 | 11 | //FreeRTOS includes 12 | #include "FreeRTOSConfig.h" 13 | #include "FreeRTOS.h" 14 | #include "task.h" 15 | //C 16 | #include 17 | #include 18 | #include //sprintf 19 | //own includes 20 | #include "selfhealing.h" 21 | #include "mxc_serial.h" 22 | #include "trustzone.h" 23 | #include "kernelpanic.h" 24 | #include "controltasks.h" 25 | #include "interrupts.h" 26 | //Drivers 27 | #include "IO.h" 28 | 29 | extern volatile void* volatile pxCurrentTCB; 30 | 31 | //types 32 | typedef struct tskTaskControlBlock 33 | { 34 | StackType_t* topOfStack; 35 | ListItem_t unused1; 36 | ListItem_t unused2; 37 | UBaseType_t prio; 38 | StackType_t* stack; 39 | char name[ configMAX_TASK_NAME_LEN ]; 40 | } MiniTCB_t; 41 | 42 | 43 | // --- HELPERS --- 44 | 45 | //checks if the currentTCB is the restoration task 46 | //IMPROVE: normally this should not be done via the name but via it's PC (program counter) 47 | int is_currentTCB_restoration(){ 48 | return strcmp(((MiniTCB_t*)pxCurrentTCB)->name, "restoration"); 49 | } 50 | 51 | //replaces actual (malicious) task with the self-healing routine 52 | static void schedule_restoration(void* task){ 53 | cprintf("\e[0;33m"); //yellow colour 54 | #ifdef DEBUG 55 | //IRQ/FIQ should be off! 56 | cprintf("schedule_restoration IRQ: %d, FIQ: %d\n", CheckIRQ(), CheckFIQ()); 57 | #endif 58 | 59 | #ifdef INFO 60 | cprintf("schedule_restoration: create restoration task\n"); 61 | #endif 62 | //create restoration task at priority of the misbehaving task 63 | //xTaskCreate(function, name, stacksize, parameter, priority, handle); 64 | TaskHandle_t restoration_task = NULL; 65 | if(xTaskCreate(restoration, "restoration", 256, task, 66 | ((MiniTCB_t*)task)->prio, &restoration_task) != pdPASS){ 67 | kernelpanic("could not create restoration task\n"); 68 | } 69 | if(restoration_task == NULL){ 70 | kernelpanic("restoration task NULL\n"); 71 | } 72 | 73 | //set restoration next instead of malicious task 74 | pxCurrentTCB = (void*)restoration_task; 75 | #ifdef INFO 76 | cprintf("new task: %s\n", ((MiniTCB_t*)pxCurrentTCB)->name); 77 | #endif 78 | 79 | #ifdef INFO 80 | cprintf("schedule_restoration: suspend %s\n", ((MiniTCB_t*)task)->name); 81 | #endif 82 | //suspend current misbehaving task (will trigger rescheduling) 83 | //since the task is suspended, detection will not run for it and 84 | //there won't be 2 restoration routines for one task 85 | vTaskSuspend(task); 86 | cprintf("\e[0m"); //default colour 87 | } 88 | 89 | 90 | #ifdef DEBUG 91 | //debug function to print a `num` values on the stack 92 | __attribute__((unused)) static void print_stack(const volatile StackType_t* stack, const unsigned int num){ 93 | for(int i = num-1; i >= 0; --i){ 94 | cprintf("stack %x: %x\n", stack+i, *(stack+i)); 95 | } 96 | } 97 | #endif 98 | 99 | // ================= 100 | // --- DETECTION --- 101 | // ================= 102 | 103 | int detection(){ 104 | //variables 105 | MiniTCB_t* tcb = NULL; 106 | int ret = 0; 107 | 108 | //prevent scheduler from swapping out the detection/restoration_scheduling routine 109 | vTaskSuspendAll(); 110 | { 111 | #ifdef DEBUG 112 | //IRQ/FIQ should be off! 113 | cprintf("detection IRQ: %d, FIQ: %d\n", CheckIRQ(), CheckFIQ()); 114 | #endif 115 | 116 | //get current task control block 117 | tcb = (MiniTCB_t*)pxCurrentTCB; 118 | 119 | //log 120 | #ifdef INFO 121 | cprintf("-- detection for %s --\n", tcb->name); 122 | #endif 123 | #ifdef DEBUG 124 | //debug prints 125 | print_MODE(); 126 | print_WORLD(); 127 | #endif 128 | 129 | //IMPROVE: detection: sensor values via SMC? 130 | //task3 131 | if(strcmp(tcb->name, "task3") == 0){ 132 | temperature t = get_config_temperature(); 133 | #ifdef INFO 134 | cprintf("temp: (%s, %d, %d)\n", t.info, t.max, t.min); 135 | #endif 136 | //IMPROVE: "policy" for now hard-coded 137 | if(t.max > 100){ 138 | schedule_restoration(tcb); 139 | ret = -13; 140 | } 141 | } 142 | }//finished => resume scheduler 143 | xTaskResumeAll(); 144 | 145 | #ifdef DEBUG 146 | //IRQ/FIQ should be off! 147 | cprintf("detection IRQ: %d, FIQ: %d\n", CheckIRQ(), CheckFIQ()); 148 | #endif 149 | #ifdef INFO 150 | cprintf("detection new task: %s\n", ((MiniTCB_t*)pxCurrentTCB)->name); 151 | cprintf("-- detection for %s done --\n", tcb->name); 152 | #endif 153 | #if defined(DEBUG) || defined(INFO) 154 | cprintf("\n"); 155 | #endif 156 | 157 | return ret; 158 | } 159 | 160 | 161 | // =================== 162 | // --- RESTORATION --- 163 | // =================== 164 | 165 | void restoration(void* malicious_task){ 166 | //restoration: for now, remove task and hang it in again 167 | #ifdef INFO 168 | cprintf("\e[0;31m-- restoration for %s --\e[0m\n", ((MiniTCB_t*)malicious_task)->name); 169 | #endif 170 | #ifdef DEBUG 171 | //debug prints 172 | cprintf("\e[0;31m"); 173 | print_MODE(); 174 | print_WORLD(); 175 | cprintf("\e[0m"); 176 | cprintf("\e[0;31mrestoration: IRQ: %d, FIQ: %d\e[0m\n", CheckIRQ(), CheckFIQ()); 177 | #endif 178 | 179 | //get number of task 180 | const unsigned int tasknum = atoi((((MiniTCB_t*)malicious_task)->name)+4); 181 | //remove task 182 | #ifdef INFO 183 | cprintf("\e[0;31mrestoration: removing %s\e[0m\n", ((MiniTCB_t*)malicious_task)->name); 184 | #endif 185 | vTaskDelete(malicious_task); 186 | //FIXME: something enables IRQ/FIQ before here (vTaskDelete!) 187 | #ifdef DEBUG 188 | cprintf("restoration: IRQ: %d, FIQ: %d\n", CheckIRQ(), CheckFIQ()); 189 | #endif 190 | 191 | //restore sensor/actuators/data 192 | #ifdef INFO 193 | cprintf("\e[0;31mrestoration: restoring temp sensor\e[0m\n"); 194 | #endif 195 | //IMPROVE: restoration for now hard-coded (should be pulled from server) 196 | reset_temperature(); 197 | 198 | //recreate task 199 | #ifdef INFO 200 | cprintf("\e[0;31mrestoration: recreating task num %d\e[0m\n", tasknum); 201 | #endif 202 | 203 | DisableInterrupts(); 204 | vTaskSuspendAll(); 205 | { 206 | #ifdef DEBUG 207 | //IRQ/FIQ should be off! 208 | cprintf("restoration xTaskCreate: IRQ: %d, FIQ: %d\n", CheckIRQ(), CheckFIQ()); 209 | #endif 210 | if(xTaskCreate(TASK_FUNCTIONS[tasknum-1], TASK_NAMES[tasknum-1], 256, 211 | TASK_NAMES[tasknum-1], TASK_PRIOS[tasknum-1], NULL) != pdPASS){ 212 | char* err = malloc(32); 213 | sprintf(err, "could not re-create task %u\n", tasknum); 214 | kernelpanic(err); 215 | } 216 | #ifdef INFO 217 | cprintf("\e[0;31m-- restoration for %s done --\e[0m\n", ((MiniTCB_t*)malicious_task)->name); 218 | #endif 219 | }//finished => resume scheduler 220 | xTaskResumeAll(); 221 | EnableInterrupts(); 222 | 223 | //remove this restoration task 224 | vTaskDelete(NULL); 225 | } 226 | -------------------------------------------------------------------------------- /Demo/Drivers/config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Offsets for the i.MX53 board (mostly original but with a few modifications). 3 | * 4 | * original author: Dongli Zhang 5 | * https://github.com/finallyjustice/imx53qsb-code "trustzone-smc" 6 | * 7 | * modifications: 8 | * @author: Michael Denzel 9 | * @contact: https://github.com/mdenzel 10 | * @license: GNU General Public License 2.0 or later 11 | * @date: 2017-03-17 12 | * @version: 0.1 13 | **/ 14 | 15 | #ifndef __CONFIG_H__ 16 | #define __CONFIG_H__ 17 | 18 | #define AIPS1_BASE_ADDR 0x53F00000 19 | #define AIPS2_BASE_ADDR 0x63F00000 20 | #define CCM_BASE_ADDR (AIPS1_BASE_ADDR + 0x000D4000) 21 | 22 | //input output multiplex controller 23 | #define IOMUXC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A8000) 24 | #define IOMUXC_CSI0_DAT10 0xe8 /*enabling TXD_MUX*/ 25 | #define IOMUXC_CSI0_DAT11 0xec /*enabling RXD_MUX*/ 26 | 27 | 28 | #define UART_PHYS 0x53FBC000 29 | /* Register definitions */ 30 | #define URXD 0x00 /* Receiver Register */ 31 | #define UTXD 0x40 /* Transmitter Register */ 32 | #define UCR1 0x80 /* Control Register 1 */ 33 | #define UCR2 0x84 /* Control Register 2 */ 34 | #define UCR3 0x88 /* Control Register 3 */ 35 | #define UCR4 0x8c /* Control Register 4 */ 36 | #define UFCR 0x90 /* FIFO Control Register */ 37 | #define USR1 0x94 /* Status Register 1 */ 38 | #define USR2 0x98 /* Status Register 2 */ 39 | #define UESC 0x9c /* Escape Character Register */ 40 | #define UTIM 0xa0 /* Escape Timer Register */ 41 | #define UBIR 0xa4 /* BRM Incremental Register */ 42 | #define UBMR 0xa8 /* BRM Modulator Register */ 43 | #define UBRC 0xac /* Baud Rate Count Register */ 44 | #define ONEMS 0xb0 /* One Millisecond Register */ 45 | #define UTS 0xb4 /* UART Test Register (mx31) */ 46 | 47 | /* UART Control Register Bit Fields.*/ 48 | #define URXD_CHARRDY (1<<15) 49 | #define URXD_ERR (1<<14) 50 | #define URXD_OVRRUN (1<<13) 51 | #define URXD_FRMERR (1<<12) 52 | #define URXD_BRK (1<<11) 53 | #define URXD_PRERR (1<<10) 54 | #define URXD_RX_DATA (0xFF) 55 | #define UCR1_ADEN (1<<15) /* Auto dectect interrupt */ 56 | #define UCR1_ADBR (1<<14) /* Auto detect baud rate */ 57 | #define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ 58 | #define UCR1_IDEN (1<<12) /* Idle condition interrupt */ 59 | #define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */ 60 | #define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */ 61 | #define UCR1_IREN (1<<7) /* Infrared interface enable */ 62 | #define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */ 63 | #define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ 64 | #define UCR1_SNDBRK (1<<4) /* Send break */ 65 | #define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ 66 | #define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */ 67 | #define UCR1_DOZE (1<<1) /* Doze */ 68 | #define UCR1_UARTEN (1<<0) /* UART enabled */ 69 | #define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ 70 | #define UCR2_IRTS (1<<14) /* Ignore RTS pin */ 71 | #define UCR2_CTSC (1<<13) /* CTS pin control */ 72 | #define UCR2_CTS (1<<12) /* Clear to send */ 73 | #define UCR2_ESCEN (1<<11) /* Escape enable */ 74 | #define UCR2_PREN (1<<8) /* Parity enable */ 75 | #define UCR2_PROE (1<<7) /* Parity odd/even */ 76 | #define UCR2_STPB (1<<6) /* Stop */ 77 | #define UCR2_WS (1<<5) /* Word size */ 78 | #define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ 79 | #define UCR2_TXEN (1<<2) /* Transmitter enabled */ 80 | #define UCR2_RXEN (1<<1) /* Receiver enabled */ 81 | #define UCR2_SRST (1<<0) /* SW reset */ 82 | #define UCR3_DTREN (1<<13) /* DTR interrupt enable */ 83 | #define UCR3_PARERREN (1<<12) /* Parity enable */ 84 | #define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */ 85 | #define UCR3_DSR (1<<10) /* Data set ready */ 86 | #define UCR3_DCD (1<<9) /* Data carrier detect */ 87 | #define UCR3_RI (1<<8) /* Ring indicator */ 88 | #define UCR3_ADNIMP (1<<7) /* Autobaud Detection Not Improved */ 89 | #define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ 90 | #define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ 91 | #define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ 92 | #define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */ 93 | #define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */ 94 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ 95 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ 96 | #define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */ 97 | #define UCR4_INVR (1<<9) /* Inverted infrared reception */ 98 | #define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ 99 | #define UCR4_WKEN (1<<7) /* Wake interrupt enable */ 100 | #define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */ 101 | #define UCR4_IRSC (1<<5) /* IR special case */ 102 | #define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */ 103 | #define UCR4_BKEN (1<<2) /* Break condition interrupt enable */ 104 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ 105 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ 106 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ 107 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ 108 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ 109 | #define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ 110 | #define USR1_RTSS (1<<14) /* RTS pin status */ 111 | #define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */ 112 | #define USR1_RTSD (1<<12) /* RTS delta */ 113 | #define USR1_ESCF (1<<11) /* Escape seq interrupt flag */ 114 | #define USR1_FRAMEERR (1<<10) /* Frame error interrupt flag */ 115 | #define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */ 116 | #define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */ 117 | #define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */ 118 | #define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */ 119 | #define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */ 120 | #define USR2_ADET (1<<15) /* Auto baud rate detect complete */ 121 | #define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */ 122 | #define USR2_DTRF (1<<13) /* DTR edge interrupt flag */ 123 | #define USR2_IDLE (1<<12) /* Idle condition */ 124 | #define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */ 125 | #define USR2_WAKE (1<<7) /* Wake */ 126 | #define USR2_RTSF (1<<4) /* RTS edge interrupt flag */ 127 | #define USR2_TXDC (1<<3) /* Transmitter complete */ 128 | #define USR2_BRCD (1<<2) /* Break condition */ 129 | #define USR2_ORE (1<<1) /* Overrun error */ 130 | #define USR2_RDR (1<<0) /* Recv data ready */ 131 | #define UTS_FRCPERR (1<<13) /* Force parity error */ 132 | #define UTS_LOOP (1<<12) /* Loop tx and rx */ 133 | #define UTS_TXEMPTY (1<<6) /* TxFIFO empty */ 134 | #define UTS_RXEMPTY (1<<5) /* RxFIFO empty */ 135 | #define UTS_TXFULL (1<<4) /* TxFIFO full */ 136 | #define UTS_RXFULL (1<<3) /* RxFIFO full */ 137 | #define UTS_SOFTRST (1<<0) /* Software reset */ 138 | 139 | #define __REG(x) (*((volatile unsigned int *)(x))) 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /FreeRTOS/Source/portable/MemMang/heap_1.c: -------------------------------------------------------------------------------- 1 | /* 2 | FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd. 3 | All rights reserved 4 | 5 | VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 6 | 7 | This file is part of the FreeRTOS distribution. 8 | 9 | FreeRTOS is free software; you can redistribute it and/or modify it under 10 | the terms of the GNU General Public License (version 2) as published by the 11 | Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. 12 | 13 | *************************************************************************** 14 | >>! NOTE: The modification to the GPL is included to allow you to !<< 15 | >>! distribute a combined work that includes FreeRTOS without being !<< 16 | >>! obliged to provide the source code for proprietary components !<< 17 | >>! outside of the FreeRTOS kernel. !<< 18 | *************************************************************************** 19 | 20 | FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 22 | FOR A PARTICULAR PURPOSE. Full license text is available on the following 23 | link: http://www.freertos.org/a00114.html 24 | 25 | *************************************************************************** 26 | * * 27 | * FreeRTOS provides completely free yet professionally developed, * 28 | * robust, strictly quality controlled, supported, and cross * 29 | * platform software that is more than just the market leader, it * 30 | * is the industry's de facto standard. * 31 | * * 32 | * Help yourself get started quickly while simultaneously helping * 33 | * to support the FreeRTOS project by purchasing a FreeRTOS * 34 | * tutorial book, reference manual, or both: * 35 | * http://www.FreeRTOS.org/Documentation * 36 | * * 37 | *************************************************************************** 38 | 39 | http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 40 | the FAQ page "My application does not run, what could be wrong?". Have you 41 | defined configASSERT()? 42 | 43 | http://www.FreeRTOS.org/support - In return for receiving this top quality 44 | embedded software for free we request you assist our global community by 45 | participating in the support forum. 46 | 47 | http://www.FreeRTOS.org/training - Investing in training allows your team to 48 | be as productive as possible as early as possible. Now you can receive 49 | FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 50 | Ltd, and the world's leading authority on the world's leading RTOS. 51 | 52 | http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 53 | including FreeRTOS+Trace - an indispensable productivity tool, a DOS 54 | compatible FAT file system, and our tiny thread aware UDP/IP stack. 55 | 56 | http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 57 | Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 58 | 59 | http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 60 | Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 61 | licenses offer ticketed support, indemnification and commercial middleware. 62 | 63 | http://www.SafeRTOS.com - High Integrity Systems also provide a safety 64 | engineered and independently SIL3 certified version for use in safety and 65 | mission critical applications that require provable dependability. 66 | 67 | 1 tab == 4 spaces! 68 | */ 69 | 70 | 71 | /* 72 | * The simplest possible implementation of pvPortMalloc(). Note that this 73 | * implementation does NOT allow allocated memory to be freed again. 74 | * 75 | * See heap_2.c, heap_3.c and heap_4.c for alternative implementations, and the 76 | * memory management pages of http://www.FreeRTOS.org for more information. 77 | */ 78 | #include 79 | 80 | /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 81 | all the API functions to use the MPU wrappers. That should only be done when 82 | task.h is included from an application file. */ 83 | #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 84 | 85 | #include "FreeRTOS.h" 86 | #include "task.h" 87 | 88 | #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 89 | 90 | /* A few bytes might be lost to byte aligning the heap start address. */ 91 | #define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) 92 | 93 | /* Allocate the memory for the heap. */ 94 | /* Allocate the memory for the heap. */ 95 | #if( configAPPLICATION_ALLOCATED_HEAP == 1 ) 96 | /* The application writer has already defined the array used for the RTOS 97 | heap - probably so it can be placed in a special segment or address. */ 98 | extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 99 | #else 100 | static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 101 | #endif /* configAPPLICATION_ALLOCATED_HEAP */ 102 | 103 | static size_t xNextFreeByte = ( size_t ) 0; 104 | 105 | /*-----------------------------------------------------------*/ 106 | 107 | void *pvPortMalloc( size_t xWantedSize ) 108 | { 109 | void *pvReturn = NULL; 110 | static uint8_t *pucAlignedHeap = NULL; 111 | 112 | /* Ensure that blocks are always aligned to the required number of bytes. */ 113 | #if( portBYTE_ALIGNMENT != 1 ) 114 | { 115 | if( xWantedSize & portBYTE_ALIGNMENT_MASK ) 116 | { 117 | /* Byte alignment required. */ 118 | xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); 119 | } 120 | } 121 | #endif 122 | 123 | vTaskSuspendAll(); 124 | { 125 | if( pucAlignedHeap == NULL ) 126 | { 127 | /* Ensure the heap starts on a correctly aligned boundary. */ 128 | pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); 129 | } 130 | 131 | /* Check there is enough room left for the allocation. */ 132 | if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) && 133 | ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */ 134 | { 135 | /* Return the next free byte then increment the index past this 136 | block. */ 137 | pvReturn = pucAlignedHeap + xNextFreeByte; 138 | xNextFreeByte += xWantedSize; 139 | } 140 | 141 | traceMALLOC( pvReturn, xWantedSize ); 142 | } 143 | ( void ) xTaskResumeAll(); 144 | 145 | #if( configUSE_MALLOC_FAILED_HOOK == 1 ) 146 | { 147 | if( pvReturn == NULL ) 148 | { 149 | extern void vApplicationMallocFailedHook( void ); 150 | vApplicationMallocFailedHook(); 151 | } 152 | } 153 | #endif 154 | 155 | return pvReturn; 156 | } 157 | /*-----------------------------------------------------------*/ 158 | 159 | void vPortFree( void *pv ) 160 | { 161 | /* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and 162 | heap_4.c for alternative implementations, and the memory management pages of 163 | http://www.FreeRTOS.org for more information. */ 164 | ( void ) pv; 165 | 166 | /* Force an assert as it is invalid to call this function. */ 167 | configASSERT( pv == NULL ); 168 | } 169 | /*-----------------------------------------------------------*/ 170 | 171 | void vPortInitialiseBlocks( void ) 172 | { 173 | /* Only required when static memory is not cleared. */ 174 | xNextFreeByte = ( size_t ) 0; 175 | } 176 | /*-----------------------------------------------------------*/ 177 | 178 | size_t xPortGetFreeHeapSize( void ) 179 | { 180 | return ( configADJUSTED_HEAP_SIZE - xNextFreeByte ); 181 | } 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/projdefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd. 3 | All rights reserved 4 | 5 | VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 6 | 7 | This file is part of the FreeRTOS distribution. 8 | 9 | FreeRTOS is free software; you can redistribute it and/or modify it under 10 | the terms of the GNU General Public License (version 2) as published by the 11 | Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. 12 | 13 | *************************************************************************** 14 | >>! NOTE: The modification to the GPL is included to allow you to !<< 15 | >>! distribute a combined work that includes FreeRTOS without being !<< 16 | >>! obliged to provide the source code for proprietary components !<< 17 | >>! outside of the FreeRTOS kernel. !<< 18 | *************************************************************************** 19 | 20 | FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 22 | FOR A PARTICULAR PURPOSE. Full license text is available on the following 23 | link: http://www.freertos.org/a00114.html 24 | 25 | *************************************************************************** 26 | * * 27 | * FreeRTOS provides completely free yet professionally developed, * 28 | * robust, strictly quality controlled, supported, and cross * 29 | * platform software that is more than just the market leader, it * 30 | * is the industry's de facto standard. * 31 | * * 32 | * Help yourself get started quickly while simultaneously helping * 33 | * to support the FreeRTOS project by purchasing a FreeRTOS * 34 | * tutorial book, reference manual, or both: * 35 | * http://www.FreeRTOS.org/Documentation * 36 | * * 37 | *************************************************************************** 38 | 39 | http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 40 | the FAQ page "My application does not run, what could be wrong?". Have you 41 | defined configASSERT()? 42 | 43 | http://www.FreeRTOS.org/support - In return for receiving this top quality 44 | embedded software for free we request you assist our global community by 45 | participating in the support forum. 46 | 47 | http://www.FreeRTOS.org/training - Investing in training allows your team to 48 | be as productive as possible as early as possible. Now you can receive 49 | FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 50 | Ltd, and the world's leading authority on the world's leading RTOS. 51 | 52 | http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 53 | including FreeRTOS+Trace - an indispensable productivity tool, a DOS 54 | compatible FAT file system, and our tiny thread aware UDP/IP stack. 55 | 56 | http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 57 | Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 58 | 59 | http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 60 | Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 61 | licenses offer ticketed support, indemnification and commercial middleware. 62 | 63 | http://www.SafeRTOS.com - High Integrity Systems also provide a safety 64 | engineered and independently SIL3 certified version for use in safety and 65 | mission critical applications that require provable dependability. 66 | 67 | 1 tab == 4 spaces! 68 | */ 69 | 70 | #ifndef PROJDEFS_H 71 | #define PROJDEFS_H 72 | 73 | /* 74 | * Defines the prototype to which task functions must conform. Defined in this 75 | * file to ensure the type is known before portable.h is included. 76 | */ 77 | typedef void (*TaskFunction_t)( void * ); 78 | 79 | /* Converts a time in milliseconds to a time in ticks. */ 80 | #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) 81 | 82 | #define pdFALSE ( ( BaseType_t ) 0 ) 83 | #define pdTRUE ( ( BaseType_t ) 1 ) 84 | 85 | #define pdPASS ( pdTRUE ) 86 | #define pdFAIL ( pdFALSE ) 87 | #define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) 88 | #define errQUEUE_FULL ( ( BaseType_t ) 0 ) 89 | 90 | /* FreeRTOS error definitions. */ 91 | #define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) 92 | #define errQUEUE_BLOCKED ( -4 ) 93 | #define errQUEUE_YIELD ( -5 ) 94 | 95 | /* Macros used for basic data corruption checks. */ 96 | #ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 97 | #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 98 | #endif 99 | 100 | #if( configUSE_16_BIT_TICKS == 1 ) 101 | #define pdINTEGRITY_CHECK_VALUE 0x5a5a 102 | #else 103 | #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL 104 | #endif 105 | 106 | /* The following errno values are used by FreeRTOS+ components, not FreeRTOS 107 | itself. */ 108 | #define pdFREERTOS_ERRNO_NONE 0 /* No errors */ 109 | #define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ 110 | #define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ 111 | #define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ 112 | #define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ 113 | #define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ 114 | #define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ 115 | #define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ 116 | #define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ 117 | #define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ 118 | #define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ 119 | #define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ 120 | #define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ 121 | #define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ 122 | #define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ 123 | #define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ 124 | #define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ 125 | #define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ 126 | #define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ 127 | #define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ 128 | #define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ 129 | #define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ 130 | #define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ 131 | #define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ 132 | #define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ 133 | #define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ 134 | #define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ 135 | #define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ 136 | #define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ 137 | #define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ 138 | #define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ 139 | #define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ 140 | #define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ 141 | #define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ 142 | #define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ 143 | #define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ 144 | #define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ 145 | #define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ 146 | #define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ 147 | #define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ 148 | 149 | /* The following endian values are used by FreeRTOS+ components, not FreeRTOS 150 | itself. */ 151 | #define pdFREERTOS_LITTLE_ENDIAN 0 152 | #define pdFREERTOS_BIG_ENDIAN 1 153 | 154 | #endif /* PROJDEFS_H */ 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/StackMacros.h: -------------------------------------------------------------------------------- 1 | /* 2 | FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd. 3 | All rights reserved 4 | 5 | VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 6 | 7 | This file is part of the FreeRTOS distribution. 8 | 9 | FreeRTOS is free software; you can redistribute it and/or modify it under 10 | the terms of the GNU General Public License (version 2) as published by the 11 | Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. 12 | 13 | *************************************************************************** 14 | >>! NOTE: The modification to the GPL is included to allow you to !<< 15 | >>! distribute a combined work that includes FreeRTOS without being !<< 16 | >>! obliged to provide the source code for proprietary components !<< 17 | >>! outside of the FreeRTOS kernel. !<< 18 | *************************************************************************** 19 | 20 | FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 22 | FOR A PARTICULAR PURPOSE. Full license text is available on the following 23 | link: http://www.freertos.org/a00114.html 24 | 25 | *************************************************************************** 26 | * * 27 | * FreeRTOS provides completely free yet professionally developed, * 28 | * robust, strictly quality controlled, supported, and cross * 29 | * platform software that is more than just the market leader, it * 30 | * is the industry's de facto standard. * 31 | * * 32 | * Help yourself get started quickly while simultaneously helping * 33 | * to support the FreeRTOS project by purchasing a FreeRTOS * 34 | * tutorial book, reference manual, or both: * 35 | * http://www.FreeRTOS.org/Documentation * 36 | * * 37 | *************************************************************************** 38 | 39 | http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 40 | the FAQ page "My application does not run, what could be wrong?". Have you 41 | defined configASSERT()? 42 | 43 | http://www.FreeRTOS.org/support - In return for receiving this top quality 44 | embedded software for free we request you assist our global community by 45 | participating in the support forum. 46 | 47 | http://www.FreeRTOS.org/training - Investing in training allows your team to 48 | be as productive as possible as early as possible. Now you can receive 49 | FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 50 | Ltd, and the world's leading authority on the world's leading RTOS. 51 | 52 | http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 53 | including FreeRTOS+Trace - an indispensable productivity tool, a DOS 54 | compatible FAT file system, and our tiny thread aware UDP/IP stack. 55 | 56 | http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 57 | Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 58 | 59 | http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 60 | Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 61 | licenses offer ticketed support, indemnification and commercial middleware. 62 | 63 | http://www.SafeRTOS.com - High Integrity Systems also provide a safety 64 | engineered and independently SIL3 certified version for use in safety and 65 | mission critical applications that require provable dependability. 66 | 67 | 1 tab == 4 spaces! 68 | */ 69 | 70 | #ifndef STACK_MACROS_H 71 | #define STACK_MACROS_H 72 | 73 | /* 74 | * Call the stack overflow hook function if the stack of the task being swapped 75 | * out is currently overflowed, or looks like it might have overflowed in the 76 | * past. 77 | * 78 | * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check 79 | * the current stack state only - comparing the current top of stack value to 80 | * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 81 | * will also cause the last few stack bytes to be checked to ensure the value 82 | * to which the bytes were set when the task was created have not been 83 | * overwritten. Note this second test does not guarantee that an overflowed 84 | * stack will always be recognised. 85 | */ 86 | 87 | /*-----------------------------------------------------------*/ 88 | 89 | #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) 90 | 91 | /* Only the current stack state is to be checked. */ 92 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 93 | { \ 94 | /* Is the currently saved stack pointer within the stack limit? */ \ 95 | if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ 96 | { \ 97 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 98 | } \ 99 | } 100 | 101 | #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ 102 | /*-----------------------------------------------------------*/ 103 | 104 | #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) 105 | 106 | /* Only the current stack state is to be checked. */ 107 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 108 | { \ 109 | \ 110 | /* Is the currently saved stack pointer within the stack limit? */ \ 111 | if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ 112 | { \ 113 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 114 | } \ 115 | } 116 | 117 | #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ 118 | /*-----------------------------------------------------------*/ 119 | 120 | #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) 121 | 122 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 123 | { \ 124 | const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ 125 | const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ 126 | \ 127 | if( ( pulStack[ 0 ] != ulCheckValue ) || \ 128 | ( pulStack[ 1 ] != ulCheckValue ) || \ 129 | ( pulStack[ 2 ] != ulCheckValue ) || \ 130 | ( pulStack[ 3 ] != ulCheckValue ) ) \ 131 | { \ 132 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 133 | } \ 134 | } 135 | 136 | #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 137 | /*-----------------------------------------------------------*/ 138 | 139 | #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) 140 | 141 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 142 | { \ 143 | int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ 144 | static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 145 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 146 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 147 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 148 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ 149 | \ 150 | \ 151 | pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ 152 | \ 153 | /* Has the extremity of the task stack ever been written over? */ \ 154 | if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ 155 | { \ 156 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 157 | } \ 158 | } 159 | 160 | #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 161 | /*-----------------------------------------------------------*/ 162 | 163 | /* Remove stack overflow macro if not being used. */ 164 | #ifndef taskCHECK_FOR_STACK_OVERFLOW 165 | #define taskCHECK_FOR_STACK_OVERFLOW() 166 | #endif 167 | 168 | 169 | 170 | #endif /* STACK_MACROS_H */ 171 | 172 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/mpu_wrappers.h: -------------------------------------------------------------------------------- 1 | /* 2 | FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd. 3 | All rights reserved 4 | 5 | VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 6 | 7 | This file is part of the FreeRTOS distribution. 8 | 9 | FreeRTOS is free software; you can redistribute it and/or modify it under 10 | the terms of the GNU General Public License (version 2) as published by the 11 | Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. 12 | 13 | *************************************************************************** 14 | >>! NOTE: The modification to the GPL is included to allow you to !<< 15 | >>! distribute a combined work that includes FreeRTOS without being !<< 16 | >>! obliged to provide the source code for proprietary components !<< 17 | >>! outside of the FreeRTOS kernel. !<< 18 | *************************************************************************** 19 | 20 | FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 22 | FOR A PARTICULAR PURPOSE. Full license text is available on the following 23 | link: http://www.freertos.org/a00114.html 24 | 25 | *************************************************************************** 26 | * * 27 | * FreeRTOS provides completely free yet professionally developed, * 28 | * robust, strictly quality controlled, supported, and cross * 29 | * platform software that is more than just the market leader, it * 30 | * is the industry's de facto standard. * 31 | * * 32 | * Help yourself get started quickly while simultaneously helping * 33 | * to support the FreeRTOS project by purchasing a FreeRTOS * 34 | * tutorial book, reference manual, or both: * 35 | * http://www.FreeRTOS.org/Documentation * 36 | * * 37 | *************************************************************************** 38 | 39 | http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 40 | the FAQ page "My application does not run, what could be wrong?". Have you 41 | defined configASSERT()? 42 | 43 | http://www.FreeRTOS.org/support - In return for receiving this top quality 44 | embedded software for free we request you assist our global community by 45 | participating in the support forum. 46 | 47 | http://www.FreeRTOS.org/training - Investing in training allows your team to 48 | be as productive as possible as early as possible. Now you can receive 49 | FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 50 | Ltd, and the world's leading authority on the world's leading RTOS. 51 | 52 | http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 53 | including FreeRTOS+Trace - an indispensable productivity tool, a DOS 54 | compatible FAT file system, and our tiny thread aware UDP/IP stack. 55 | 56 | http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 57 | Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 58 | 59 | http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 60 | Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 61 | licenses offer ticketed support, indemnification and commercial middleware. 62 | 63 | http://www.SafeRTOS.com - High Integrity Systems also provide a safety 64 | engineered and independently SIL3 certified version for use in safety and 65 | mission critical applications that require provable dependability. 66 | 67 | 1 tab == 4 spaces! 68 | */ 69 | 70 | #ifndef MPU_WRAPPERS_H 71 | #define MPU_WRAPPERS_H 72 | 73 | /* This file redefines API functions to be called through a wrapper macro, but 74 | only for ports that are using the MPU. */ 75 | #ifdef portUSING_MPU_WRAPPERS 76 | 77 | /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is 78 | included from queue.c or task.c to prevent it from having an effect within 79 | those files. */ 80 | #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 81 | 82 | #define xTaskGenericCreate MPU_xTaskGenericCreate 83 | #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions 84 | #define vTaskDelete MPU_vTaskDelete 85 | #define vTaskDelayUntil MPU_vTaskDelayUntil 86 | #define vTaskDelay MPU_vTaskDelay 87 | #define uxTaskPriorityGet MPU_uxTaskPriorityGet 88 | #define vTaskPrioritySet MPU_vTaskPrioritySet 89 | #define eTaskGetState MPU_eTaskGetState 90 | #define vTaskSuspend MPU_vTaskSuspend 91 | #define vTaskResume MPU_vTaskResume 92 | #define vTaskSuspendAll MPU_vTaskSuspendAll 93 | #define xTaskResumeAll MPU_xTaskResumeAll 94 | #define xTaskGetTickCount MPU_xTaskGetTickCount 95 | #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks 96 | #define vTaskList MPU_vTaskList 97 | #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats 98 | #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag 99 | #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag 100 | #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook 101 | #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark 102 | #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle 103 | #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState 104 | #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle 105 | #define uxTaskGetSystemState MPU_uxTaskGetSystemState 106 | #define xTaskGenericNotify MPU_xTaskGenericNotify 107 | #define xTaskNotifyWait MPU_xTaskNotifyWait 108 | #define ulTaskNotifyTake MPU_ulTaskNotifyTake 109 | 110 | #define xQueueGenericCreate MPU_xQueueGenericCreate 111 | #define xQueueCreateMutex MPU_xQueueCreateMutex 112 | #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive 113 | #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive 114 | #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore 115 | #define xQueueGenericSend MPU_xQueueGenericSend 116 | #define xQueueGenericReceive MPU_xQueueGenericReceive 117 | #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting 118 | #define vQueueDelete MPU_vQueueDelete 119 | #define xQueueGenericReset MPU_xQueueGenericReset 120 | #define xQueueCreateSet MPU_xQueueCreateSet 121 | #define xQueueSelectFromSet MPU_xQueueSelectFromSet 122 | #define xQueueAddToSet MPU_xQueueAddToSet 123 | #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet 124 | #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder 125 | 126 | #define pvPortMalloc MPU_pvPortMalloc 127 | #define vPortFree MPU_vPortFree 128 | #define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize 129 | #define vPortInitialiseBlocks MPU_vPortInitialiseBlocks 130 | #define xPortGetMinimumEverFreeHeapSize MPU_xPortGetMinimumEverFreeHeapSize 131 | 132 | #if configQUEUE_REGISTRY_SIZE > 0 133 | #define vQueueAddToRegistry MPU_vQueueAddToRegistry 134 | #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue 135 | #endif 136 | 137 | #define xTimerCreate MPU_xTimerCreate 138 | #define pvTimerGetTimerID MPU_pvTimerGetTimerID 139 | #define vTimerSetTimerID MPU_vTimerSetTimerID 140 | #define xTimerIsTimerActive MPU_xTimerIsTimerActive 141 | #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle 142 | #define xTimerPendFunctionCall MPU_xTimerPendFunctionCall 143 | #define pcTimerGetTimerName MPU_pcTimerGetTimerName 144 | #define xTimerGenericCommand MPU_xTimerGenericCommand 145 | 146 | #define xEventGroupCreate MPU_xEventGroupCreate 147 | #define xEventGroupWaitBits MPU_xEventGroupWaitBits 148 | #define xEventGroupClearBits MPU_xEventGroupClearBits 149 | #define xEventGroupSetBits MPU_xEventGroupSetBits 150 | #define xEventGroupSync MPU_xEventGroupSync 151 | #define vEventGroupDelete MPU_vEventGroupDelete 152 | 153 | /* Remove the privileged function macro. */ 154 | #define PRIVILEGED_FUNCTION 155 | 156 | #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ 157 | 158 | /* Ensure API functions go in the privileged execution section. */ 159 | #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) 160 | #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) 161 | 162 | #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ 163 | 164 | #else /* portUSING_MPU_WRAPPERS */ 165 | 166 | #define PRIVILEGED_FUNCTION 167 | #define PRIVILEGED_DATA 168 | #define portUSING_MPU_WRAPPERS 0 169 | 170 | #endif /* portUSING_MPU_WRAPPERS */ 171 | 172 | 173 | #endif /* MPU_WRAPPERS_H */ 174 | 175 | -------------------------------------------------------------------------------- /FreeRTOS/Source/portable/GCC/portisr.c: -------------------------------------------------------------------------------- 1 | /** 2 | * FreeRTOS Interrupt Service Routines (ISR) (with modifications). 3 | * 4 | * original author: James Walmsley https://github.com/jameswalmsley/RaspberryPi-FreeRTOS 5 | * 6 | * modifications (mainly Timing functionality): 7 | * @author: Michael Denzel 8 | * @contact: https://github.com/mdenzel 9 | * @license: GNU General Public License 2.0 or later 10 | * @date: 2017-03-17 11 | * @version: 0.1 12 | **/ 13 | 14 | /*----------------------------------------------------------- 15 | * Components that can be compiled to either ARM or THUMB mode are 16 | * contained in port.c The ISR routines, which can only be compiled 17 | * to ARM mode, are contained in this file. 18 | *----------------------------------------------------------*/ 19 | 20 | /* 21 | Changes from V2.5.2 22 | 23 | + The critical section management functions have been changed. These no 24 | longer modify the stack and are safe to use at all optimisation levels. 25 | The functions are now also the same for both ARM and THUMB modes. 26 | 27 | Changes from V2.6.0 28 | 29 | + Removed the 'static' from the definition of vNonPreemptiveTick() to 30 | allow the demo to link when using the cooperative scheduler. 31 | 32 | Changes from V3.2.4 33 | 34 | + The assembler statements are now included in a single asm block rather 35 | than each line having its own asm block. 36 | */ 37 | 38 | 39 | /* Scheduler includes. */ 40 | #include "FreeRTOS.h" 41 | #include "mxc_serial.h" 42 | #include "interrupts.h" 43 | #include "trustzone.h" 44 | 45 | //optional includes 46 | #ifdef TIMING 47 | #include "timing.h" 48 | #endif 49 | 50 | /* Constants required to handle interrupts. */ 51 | #define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 ) 52 | #define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 ) 53 | 54 | /* Constants required to handle critical sections. */ 55 | #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) 56 | volatile uint32_t ulCriticalNesting = 9999UL; 57 | 58 | /*-----------------------------------------------------------*/ 59 | 60 | /* ISR to handle manual context switches (from a call to taskYIELD()). */ 61 | void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked)); 62 | 63 | /* 64 | * The scheduler can only be started from ARM mode, hence the inclusion of this 65 | * function here. 66 | */ 67 | void vPortISRStartFirstTask( void ); 68 | /*-----------------------------------------------------------*/ 69 | 70 | int g_bStarted = 0; 71 | 72 | extern volatile void * volatile pxCurrentTCB; 73 | 74 | void vPortISRStartFirstTask( void ) 75 | { 76 | #ifdef DEBUG 77 | cprintf("\nvPortISRStartFirstTask: %x\n", *(StackType_t*)pxCurrentTCB); 78 | #endif 79 | 80 | g_bStarted++; 81 | 82 | // Simply start the scheduler. This is included here as it can only be called from ARM mode. 83 | portRESTORE_CONTEXT(); 84 | 85 | //should never reach here (= returns to main) 86 | } 87 | /*-----------------------------------------------------------*/ 88 | 89 | /* 90 | * Called by portYIELD() or taskYIELD() to manually force a context switch. 91 | * 92 | * When a context switch is performed from the task level the saved task 93 | * context is made to look as if it occurred from within the tick ISR. This 94 | * way the same restore context function can be used when restoring the context 95 | * saved from the ISR or that saved from a call to vPortYieldProcessor. 96 | */ 97 | void vPortYieldProcessor( void ) 98 | { 99 | /* Within an IRQ ISR the link register has an offset from the true return 100 | address, but an SWI ISR does not. Add the offset manually so the same 101 | ISR return code can be used in both cases. */ 102 | __asm volatile ( "ADD LR, LR, #4" ); //this is skipped in TrustZone because SMC 3 saved LR (and runs before vPortYieldProcessor) and SMC 0 (portSAVE_CONTEXT) will restore the saved LR 103 | 104 | #ifdef DEBUG 105 | __asm volatile("push {r0-r12, lr}\n"); 106 | cprintf("vPortYieldProcessor\n"); 107 | __asm volatile("pop {r0-r12, lr}\n"); 108 | #endif 109 | 110 | #ifdef TIMING 111 | __asm volatile("push {r0-r12, lr}\n"); 112 | start_timer(); 113 | __asm volatile("pop {r0-r12, lr}\n"); 114 | #endif 115 | 116 | /* Perform the context switch. First save the context of the current task. */ 117 | portSAVE_CONTEXT(); 118 | 119 | /* Find the highest priority task that is ready to run. */ 120 | __asm volatile ( "bl vTaskSwitchContext" ); 121 | 122 | /* Restore the context of the new task. */ 123 | portRESTORE_CONTEXT(); 124 | } 125 | /*-----------------------------------------------------------*/ 126 | 127 | /* 128 | * The ISR used for the scheduler tick. 129 | */ 130 | 131 | /*-----------------------------------------------------------*/ 132 | 133 | 134 | /** 135 | * This is the KERNEL's true entry point into an ISR. 136 | * 137 | * We use the FreeRTOS to save context before entering the 138 | * vectorising ISR, and emitting the true ISR event. 139 | * 140 | * On return from the ISR we simply restore the context 141 | **/ 142 | 143 | extern void irqHandler(void); 144 | 145 | void vFreeRTOS_ISR( void ) __attribute__((naked)); 146 | void vFreeRTOS_ISR( void ) { 147 | 148 | #ifdef DEBUG 149 | //log 150 | __asm volatile("push {r0-r12, lr}\n"); 151 | cprintf("\nvFreeRTOS_ISR\n"); 152 | print_MODE(); 153 | print_WORLD(); 154 | cprintf("\n"); 155 | __asm volatile("pop {r0-r12, lr}\n"); 156 | #endif 157 | 158 | #ifdef TIMING 159 | __asm volatile("push {r0-r12, lr}\n"); 160 | start_timer(); 161 | __asm volatile("pop {r0-r12, lr}\n"); 162 | #endif 163 | 164 | //save last task 165 | portSAVE_CONTEXT(); 166 | 167 | #ifdef DEBUG 168 | cprintf("after portSAVE_CONTEXT\n"); 169 | cprintf("IRQ: %d, FIQ: %d\n", CheckIRQ(), CheckFIQ()); 170 | #endif 171 | 172 | //interrupt handler (might schedule next task which is started below in portRESTORE_CONTEXT) 173 | irqHandler(); 174 | 175 | //switch to next task 176 | portRESTORE_CONTEXT(); //XXX: here the context switch from vTickISR happens 177 | } 178 | 179 | /* 180 | * The interrupt management utilities can only be called from ARM mode. When 181 | * THUMB_INTERWORK is defined the utilities are defined as functions here to 182 | * ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then 183 | * the utilities are defined as macros in portmacro.h - as per other ports. 184 | */ 185 | #ifdef THUMB_INTERWORK 186 | 187 | void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked)); 188 | void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked)); 189 | 190 | void vPortDisableInterruptsFromThumb( void ) 191 | { 192 | __asm volatile ( 193 | "STMDB SP!, {R0} \n\t" /* Push R0. */ 194 | "MRS R0, CPSR \n\t" /* Get CPSR. */ 195 | "ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ 196 | "MSR CPSR, R0 \n\t" /* Write back modified value. */ 197 | "LDMIA SP!, {R0} \n\t" /* Pop R0. */ 198 | "BX R14" ); /* Return back to thumb. */ 199 | } 200 | 201 | void vPortEnableInterruptsFromThumb( void ) 202 | { 203 | __asm volatile ( 204 | "STMDB SP!, {R0} \n\t" /* Push R0. */ 205 | "MRS R0, CPSR \n\t" /* Get CPSR. */ 206 | "BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ 207 | "MSR CPSR, R0 \n\t" /* Write back modified value. */ 208 | "LDMIA SP!, {R0} \n\t" /* Pop R0. */ 209 | "BX R14" ); /* Return back to thumb. */ 210 | } 211 | 212 | #endif /* THUMB_INTERWORK */ 213 | 214 | /* The code generated by the GCC compiler uses the stack in different ways at 215 | different optimisation levels. The interrupt flags can therefore not always 216 | be saved to the stack. Instead the critical section nesting level is stored 217 | in a variable, which is then saved as part of the stack context. */ 218 | void vPortEnterCritical( void ) 219 | { 220 | /* Disable interrupts as per portDISABLE_INTERRUPTS(); */ 221 | __asm volatile ( 222 | "STMDB SP!, {R0} \n\t" /* Push R0. */ 223 | "MRS R0, CPSR \n\t" /* Get CPSR. */ 224 | "ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ 225 | "MSR CPSR, R0 \n\t" /* Write back modified value. */ 226 | "LDMIA SP!, {R0}" ); /* Pop R0. */ 227 | 228 | /* Now interrupts are disabled ulCriticalNesting can be accessed 229 | directly. Increment ulCriticalNesting to keep a count of how many times 230 | portENTER_CRITICAL() has been called. */ 231 | ulCriticalNesting++; 232 | } 233 | 234 | void vPortExitCritical( void ) 235 | { 236 | if( ulCriticalNesting > portNO_CRITICAL_NESTING ) 237 | { 238 | /* Decrement the nesting count as we are leaving a critical section. */ 239 | ulCriticalNesting--; 240 | 241 | /* If the nesting level has reached zero then interrupts should be 242 | re-enabled. */ 243 | if( ulCriticalNesting == portNO_CRITICAL_NESTING ) 244 | { 245 | /* Enable interrupts as per portEXIT_CRITICAL(). */ 246 | __asm volatile ( 247 | "STMDB SP!, {R0} \n\t" /* Push R0. */ 248 | "MRS R0, CPSR \n\t" /* Get CPSR. */ 249 | "BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ //FIXME: this enables IRQ+FIQ no matter what the state before was 250 | "MSR CPSR, R0 \n\t" /* Write back modified value. */ 251 | "LDMIA SP!, {R0}" ); /* Pop R0. */ 252 | } 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/portable.h: -------------------------------------------------------------------------------- 1 | /* 2 | FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd. 3 | All rights reserved 4 | 5 | VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 6 | 7 | This file is part of the FreeRTOS distribution. 8 | 9 | FreeRTOS is free software; you can redistribute it and/or modify it under 10 | the terms of the GNU General Public License (version 2) as published by the 11 | Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. 12 | 13 | *************************************************************************** 14 | >>! NOTE: The modification to the GPL is included to allow you to !<< 15 | >>! distribute a combined work that includes FreeRTOS without being !<< 16 | >>! obliged to provide the source code for proprietary components !<< 17 | >>! outside of the FreeRTOS kernel. !<< 18 | *************************************************************************** 19 | 20 | FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 22 | FOR A PARTICULAR PURPOSE. Full license text is available on the following 23 | link: http://www.freertos.org/a00114.html 24 | 25 | *************************************************************************** 26 | * * 27 | * FreeRTOS provides completely free yet professionally developed, * 28 | * robust, strictly quality controlled, supported, and cross * 29 | * platform software that is more than just the market leader, it * 30 | * is the industry's de facto standard. * 31 | * * 32 | * Help yourself get started quickly while simultaneously helping * 33 | * to support the FreeRTOS project by purchasing a FreeRTOS * 34 | * tutorial book, reference manual, or both: * 35 | * http://www.FreeRTOS.org/Documentation * 36 | * * 37 | *************************************************************************** 38 | 39 | http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 40 | the FAQ page "My application does not run, what could be wrong?". Have you 41 | defined configASSERT()? 42 | 43 | http://www.FreeRTOS.org/support - In return for receiving this top quality 44 | embedded software for free we request you assist our global community by 45 | participating in the support forum. 46 | 47 | http://www.FreeRTOS.org/training - Investing in training allows your team to 48 | be as productive as possible as early as possible. Now you can receive 49 | FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 50 | Ltd, and the world's leading authority on the world's leading RTOS. 51 | 52 | http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 53 | including FreeRTOS+Trace - an indispensable productivity tool, a DOS 54 | compatible FAT file system, and our tiny thread aware UDP/IP stack. 55 | 56 | http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 57 | Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 58 | 59 | http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 60 | Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 61 | licenses offer ticketed support, indemnification and commercial middleware. 62 | 63 | http://www.SafeRTOS.com - High Integrity Systems also provide a safety 64 | engineered and independently SIL3 certified version for use in safety and 65 | mission critical applications that require provable dependability. 66 | 67 | 1 tab == 4 spaces! 68 | */ 69 | 70 | /*----------------------------------------------------------- 71 | * Portable layer API. Each function must be defined for each port. 72 | *----------------------------------------------------------*/ 73 | 74 | #ifndef PORTABLE_H 75 | #define PORTABLE_H 76 | 77 | /* Each FreeRTOS port has a unique portmacro.h header file. Originally a 78 | pre-processor definition was used to ensure the pre-processor found the correct 79 | portmacro.h file for the port being used. That scheme was deprecated in favour 80 | of setting the compiler's include path such that it found the correct 81 | portmacro.h file - removing the need for the constant and allowing the 82 | portmacro.h file to be located anywhere in relation to the port being used. 83 | Purely for reasons of backward compatibility the old method is still valid, but 84 | to make it clear that new projects should not use it, support for the port 85 | specific constants has been moved into the deprecated_definitions.h header 86 | file. */ 87 | #include "deprecated_definitions.h" 88 | 89 | /* If portENTER_CRITICAL is not defined then including deprecated_definitions.h 90 | did not result in a portmacro.h header file being included - and it should be 91 | included here. In this case the path to the correct portmacro.h header file 92 | must be set in the compiler's include path. */ 93 | #ifndef portENTER_CRITICAL 94 | #include "portmacro.h" 95 | #endif 96 | 97 | #if portBYTE_ALIGNMENT == 32 98 | #define portBYTE_ALIGNMENT_MASK ( 0x001f ) 99 | #endif 100 | 101 | #if portBYTE_ALIGNMENT == 16 102 | #define portBYTE_ALIGNMENT_MASK ( 0x000f ) 103 | #endif 104 | 105 | #if portBYTE_ALIGNMENT == 8 106 | #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) 107 | #endif 108 | 109 | #if portBYTE_ALIGNMENT == 4 110 | #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) 111 | #endif 112 | 113 | #if portBYTE_ALIGNMENT == 2 114 | #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) 115 | #endif 116 | 117 | #if portBYTE_ALIGNMENT == 1 118 | #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) 119 | #endif 120 | 121 | #ifndef portBYTE_ALIGNMENT_MASK 122 | #error "Invalid portBYTE_ALIGNMENT definition" 123 | #endif 124 | 125 | #ifndef portNUM_CONFIGURABLE_REGIONS 126 | #define portNUM_CONFIGURABLE_REGIONS 1 127 | #endif 128 | 129 | #ifdef __cplusplus 130 | extern "C" { 131 | #endif 132 | 133 | #include "mpu_wrappers.h" 134 | 135 | /* 136 | * Setup the stack of a new task so it is ready to be placed under the 137 | * scheduler control. The registers have to be placed on the stack in 138 | * the order that the port expects to find them. 139 | * 140 | */ 141 | #if( portUSING_MPU_WRAPPERS == 1 ) 142 | StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; 143 | #else 144 | StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; 145 | #endif 146 | 147 | /* Used by heap_5.c. */ 148 | typedef struct HeapRegion 149 | { 150 | uint8_t *pucStartAddress; 151 | size_t xSizeInBytes; 152 | } HeapRegion_t; 153 | 154 | /* 155 | * Used to define multiple heap regions for use by heap_5.c. This function 156 | * must be called before any calls to pvPortMalloc() - not creating a task, 157 | * queue, semaphore, mutex, software timer, event group, etc. will result in 158 | * pvPortMalloc being called. 159 | * 160 | * pxHeapRegions passes in an array of HeapRegion_t structures - each of which 161 | * defines a region of memory that can be used as the heap. The array is 162 | * terminated by a HeapRegions_t structure that has a size of 0. The region 163 | * with the lowest start address must appear first in the array. 164 | */ 165 | void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION; 166 | 167 | 168 | /* 169 | * Map to the memory management routines required for the port. 170 | */ 171 | void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; 172 | void vPortFree( void *pv ) PRIVILEGED_FUNCTION; 173 | void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; 174 | size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; 175 | size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; 176 | 177 | /* 178 | * Setup the hardware ready for the scheduler to take control. This generally 179 | * sets up a tick interrupt and sets timers for the correct tick frequency. 180 | */ 181 | BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; 182 | 183 | /* 184 | * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so 185 | * the hardware is left in its original condition after the scheduler stops 186 | * executing. 187 | */ 188 | void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; 189 | 190 | /* 191 | * The structures and methods of manipulating the MPU are contained within the 192 | * port layer. 193 | * 194 | * Fills the xMPUSettings structure with the memory region information 195 | * contained in xRegions. 196 | */ 197 | #if( portUSING_MPU_WRAPPERS == 1 ) 198 | struct xMEMORY_REGION; 199 | void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint16_t usStackDepth ) PRIVILEGED_FUNCTION; 200 | #endif 201 | 202 | #ifdef __cplusplus 203 | } 204 | #endif 205 | 206 | #endif /* PORTABLE_H */ 207 | 208 | -------------------------------------------------------------------------------- /FreeRTOS/Source/portable/GCC/portmacro.h: -------------------------------------------------------------------------------- 1 | /** 2 | * FreeRTOS macros to switch context (with modifications). 3 | * 4 | * original author: James Walmsley https://github.com/jameswalmsley/RaspberryPi-FreeRTOS 5 | * 6 | * modifications (mainly TrustZone and Timing functionality): 7 | * @author: Michael Denzel 8 | * @contact: https://github.com/mdenzel 9 | * @license: GNU General Public License 2.0 or later 10 | * @date: 2017-03-17 11 | * @version: 0.1 12 | **/ 13 | 14 | #ifndef PORTMACRO_H 15 | #define PORTMACRO_H 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | /*----------------------------------------------------------- 22 | * Port specific definitions. 23 | * 24 | * The settings in this file configure FreeRTOS correctly for the 25 | * given hardware and compiler. 26 | * 27 | * These settings should not be altered. 28 | *----------------------------------------------------------- 29 | */ 30 | 31 | /* Type definitions. */ 32 | #define portCHAR char 33 | #define portFLOAT float 34 | #define portDOUBLE double 35 | #define portLONG long 36 | #define portSHORT short 37 | #define portSTACK_TYPE uint32_t 38 | #define portBASE_TYPE portLONG 39 | 40 | typedef portSTACK_TYPE StackType_t; 41 | typedef long BaseType_t; 42 | typedef unsigned long UBaseType_t; 43 | 44 | #if( configUSE_16_BIT_TICKS == 1 ) 45 | typedef uint16_t TickType_t; 46 | #define portMAX_DELAY ( TickType_t ) 0xffff 47 | #else 48 | typedef uint32_t TickType_t; 49 | #define portMAX_DELAY ( TickType_t ) 0xffffffffUL 50 | #endif 51 | /*-----------------------------------------------------------*/ 52 | 53 | /* Architecture specifics. */ 54 | #define portSTACK_GROWTH ( -1 ) 55 | #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) 56 | #define portBYTE_ALIGNMENT 8 57 | #define portNOP() __asm volatile ( "NOP" ); 58 | /*-----------------------------------------------------------*/ 59 | 60 | 61 | /* Scheduler utilities. */ 62 | 63 | /* 64 | * portSAVE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR 65 | * and portEXIT_SWITCHING_ISR can only be called from ARM mode, but 66 | * are included here for efficiency. An attempt to call one from 67 | * THUMB mode code will result in a compile time error. 68 | */ 69 | #ifdef TRUSTZONE 70 | 71 | #define portRESTORE_CONTEXT() \ 72 | { \ 73 | __asm volatile ( \ 74 | /* Call Monitor */ \ 75 | "SMC #0\n\t" \ 76 | ); \ 77 | } 78 | /*-----------------------------------------------------------*/ 79 | #define portSAVE_CONTEXT() \ 80 | { \ 81 | __asm volatile ( \ 82 | /* Call Monitor */ \ 83 | "SMC #1\n\t" \ 84 | ); \ 85 | } 86 | 87 | #else 88 | 89 | #ifdef TIMING 90 | #define portRESTORE_CONTEXT() \ 91 | { \ 92 | extern volatile void * volatile pxCurrentTCB; \ 93 | extern volatile uint32_t ulCriticalNesting; \ 94 | \ 95 | /* Set the LR to the task stack. */ \ 96 | __asm volatile ( \ 97 | "LDR R0, =pxCurrentTCB \n\t" \ 98 | "LDR R0, [R0] \n\t" \ 99 | "LDR LR, [R0] \n\t" \ 100 | \ 101 | /* The critical nesting depth is the first item on the stack*/\ 102 | /* Load it into the ulCriticalNesting variable. */\ 103 | "LDR R0, =ulCriticalNesting \n\t" \ 104 | "LDMFD LR!, {R1} \n\t" \ 105 | "STR R1, [R0] \n\t" \ 106 | \ 107 | /* Get the SPSR from the stack. */\ 108 | "LDMFD LR!, {R0} \n\t" \ 109 | "MSR SPSR_cxsf, R0 \n\t" /*this enables interrupts*/\ 110 | \ 111 | /* Restore all system mode registers for the task. */\ 112 | "LDMFD LR, {R0-R14}^ \n\t" \ 113 | "NOP \n\t" \ 114 | \ 115 | /* Restore the return address. */\ 116 | "LDR LR, [LR, #+60] \n\t" \ 117 | \ 118 | /* Timing */ \ 119 | "push {r0-r12, lr} \n\t" \ 120 | "bl stop_timer \n\t" \ 121 | "mov r1, r0 \n\t"); \ 122 | cprintf("noTZ timing: %d ns\n"); \ 123 | __asm volatile ( \ 124 | "pop {r0-r12, lr} \n\t" \ 125 | /* And return - correcting the offset in the LR to obtain */\ 126 | /* the correct address. */ \ 127 | "SUBS PC, LR, #4 \n\t" \ 128 | "NOP \n\t" \ 129 | "NOP \n\t" \ 130 | ); \ 131 | ( void ) ulCriticalNesting; \ 132 | ( void ) pxCurrentTCB; \ 133 | } 134 | 135 | #else 136 | 137 | #define portRESTORE_CONTEXT() \ 138 | { \ 139 | extern volatile void * volatile pxCurrentTCB; \ 140 | extern volatile uint32_t ulCriticalNesting; \ 141 | \ 142 | /* Set the LR to the task stack. */ \ 143 | __asm volatile ( \ 144 | "LDR R0, =pxCurrentTCB \n\t" \ 145 | "LDR R0, [R0] \n\t" \ 146 | "LDR LR, [R0] \n\t" \ 147 | \ 148 | /* The critical nesting depth is the first item on the stack*/\ 149 | /* Load it into the ulCriticalNesting variable. */\ 150 | "LDR R0, =ulCriticalNesting \n\t" \ 151 | "LDMFD LR!, {R1} \n\t" \ 152 | "STR R1, [R0] \n\t" \ 153 | \ 154 | /* Get the SPSR from the stack. */\ 155 | "LDMFD LR!, {R0} \n\t" \ 156 | "MSR SPSR_cxsf, R0 \n\t" /*this enables interrupts*/\ 157 | \ 158 | /* Restore all system mode registers for the task. */\ 159 | "LDMFD LR, {R0-R14}^ \n\t" \ 160 | "NOP \n\t" \ 161 | \ 162 | /* Restore the return address. */\ 163 | "LDR LR, [LR, #+60] \n\t" \ 164 | \ 165 | /* And return - correcting the offset in the LR to obtain */\ 166 | /* the correct address. */ \ 167 | "SUBS PC, LR, #4 \n\t" \ 168 | "NOP \n\t" \ 169 | "NOP \n\t" \ 170 | ); \ 171 | ( void ) ulCriticalNesting; \ 172 | ( void ) pxCurrentTCB; \ 173 | } 174 | #endif 175 | /*-----------------------------------------------------------*/ 176 | #define portSAVE_CONTEXT() \ 177 | { \ 178 | extern volatile void * volatile pxCurrentTCB; \ 179 | extern volatile uint32_t ulCriticalNesting; \ 180 | \ 181 | /* Push R0 as we are going to use the register. */ \ 182 | __asm volatile ( \ 183 | "STMDB SP!, {R0} \n\t" \ 184 | \ 185 | /* Set R0 to point to the task stack pointer. */ \ 186 | "STMDB SP,{SP}^ \n\t" \ 187 | "NOP \n\t" \ 188 | "SUB SP, SP, #4 \n\t" \ 189 | "LDMIA SP!,{R0} \n\t" \ 190 | \ 191 | /* Push the return address onto the stack. */ \ 192 | "STMDB R0!, {LR} \n\t" \ 193 | \ 194 | /* Now we have saved LR we can use it instead of R0. */ \ 195 | "MOV LR, R0 \n\t" \ 196 | \ 197 | /* Pop R0 so we can save it onto the system mode stack. */\ 198 | "LDMIA SP!, {R0} \n\t" \ 199 | \ 200 | /* Push all the system mode registers onto the task stack. */\ 201 | "STMDB LR,{R0-LR}^ \n\t" \ 202 | "NOP \n\t" \ 203 | "SUB LR, LR, #60 \n\t" \ 204 | \ 205 | /* Push the SPSR onto the task stack. */ \ 206 | "MRS R0, SPSR \n\t" \ 207 | "STMDB LR!, {R0} \n\t" \ 208 | \ 209 | "LDR R0, =ulCriticalNesting \n\t" \ 210 | "LDR R0, [R0] \n\t" \ 211 | "STMDB LR!, {R0} \n\t" \ 212 | \ 213 | /* Store the new top of stack for the task. */ \ 214 | "LDR R0, =pxCurrentTCB \n\t" \ 215 | "LDR R0, [R0] \n\t" \ 216 | "STR LR, [R0] \n\t" \ 217 | ); \ 218 | ( void ) ulCriticalNesting; \ 219 | ( void ) pxCurrentTCB; \ 220 | } 221 | 222 | #endif 223 | 224 | extern void vTaskSwitchContext( void ); 225 | #define portYIELD_FROM_ISR() vTaskSwitchContext() 226 | #define portYIELD() __asm volatile ( "SWI 0" ) 227 | /*-----------------------------------------------------------*/ 228 | 229 | 230 | /* Critical section management. */ 231 | 232 | /* 233 | * The interrupt management utilities can only be called from ARM mode. When 234 | * THUMB_INTERWORK is defined the utilities are defined as functions in 235 | * portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not 236 | * defined then the utilities are defined as macros here - as per other ports. 237 | */ 238 | 239 | #ifdef THUMB_INTERWORK 240 | 241 | extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked)); 242 | extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked)); 243 | 244 | #define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb() 245 | #define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb() 246 | 247 | #else 248 | 249 | #define portDISABLE_INTERRUPTS() \ 250 | __asm volatile ( \ 251 | "STMDB SP!, {R0} \n\t" /* Push R0. */ \ 252 | "MRS R0, CPSR \n\t" /* Get CPSR. */ \ 253 | "ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \ 254 | "MSR CPSR, R0 \n\t" /* Write back modified value. */ \ 255 | "LDMIA SP!, {R0} " ) /* Pop R0. */ 256 | 257 | #define portENABLE_INTERRUPTS() \ 258 | __asm volatile ( \ 259 | "STMDB SP!, {R0} \n\t" /* Push R0. */ \ 260 | "MRS R0, CPSR \n\t" /* Get CPSR. */ \ 261 | "BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \ 262 | "MSR CPSR, R0 \n\t" /* Write back modified value. */ \ 263 | "LDMIA SP!, {R0} " ) /* Pop R0. */ 264 | 265 | #endif /* THUMB_INTERWORK */ 266 | 267 | extern void vPortEnterCritical( void ); 268 | extern void vPortExitCritical( void ); 269 | 270 | #define portENTER_CRITICAL() vPortEnterCritical(); 271 | #define portEXIT_CRITICAL() vPortExitCritical(); 272 | /*-----------------------------------------------------------*/ 273 | 274 | /* Task function macros as described on the FreeRTOS.org WEB site. */ 275 | #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) 276 | #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) 277 | 278 | #ifdef __cplusplus 279 | } 280 | #endif 281 | 282 | #endif /* PORTMACRO_H */ 283 | -------------------------------------------------------------------------------- /FreeRTOS/Source/portable/GCC/port.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Raspberry Pi Porting layer for FreeRTOS. (with modifications) 3 | * 4 | * original author: James Walmsley https://github.com/jameswalmsley/RaspberryPi-FreeRTOS 5 | * 6 | * modifications (mainly TrustZone and EPIT timer functionality): 7 | * @author: Michael Denzel 8 | * @contact: https://github.com/mdenzel 9 | * @license: GNU General Public License 2.0 or later 10 | * @date: 2017-03-17 11 | * @version: 0.1 12 | **/ 13 | 14 | #include 15 | 16 | //FreeRTOS 17 | #include "FreeRTOS.h" 18 | #include "task.h" 19 | 20 | //TrustZone 21 | #include "interrupts.h" 22 | #include "kernelpanic.h" 23 | 24 | //Drivers 25 | #include "mxc_serial.h" 26 | 27 | /* Constants required to setup the task context. */ 28 | #define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */ 29 | #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) 30 | #define portINSTRUCTION_SIZE ( ( StackType_t ) 4 ) 31 | #define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 ) 32 | 33 | // Constants required to setup the VIC for the tick ISR. 34 | //EPIT timer 1 at 0x53FAC000 35 | //EPIT timer 2 at 0x53FB0000 36 | #define portTIMER_BASE ((unsigned long) 0x53FAC000) 37 | 38 | typedef struct EPIT_TIMER_REGS { 39 | unsigned int CR; //control register 40 | unsigned int SR; //status register 41 | unsigned int LR; //load register 42 | unsigned int CMPR; //compare register 43 | unsigned int CNR; //counter register 44 | } EPIT_TIMER_REGS; 45 | 46 | static volatile EPIT_TIMER_REGS* const pRegs = (EPIT_TIMER_REGS*) (portTIMER_BASE); 47 | 48 | /*-----------------------------------------------------------*/ 49 | 50 | /* Setup the timer to generate the tick interrupts. */ 51 | static void prvSetupTimerInterrupt( void ); 52 | 53 | /* 54 | * The scheduler can only be started from ARM mode, so 55 | * vPortISRStartFirstSTask() is defined in portISR.c. 56 | */ 57 | extern void vPortISRStartFirstTask( void ); 58 | 59 | /*-----------------------------------------------------------*/ 60 | 61 | /* 62 | * Initialise the stack of a task to look exactly as if a call to 63 | * portSAVE_CONTEXT had been called. 64 | * 65 | * See header file for description. 66 | */ 67 | StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) 68 | { 69 | StackType_t *pxOriginalTOS; 70 | 71 | pxOriginalTOS = pxTopOfStack; 72 | 73 | /* To ensure asserts in tasks.c don't fail, although in this case the assert 74 | is not really required. */ 75 | pxTopOfStack--; 76 | 77 | /* Setup the initial stack of the task. The stack is set exactly as 78 | expected by the portRESTORE_CONTEXT() macro. */ 79 | 80 | /* First on the stack is the return address - which in this case is the 81 | start of the task. The offset is added to make the return address appear 82 | as it would within an IRQ ISR. */ 83 | *pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE; 84 | pxTopOfStack--; 85 | 86 | *pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */ 87 | pxTopOfStack--; 88 | *pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */ 89 | pxTopOfStack--; 90 | *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ 91 | pxTopOfStack--; 92 | *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ 93 | pxTopOfStack--; 94 | *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ 95 | pxTopOfStack--; 96 | *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ 97 | pxTopOfStack--; 98 | *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ 99 | pxTopOfStack--; 100 | *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ 101 | pxTopOfStack--; 102 | *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ 103 | pxTopOfStack--; 104 | *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ 105 | pxTopOfStack--; 106 | *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ 107 | pxTopOfStack--; 108 | *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ 109 | pxTopOfStack--; 110 | *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ 111 | pxTopOfStack--; 112 | *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ 113 | pxTopOfStack--; 114 | 115 | /* When the task starts is will expect to find the function parameter in 116 | R0. */ 117 | *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ 118 | pxTopOfStack--; 119 | 120 | /* The last thing onto the stack is the status register, which is set for 121 | system mode, with interrupts enabled. */ 122 | *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; 123 | 124 | if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 ) 125 | { 126 | /* We want the task to start in thumb mode. */ 127 | *pxTopOfStack |= portTHUMB_MODE_BIT; 128 | } 129 | 130 | pxTopOfStack--; 131 | 132 | /* Some optimisation levels use the stack differently to others. This 133 | means the interrupt flags cannot always be stored on the stack and will 134 | instead be stored in a variable, which is then saved as part of the 135 | tasks context. */ 136 | *pxTopOfStack = portNO_CRITICAL_SECTION_NESTING; 137 | 138 | return pxTopOfStack; 139 | } 140 | /*-----------------------------------------------------------*/ 141 | 142 | BaseType_t xPortStartScheduler( void ) 143 | { 144 | /* Start the timer that generates the tick ISR. Interrupts are disabled 145 | here already. */ 146 | prvSetupTimerInterrupt(); 147 | 148 | /* Start the first task. */ 149 | vPortISRStartFirstTask(); 150 | 151 | /* Should not get here! */ 152 | return 0; 153 | } 154 | /*-----------------------------------------------------------*/ 155 | 156 | void vPortEndScheduler( void ) 157 | { 158 | /* It is unlikely that the ARM port will require this function as there 159 | is nothing to return to. */ 160 | } 161 | /*-----------------------------------------------------------*/ 162 | 163 | /* 164 | * This is the TICK interrupt service routine, note. no SAVE/RESTORE_CONTEXT here 165 | * as thats done in the bottom-half of the ISR. 166 | */ 167 | void vTickISR(unsigned int nIRQ, void *pParam ) 168 | { 169 | #ifdef DEBUG 170 | //log 171 | cprintf("tick IRQ %d\n", nIRQ); 172 | #endif 173 | 174 | //acknowledge IRQ and clear status register 175 | AcknowledgeInterrupt(nIRQ); 176 | pRegs->SR = 0b1; 177 | 178 | //count 179 | xTaskIncrementTick(); 180 | 181 | #if configUSE_PREEMPTION == 1 182 | vTaskSwitchContext(); 183 | #endif 184 | } 185 | 186 | /* 187 | * Setup the timer 0 to generate the tick interrupts at the required frequency. 188 | */ 189 | static void prvSetupTimerInterrupt( void ) 190 | { 191 | //setup rate 192 | const uint32_t clock_frequency = 32768; //Hz 193 | const uint32_t ulCompareMatch = clock_frequency * configTICK_RATE_HZ; 194 | 195 | //log 196 | cprintf("setup timer interrupt\n"); 197 | 198 | const unsigned int enabled = CheckIRQ(); 199 | if(enabled == 1){ 200 | DisableInterrupts(); 201 | } 202 | { 203 | //FIXME: for a secure implementation this would have to be shielded from normal world! 204 | /*EPIT documentation: i.MX53 spec p. 1140 205 | * bit name needed(now/runtime) description 206 | * ----------------------------------------------------------- 207 | * 0 EN 0/1 enable bit 208 | * 1 ENMOD 0 enable mod (0=restart from same 209 | * value, 1=reset on restart) 210 | * 2 OCIEN 1 enable/disable interrupt 211 | * 3 RLD 1 reload control (0=free, 212 | * 1=setup-forget) 213 | * 4-15 PRESCALAR 0x000 clock prescaler val (divide by X) 214 | * 16 SWR 0 software reset 215 | * 17 IOVW 1/0 counter overwrite (Load Reg LR) 216 | * 18 DBGEN 1 functional in dbg mode? 217 | * 19 WAITEN 1 functional in wait mode? 218 | * 20 reserved 0 219 | * 21 STOPEN 0 functional in stop mode? 220 | * 22-23 OM 0b00 output mode (set pin on match? 221 | * => not needed due to IRQ) 222 | * 24-25 CLKSRC 0b01 clock source (00 off, 223 | * 01 peripheral, 10 high freq. 224 | * clock, 11 low freq. clock) 225 | * 26-31 reserved 0 226 | * 227 | * "Peripheral bus write access to the EPIT control register (EPITCR) and the EPIT load 228 | * register (EPITLR) results in one cycle of wait state, while other valid peripheral bus 229 | * accesses are with 0 wait state." 230 | * => NOP needed after CR and LR 231 | */ 232 | #ifdef DEBUG 233 | cprintf("EPIT: %x (before init)\n", pRegs->CR); 234 | #endif 235 | 236 | //1. make sure EPIT is disabled 237 | pRegs->CR = pRegs->CR & (~(0b1)); 238 | __asm volatile("nop"); 239 | 240 | //2. set OM=00 241 | pRegs->CR = pRegs->CR & (~(0b11 << 22)); 242 | __asm volatile("nop"); 243 | 244 | //3. disable EPIT interrupts 245 | pRegs->CR = pRegs->CR & (~(0b100)); 246 | __asm volatile("nop"); 247 | 248 | //4. program CLKSRC to 0b10 249 | pRegs->CR = (pRegs->CR & (~(0b1 << 24))) | (0b1 << 25); 250 | __asm volatile("nop"); 251 | 252 | //5. clear EPIT status register (SR) => write 0b1 to clear! 253 | pRegs->SR = 0b1; 254 | 255 | //6. enable EPIT interrupts 256 | pRegs->CR = pRegs->CR | 0b100; 257 | __asm volatile("nop"); 258 | 259 | //7. bring counter to defined state (IOVW and load register LR) 260 | //XXX: setting IOVW did not work, thus ENMOD is used (step 8.) 261 | //pRegs->CR = pRegs->CR | (0b1 << 17); 262 | //__asm volatile("nop"); 263 | //init load/compare values 264 | pRegs->LR = ulCompareMatch; 265 | __asm volatile("nop"); 266 | pRegs->CMPR = ulCompareMatch; 267 | //reset IOVW again 268 | //pRegs->CR = pRegs->CR & (~(0b1 << 17)); 269 | //__asm volatile("nop"); 270 | 271 | 272 | //8. init rest (except enable bit EN) 273 | // 0b 0000 0001 0000 1100 0000 0000 0000 1110 274 | // 0x 0 1 0 C 0 0 0 E 275 | pRegs->CR = 0x010C000E; 276 | __asm volatile("nop"); 277 | 278 | //9. enable EPIT 279 | pRegs->CR = pRegs->CR | (0b1); 280 | __asm volatile("nop"); 281 | //CR should now be 0x...F 282 | 283 | #ifdef DEBUG 284 | cprintf("EPIT: %x (=0x010C000F?)\n", pRegs->CR); 285 | cprintf("EPIT CNR: %x\n", pRegs->CNR); 286 | cprintf("EPIT CMPR: %x\n", pRegs->CMPR); 287 | cprintf("EPIT LR: %x\n", pRegs->LR); 288 | cprintf("EPIT CNR: %x\n", pRegs->CNR); 289 | #endif 290 | 291 | //setup timer interrupt 292 | //EPIT1 = IRQ 40 293 | //EPIT2 = IRQ 41 294 | if(RegisterInterrupt(40, vTickISR, NULL) != 0){ 295 | kernelpanic("EPIT: could not register IRQ 40"); 296 | } 297 | if(EnableInterrupt(40) != 0){ //all interrupts enabled by default, so this is redundant for maybe later 298 | kernelpanic("EPIT: IRQ 40 cannot be enabled"); 299 | } 300 | } 301 | if(enabled == 1){ 302 | EnableInterrupts(); 303 | } 304 | } 305 | /*-----------------------------------------------------------*/ 306 | 307 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/deprecated_definitions.h: -------------------------------------------------------------------------------- 1 | /* 2 | FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd. 3 | All rights reserved 4 | 5 | VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 6 | 7 | This file is part of the FreeRTOS distribution. 8 | 9 | FreeRTOS is free software; you can redistribute it and/or modify it under 10 | the terms of the GNU General Public License (version 2) as published by the 11 | Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. 12 | 13 | *************************************************************************** 14 | >>! NOTE: The modification to the GPL is included to allow you to !<< 15 | >>! distribute a combined work that includes FreeRTOS without being !<< 16 | >>! obliged to provide the source code for proprietary components !<< 17 | >>! outside of the FreeRTOS kernel. !<< 18 | *************************************************************************** 19 | 20 | FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 22 | FOR A PARTICULAR PURPOSE. Full license text is available on the following 23 | link: http://www.freertos.org/a00114.html 24 | 25 | *************************************************************************** 26 | * * 27 | * FreeRTOS provides completely free yet professionally developed, * 28 | * robust, strictly quality controlled, supported, and cross * 29 | * platform software that is more than just the market leader, it * 30 | * is the industry's de facto standard. * 31 | * * 32 | * Help yourself get started quickly while simultaneously helping * 33 | * to support the FreeRTOS project by purchasing a FreeRTOS * 34 | * tutorial book, reference manual, or both: * 35 | * http://www.FreeRTOS.org/Documentation * 36 | * * 37 | *************************************************************************** 38 | 39 | http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 40 | the FAQ page "My application does not run, what could be wrong?". Have you 41 | defined configASSERT()? 42 | 43 | http://www.FreeRTOS.org/support - In return for receiving this top quality 44 | embedded software for free we request you assist our global community by 45 | participating in the support forum. 46 | 47 | http://www.FreeRTOS.org/training - Investing in training allows your team to 48 | be as productive as possible as early as possible. Now you can receive 49 | FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 50 | Ltd, and the world's leading authority on the world's leading RTOS. 51 | 52 | http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 53 | including FreeRTOS+Trace - an indispensable productivity tool, a DOS 54 | compatible FAT file system, and our tiny thread aware UDP/IP stack. 55 | 56 | http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 57 | Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 58 | 59 | http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 60 | Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 61 | licenses offer ticketed support, indemnification and commercial middleware. 62 | 63 | http://www.SafeRTOS.com - High Integrity Systems also provide a safety 64 | engineered and independently SIL3 certified version for use in safety and 65 | mission critical applications that require provable dependability. 66 | 67 | 1 tab == 4 spaces! 68 | */ 69 | 70 | #ifndef DEPRECATED_DEFINITIONS_H 71 | #define DEPRECATED_DEFINITIONS_H 72 | 73 | 74 | /* Each FreeRTOS port has a unique portmacro.h header file. Originally a 75 | pre-processor definition was used to ensure the pre-processor found the correct 76 | portmacro.h file for the port being used. That scheme was deprecated in favour 77 | of setting the compiler's include path such that it found the correct 78 | portmacro.h file - removing the need for the constant and allowing the 79 | portmacro.h file to be located anywhere in relation to the port being used. The 80 | definitions below remain in the code for backward compatibility only. New 81 | projects should not use them. */ 82 | 83 | #ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT 84 | #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" 85 | typedef void ( __interrupt __far *pxISR )(); 86 | #endif 87 | 88 | #ifdef OPEN_WATCOM_FLASH_LITE_186_PORT 89 | #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" 90 | typedef void ( __interrupt __far *pxISR )(); 91 | #endif 92 | 93 | #ifdef GCC_MEGA_AVR 94 | #include "../portable/GCC/ATMega323/portmacro.h" 95 | #endif 96 | 97 | #ifdef IAR_MEGA_AVR 98 | #include "../portable/IAR/ATMega323/portmacro.h" 99 | #endif 100 | 101 | #ifdef MPLAB_PIC24_PORT 102 | #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" 103 | #endif 104 | 105 | #ifdef MPLAB_DSPIC_PORT 106 | #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" 107 | #endif 108 | 109 | #ifdef MPLAB_PIC18F_PORT 110 | #include "../../Source/portable/MPLAB/PIC18F/portmacro.h" 111 | #endif 112 | 113 | #ifdef MPLAB_PIC32MX_PORT 114 | #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" 115 | #endif 116 | 117 | #ifdef _FEDPICC 118 | #include "libFreeRTOS/Include/portmacro.h" 119 | #endif 120 | 121 | #ifdef SDCC_CYGNAL 122 | #include "../../Source/portable/SDCC/Cygnal/portmacro.h" 123 | #endif 124 | 125 | #ifdef GCC_ARM7 126 | #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" 127 | #endif 128 | 129 | #ifdef GCC_ARM7_ECLIPSE 130 | #include "portmacro.h" 131 | #endif 132 | 133 | #ifdef ROWLEY_LPC23xx 134 | #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" 135 | #endif 136 | 137 | #ifdef IAR_MSP430 138 | #include "..\..\Source\portable\IAR\MSP430\portmacro.h" 139 | #endif 140 | 141 | #ifdef GCC_MSP430 142 | #include "../../Source/portable/GCC/MSP430F449/portmacro.h" 143 | #endif 144 | 145 | #ifdef ROWLEY_MSP430 146 | #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" 147 | #endif 148 | 149 | #ifdef ARM7_LPC21xx_KEIL_RVDS 150 | #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" 151 | #endif 152 | 153 | #ifdef SAM7_GCC 154 | #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" 155 | #endif 156 | 157 | #ifdef SAM7_IAR 158 | #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" 159 | #endif 160 | 161 | #ifdef SAM9XE_IAR 162 | #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" 163 | #endif 164 | 165 | #ifdef LPC2000_IAR 166 | #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" 167 | #endif 168 | 169 | #ifdef STR71X_IAR 170 | #include "..\..\Source\portable\IAR\STR71x\portmacro.h" 171 | #endif 172 | 173 | #ifdef STR75X_IAR 174 | #include "..\..\Source\portable\IAR\STR75x\portmacro.h" 175 | #endif 176 | 177 | #ifdef STR75X_GCC 178 | #include "..\..\Source\portable\GCC\STR75x\portmacro.h" 179 | #endif 180 | 181 | #ifdef STR91X_IAR 182 | #include "..\..\Source\portable\IAR\STR91x\portmacro.h" 183 | #endif 184 | 185 | #ifdef GCC_H8S 186 | #include "../../Source/portable/GCC/H8S2329/portmacro.h" 187 | #endif 188 | 189 | #ifdef GCC_AT91FR40008 190 | #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" 191 | #endif 192 | 193 | #ifdef RVDS_ARMCM3_LM3S102 194 | #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" 195 | #endif 196 | 197 | #ifdef GCC_ARMCM3_LM3S102 198 | #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" 199 | #endif 200 | 201 | #ifdef GCC_ARMCM3 202 | #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" 203 | #endif 204 | 205 | #ifdef IAR_ARM_CM3 206 | #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" 207 | #endif 208 | 209 | #ifdef IAR_ARMCM3_LM 210 | #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" 211 | #endif 212 | 213 | #ifdef HCS12_CODE_WARRIOR 214 | #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" 215 | #endif 216 | 217 | #ifdef MICROBLAZE_GCC 218 | #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" 219 | #endif 220 | 221 | #ifdef TERN_EE 222 | #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" 223 | #endif 224 | 225 | #ifdef GCC_HCS12 226 | #include "../../Source/portable/GCC/HCS12/portmacro.h" 227 | #endif 228 | 229 | #ifdef GCC_MCF5235 230 | #include "../../Source/portable/GCC/MCF5235/portmacro.h" 231 | #endif 232 | 233 | #ifdef COLDFIRE_V2_GCC 234 | #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" 235 | #endif 236 | 237 | #ifdef COLDFIRE_V2_CODEWARRIOR 238 | #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" 239 | #endif 240 | 241 | #ifdef GCC_PPC405 242 | #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" 243 | #endif 244 | 245 | #ifdef GCC_PPC440 246 | #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" 247 | #endif 248 | 249 | #ifdef _16FX_SOFTUNE 250 | #include "..\..\Source\portable\Softune\MB96340\portmacro.h" 251 | #endif 252 | 253 | #ifdef BCC_INDUSTRIAL_PC_PORT 254 | /* A short file name has to be used in place of the normal 255 | FreeRTOSConfig.h when using the Borland compiler. */ 256 | #include "frconfig.h" 257 | #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" 258 | typedef void ( __interrupt __far *pxISR )(); 259 | #endif 260 | 261 | #ifdef BCC_FLASH_LITE_186_PORT 262 | /* A short file name has to be used in place of the normal 263 | FreeRTOSConfig.h when using the Borland compiler. */ 264 | #include "frconfig.h" 265 | #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" 266 | typedef void ( __interrupt __far *pxISR )(); 267 | #endif 268 | 269 | #ifdef __GNUC__ 270 | #ifdef __AVR32_AVR32A__ 271 | #include "portmacro.h" 272 | #endif 273 | #endif 274 | 275 | #ifdef __ICCAVR32__ 276 | #ifdef __CORE__ 277 | #if __CORE__ == __AVR32A__ 278 | #include "portmacro.h" 279 | #endif 280 | #endif 281 | #endif 282 | 283 | #ifdef __91467D 284 | #include "portmacro.h" 285 | #endif 286 | 287 | #ifdef __96340 288 | #include "portmacro.h" 289 | #endif 290 | 291 | 292 | #ifdef __IAR_V850ES_Fx3__ 293 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 294 | #endif 295 | 296 | #ifdef __IAR_V850ES_Jx3__ 297 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 298 | #endif 299 | 300 | #ifdef __IAR_V850ES_Jx3_L__ 301 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 302 | #endif 303 | 304 | #ifdef __IAR_V850ES_Jx2__ 305 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 306 | #endif 307 | 308 | #ifdef __IAR_V850ES_Hx2__ 309 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 310 | #endif 311 | 312 | #ifdef __IAR_78K0R_Kx3__ 313 | #include "../../Source/portable/IAR/78K0R/portmacro.h" 314 | #endif 315 | 316 | #ifdef __IAR_78K0R_Kx3L__ 317 | #include "../../Source/portable/IAR/78K0R/portmacro.h" 318 | #endif 319 | 320 | #endif /* DEPRECATED_DEFINITIONS_H */ 321 | 322 | -------------------------------------------------------------------------------- /FreeRTOS/Source/list.c: -------------------------------------------------------------------------------- 1 | /* 2 | FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd. 3 | All rights reserved 4 | 5 | VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 6 | 7 | This file is part of the FreeRTOS distribution. 8 | 9 | FreeRTOS is free software; you can redistribute it and/or modify it under 10 | the terms of the GNU General Public License (version 2) as published by the 11 | Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. 12 | 13 | *************************************************************************** 14 | >>! NOTE: The modification to the GPL is included to allow you to !<< 15 | >>! distribute a combined work that includes FreeRTOS without being !<< 16 | >>! obliged to provide the source code for proprietary components !<< 17 | >>! outside of the FreeRTOS kernel. !<< 18 | *************************************************************************** 19 | 20 | FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 22 | FOR A PARTICULAR PURPOSE. Full license text is available on the following 23 | link: http://www.freertos.org/a00114.html 24 | 25 | *************************************************************************** 26 | * * 27 | * FreeRTOS provides completely free yet professionally developed, * 28 | * robust, strictly quality controlled, supported, and cross * 29 | * platform software that is more than just the market leader, it * 30 | * is the industry's de facto standard. * 31 | * * 32 | * Help yourself get started quickly while simultaneously helping * 33 | * to support the FreeRTOS project by purchasing a FreeRTOS * 34 | * tutorial book, reference manual, or both: * 35 | * http://www.FreeRTOS.org/Documentation * 36 | * * 37 | *************************************************************************** 38 | 39 | http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 40 | the FAQ page "My application does not run, what could be wrong?". Have you 41 | defined configASSERT()? 42 | 43 | http://www.FreeRTOS.org/support - In return for receiving this top quality 44 | embedded software for free we request you assist our global community by 45 | participating in the support forum. 46 | 47 | http://www.FreeRTOS.org/training - Investing in training allows your team to 48 | be as productive as possible as early as possible. Now you can receive 49 | FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 50 | Ltd, and the world's leading authority on the world's leading RTOS. 51 | 52 | http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 53 | including FreeRTOS+Trace - an indispensable productivity tool, a DOS 54 | compatible FAT file system, and our tiny thread aware UDP/IP stack. 55 | 56 | http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 57 | Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 58 | 59 | http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 60 | Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 61 | licenses offer ticketed support, indemnification and commercial middleware. 62 | 63 | http://www.SafeRTOS.com - High Integrity Systems also provide a safety 64 | engineered and independently SIL3 certified version for use in safety and 65 | mission critical applications that require provable dependability. 66 | 67 | 1 tab == 4 spaces! 68 | */ 69 | 70 | 71 | #include 72 | #include "FreeRTOS.h" 73 | #include "list.h" 74 | 75 | /*----------------------------------------------------------- 76 | * PUBLIC LIST API documented in list.h 77 | *----------------------------------------------------------*/ 78 | 79 | void vListInitialise( List_t * const pxList ) 80 | { 81 | /* The list structure contains a list item which is used to mark the 82 | end of the list. To initialise the list the list end is inserted 83 | as the only list entry. */ 84 | pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 85 | 86 | /* The list end value is the highest possible value in the list to 87 | ensure it remains at the end of the list. */ 88 | pxList->xListEnd.xItemValue = portMAX_DELAY; 89 | 90 | /* The list end next and previous pointers point to itself so we know 91 | when the list is empty. */ 92 | pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 93 | pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 94 | 95 | pxList->uxNumberOfItems = ( UBaseType_t ) 0U; 96 | 97 | /* Write known values into the list if 98 | configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 99 | listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); 100 | listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); 101 | } 102 | /*-----------------------------------------------------------*/ 103 | 104 | void vListInitialiseItem( ListItem_t * const pxItem ) 105 | { 106 | /* Make sure the list item is not recorded as being on a list. */ 107 | pxItem->pvContainer = NULL; 108 | 109 | /* Write known values into the list item if 110 | configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 111 | listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); 112 | listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); 113 | } 114 | /*-----------------------------------------------------------*/ 115 | 116 | void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) 117 | { 118 | ListItem_t * const pxIndex = pxList->pxIndex; 119 | 120 | /* Only effective when configASSERT() is also defined, these tests may catch 121 | the list data structures being overwritten in memory. They will not catch 122 | data errors caused by incorrect configuration or use of FreeRTOS. */ 123 | listTEST_LIST_INTEGRITY( pxList ); 124 | listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); 125 | 126 | /* Insert a new list item into pxList, but rather than sort the list, 127 | makes the new list item the last item to be removed by a call to 128 | listGET_OWNER_OF_NEXT_ENTRY(). */ 129 | pxNewListItem->pxNext = pxIndex; 130 | pxNewListItem->pxPrevious = pxIndex->pxPrevious; 131 | 132 | /* Only used during decision coverage testing. */ 133 | mtCOVERAGE_TEST_DELAY(); 134 | 135 | pxIndex->pxPrevious->pxNext = pxNewListItem; 136 | pxIndex->pxPrevious = pxNewListItem; 137 | 138 | /* Remember which list the item is in. */ 139 | pxNewListItem->pvContainer = ( void * ) pxList; 140 | 141 | ( pxList->uxNumberOfItems )++; 142 | } 143 | /*-----------------------------------------------------------*/ 144 | 145 | void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) 146 | { 147 | ListItem_t *pxIterator; 148 | const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; 149 | 150 | /* Only effective when configASSERT() is also defined, these tests may catch 151 | the list data structures being overwritten in memory. They will not catch 152 | data errors caused by incorrect configuration or use of FreeRTOS. */ 153 | listTEST_LIST_INTEGRITY( pxList ); 154 | listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); 155 | 156 | /* Insert the new list item into the list, sorted in xItemValue order. 157 | 158 | If the list already contains a list item with the same item value then the 159 | new list item should be placed after it. This ensures that TCB's which are 160 | stored in ready lists (all of which have the same xItemValue value) get a 161 | share of the CPU. However, if the xItemValue is the same as the back marker 162 | the iteration loop below will not end. Therefore the value is checked 163 | first, and the algorithm slightly modified if necessary. */ 164 | if( xValueOfInsertion == portMAX_DELAY ) 165 | { 166 | pxIterator = pxList->xListEnd.pxPrevious; 167 | } 168 | else 169 | { 170 | /* *** NOTE *********************************************************** 171 | If you find your application is crashing here then likely causes are 172 | listed below. In addition see http://www.freertos.org/FAQHelp.html for 173 | more tips, and ensure configASSERT() is defined! 174 | http://www.freertos.org/a00110.html#configASSERT 175 | 176 | 1) Stack overflow - 177 | see http://www.freertos.org/Stacks-and-stack-overflow-checking.html 178 | 2) Incorrect interrupt priority assignment, especially on Cortex-M 179 | parts where numerically high priority values denote low actual 180 | interrupt priorities, which can seem counter intuitive. See 181 | http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition 182 | of configMAX_SYSCALL_INTERRUPT_PRIORITY on 183 | http://www.freertos.org/a00110.html 184 | 3) Calling an API function from within a critical section or when 185 | the scheduler is suspended, or calling an API function that does 186 | not end in "FromISR" from an interrupt. 187 | 4) Using a queue or semaphore before it has been initialised or 188 | before the scheduler has been started (are interrupts firing 189 | before vTaskStartScheduler() has been called?). 190 | **********************************************************************/ 191 | 192 | for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 193 | { 194 | /* There is nothing to do here, just iterating to the wanted 195 | insertion position. */ 196 | } 197 | } 198 | 199 | pxNewListItem->pxNext = pxIterator->pxNext; 200 | pxNewListItem->pxNext->pxPrevious = pxNewListItem; 201 | pxNewListItem->pxPrevious = pxIterator; 202 | pxIterator->pxNext = pxNewListItem; 203 | 204 | /* Remember which list the item is in. This allows fast removal of the 205 | item later. */ 206 | pxNewListItem->pvContainer = ( void * ) pxList; 207 | 208 | ( pxList->uxNumberOfItems )++; 209 | } 210 | /*-----------------------------------------------------------*/ 211 | 212 | UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) 213 | { 214 | /* The list item knows which list it is in. Obtain the list from the list 215 | item. */ 216 | List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer; 217 | 218 | pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; 219 | pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; 220 | 221 | /* Only used during decision coverage testing. */ 222 | mtCOVERAGE_TEST_DELAY(); 223 | 224 | /* Make sure the index is left pointing to a valid item. */ 225 | if( pxList->pxIndex == pxItemToRemove ) 226 | { 227 | pxList->pxIndex = pxItemToRemove->pxPrevious; 228 | } 229 | else 230 | { 231 | mtCOVERAGE_TEST_MARKER(); 232 | } 233 | 234 | pxItemToRemove->pvContainer = NULL; 235 | ( pxList->uxNumberOfItems )--; 236 | 237 | return pxList->uxNumberOfItems; 238 | } 239 | /*-----------------------------------------------------------*/ 240 | 241 | -------------------------------------------------------------------------------- /2023-11-27_Worldswitch_Code.drawio: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /2023-11-27_Worldswitch.drawio: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /FreeRTOS/Source/portable/MemMang/heap_2.c: -------------------------------------------------------------------------------- 1 | /* 2 | FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd. 3 | All rights reserved 4 | 5 | VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 6 | 7 | This file is part of the FreeRTOS distribution. 8 | 9 | FreeRTOS is free software; you can redistribute it and/or modify it under 10 | the terms of the GNU General Public License (version 2) as published by the 11 | Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. 12 | 13 | *************************************************************************** 14 | >>! NOTE: The modification to the GPL is included to allow you to !<< 15 | >>! distribute a combined work that includes FreeRTOS without being !<< 16 | >>! obliged to provide the source code for proprietary components !<< 17 | >>! outside of the FreeRTOS kernel. !<< 18 | *************************************************************************** 19 | 20 | FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 21 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 22 | FOR A PARTICULAR PURPOSE. Full license text is available on the following 23 | link: http://www.freertos.org/a00114.html 24 | 25 | *************************************************************************** 26 | * * 27 | * FreeRTOS provides completely free yet professionally developed, * 28 | * robust, strictly quality controlled, supported, and cross * 29 | * platform software that is more than just the market leader, it * 30 | * is the industry's de facto standard. * 31 | * * 32 | * Help yourself get started quickly while simultaneously helping * 33 | * to support the FreeRTOS project by purchasing a FreeRTOS * 34 | * tutorial book, reference manual, or both: * 35 | * http://www.FreeRTOS.org/Documentation * 36 | * * 37 | *************************************************************************** 38 | 39 | http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 40 | the FAQ page "My application does not run, what could be wrong?". Have you 41 | defined configASSERT()? 42 | 43 | http://www.FreeRTOS.org/support - In return for receiving this top quality 44 | embedded software for free we request you assist our global community by 45 | participating in the support forum. 46 | 47 | http://www.FreeRTOS.org/training - Investing in training allows your team to 48 | be as productive as possible as early as possible. Now you can receive 49 | FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 50 | Ltd, and the world's leading authority on the world's leading RTOS. 51 | 52 | http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 53 | including FreeRTOS+Trace - an indispensable productivity tool, a DOS 54 | compatible FAT file system, and our tiny thread aware UDP/IP stack. 55 | 56 | http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 57 | Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 58 | 59 | http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 60 | Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 61 | licenses offer ticketed support, indemnification and commercial middleware. 62 | 63 | http://www.SafeRTOS.com - High Integrity Systems also provide a safety 64 | engineered and independently SIL3 certified version for use in safety and 65 | mission critical applications that require provable dependability. 66 | 67 | 1 tab == 4 spaces! 68 | */ 69 | 70 | /* 71 | * A sample implementation of pvPortMalloc() and vPortFree() that permits 72 | * allocated blocks to be freed, but does not combine adjacent free blocks 73 | * into a single larger block (and so will fragment memory). See heap_4.c for 74 | * an equivalent that does combine adjacent blocks into single larger blocks. 75 | * 76 | * See heap_1.c, heap_3.c and heap_4.c for alternative implementations, and the 77 | * memory management pages of http://www.FreeRTOS.org for more information. 78 | */ 79 | #include 80 | 81 | /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 82 | all the API functions to use the MPU wrappers. That should only be done when 83 | task.h is included from an application file. */ 84 | #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 85 | 86 | #include "FreeRTOS.h" 87 | #include "task.h" 88 | 89 | #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 90 | 91 | /* A few bytes might be lost to byte aligning the heap start address. */ 92 | #define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) 93 | 94 | /* 95 | * Initialises the heap structures before their first use. 96 | */ 97 | static void prvHeapInit( void ); 98 | 99 | /* Allocate the memory for the heap. */ 100 | #if( configAPPLICATION_ALLOCATED_HEAP == 1 ) 101 | /* The application writer has already defined the array used for the RTOS 102 | heap - probably so it can be placed in a special segment or address. */ 103 | extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 104 | #else 105 | static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 106 | #endif /* configAPPLICATION_ALLOCATED_HEAP */ 107 | 108 | 109 | /* Define the linked list structure. This is used to link free blocks in order 110 | of their size. */ 111 | typedef struct A_BLOCK_LINK 112 | { 113 | struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ 114 | size_t xBlockSize; /*<< The size of the free block. */ 115 | } BlockLink_t; 116 | 117 | 118 | static const uint16_t heapSTRUCT_SIZE = ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK ); 119 | #define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) 120 | 121 | /* Create a couple of list links to mark the start and end of the list. */ 122 | static BlockLink_t xStart, xEnd; 123 | 124 | /* Keeps track of the number of free bytes remaining, but says nothing about 125 | fragmentation. */ 126 | static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; 127 | 128 | /* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */ 129 | 130 | /* 131 | * Insert a block into the list of free blocks - which is ordered by size of 132 | * the block. Small blocks at the start of the list and large blocks at the end 133 | * of the list. 134 | */ 135 | #define prvInsertBlockIntoFreeList( pxBlockToInsert ) \ 136 | { \ 137 | BlockLink_t *pxIterator; \ 138 | size_t xBlockSize; \ 139 | \ 140 | xBlockSize = pxBlockToInsert->xBlockSize; \ 141 | \ 142 | /* Iterate through the list until a block is found that has a larger size */ \ 143 | /* than the block we are inserting. */ \ 144 | for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \ 145 | { \ 146 | /* There is nothing to do here - just iterate to the correct position. */ \ 147 | } \ 148 | \ 149 | /* Update the list to include the block being inserted in the correct */ \ 150 | /* position. */ \ 151 | pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \ 152 | pxIterator->pxNextFreeBlock = pxBlockToInsert; \ 153 | } 154 | /*-----------------------------------------------------------*/ 155 | 156 | void *pvPortMalloc( size_t xWantedSize ) 157 | { 158 | BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; 159 | static BaseType_t xHeapHasBeenInitialised = pdFALSE; 160 | void *pvReturn = NULL; 161 | 162 | vTaskSuspendAll(); 163 | { 164 | /* If this is the first call to malloc then the heap will require 165 | initialisation to setup the list of free blocks. */ 166 | if( xHeapHasBeenInitialised == pdFALSE ) 167 | { 168 | prvHeapInit(); 169 | xHeapHasBeenInitialised = pdTRUE; 170 | } 171 | 172 | /* The wanted size is increased so it can contain a BlockLink_t 173 | structure in addition to the requested amount of bytes. */ 174 | if( xWantedSize > 0 ) 175 | { 176 | xWantedSize += heapSTRUCT_SIZE; 177 | 178 | /* Ensure that blocks are always aligned to the required number of bytes. */ 179 | if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0 ) 180 | { 181 | /* Byte alignment required. */ 182 | xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); 183 | } 184 | } 185 | 186 | if( ( xWantedSize > 0 ) && ( xWantedSize < configADJUSTED_HEAP_SIZE ) ) 187 | { 188 | /* Blocks are stored in byte order - traverse the list from the start 189 | (smallest) block until one of adequate size is found. */ 190 | pxPreviousBlock = &xStart; 191 | pxBlock = xStart.pxNextFreeBlock; 192 | while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) 193 | { 194 | pxPreviousBlock = pxBlock; 195 | pxBlock = pxBlock->pxNextFreeBlock; 196 | } 197 | 198 | /* If we found the end marker then a block of adequate size was not found. */ 199 | if( pxBlock != &xEnd ) 200 | { 201 | /* Return the memory space - jumping over the BlockLink_t structure 202 | at its start. */ 203 | pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); 204 | 205 | /* This block is being returned for use so must be taken out of the 206 | list of free blocks. */ 207 | pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; 208 | 209 | /* If the block is larger than required it can be split into two. */ 210 | if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) 211 | { 212 | /* This block is to be split into two. Create a new block 213 | following the number of bytes requested. The void cast is 214 | used to prevent byte alignment warnings from the compiler. */ 215 | pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); 216 | 217 | /* Calculate the sizes of two blocks split from the single 218 | block. */ 219 | pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; 220 | pxBlock->xBlockSize = xWantedSize; 221 | 222 | /* Insert the new block into the list of free blocks. */ 223 | prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); 224 | } 225 | 226 | xFreeBytesRemaining -= pxBlock->xBlockSize; 227 | } 228 | } 229 | 230 | traceMALLOC( pvReturn, xWantedSize ); 231 | } 232 | ( void ) xTaskResumeAll(); 233 | 234 | #if( configUSE_MALLOC_FAILED_HOOK == 1 ) 235 | { 236 | if( pvReturn == NULL ) 237 | { 238 | extern void vApplicationMallocFailedHook( void ); 239 | vApplicationMallocFailedHook(); 240 | } 241 | } 242 | #endif 243 | 244 | return pvReturn; 245 | } 246 | /*-----------------------------------------------------------*/ 247 | 248 | void vPortFree( void *pv ) 249 | { 250 | uint8_t *puc = ( uint8_t * ) pv; 251 | BlockLink_t *pxLink; 252 | 253 | if( pv != NULL ) 254 | { 255 | /* The memory being freed will have an BlockLink_t structure immediately 256 | before it. */ 257 | puc -= heapSTRUCT_SIZE; 258 | 259 | /* This unexpected casting is to keep some compilers from issuing 260 | byte alignment warnings. */ 261 | pxLink = ( void * ) puc; 262 | 263 | vTaskSuspendAll(); 264 | { 265 | /* Add this block to the list of free blocks. */ 266 | prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); 267 | xFreeBytesRemaining += pxLink->xBlockSize; 268 | traceFREE( pv, pxLink->xBlockSize ); 269 | } 270 | ( void ) xTaskResumeAll(); 271 | } 272 | } 273 | /*-----------------------------------------------------------*/ 274 | 275 | size_t xPortGetFreeHeapSize( void ) 276 | { 277 | return xFreeBytesRemaining; 278 | } 279 | /*-----------------------------------------------------------*/ 280 | 281 | void vPortInitialiseBlocks( void ) 282 | { 283 | /* This just exists to keep the linker quiet. */ 284 | } 285 | /*-----------------------------------------------------------*/ 286 | 287 | static void prvHeapInit( void ) 288 | { 289 | BlockLink_t *pxFirstFreeBlock; 290 | uint8_t *pucAlignedHeap; 291 | 292 | /* Ensure the heap starts on a correctly aligned boundary. */ 293 | pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); 294 | 295 | /* xStart is used to hold a pointer to the first item in the list of free 296 | blocks. The void cast is used to prevent compiler warnings. */ 297 | xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; 298 | xStart.xBlockSize = ( size_t ) 0; 299 | 300 | /* xEnd is used to mark the end of the list of free blocks. */ 301 | xEnd.xBlockSize = configADJUSTED_HEAP_SIZE; 302 | xEnd.pxNextFreeBlock = NULL; 303 | 304 | /* To start with there is a single free block that is sized to take up the 305 | entire heap space. */ 306 | pxFirstFreeBlock = ( void * ) pucAlignedHeap; 307 | pxFirstFreeBlock->xBlockSize = configADJUSTED_HEAP_SIZE; 308 | pxFirstFreeBlock->pxNextFreeBlock = &xEnd; 309 | } 310 | /*-----------------------------------------------------------*/ 311 | --------------------------------------------------------------------------------