├── Demo ├── FreeRTOSConfig.h ├── FreeRTOS_asm_vector.S ├── FreeRTOS_tick_config.c ├── demo.h ├── main.c ├── startup.S └── uart.c ├── FreeRTOS └── Source │ ├── include │ ├── FreeRTOS.h │ ├── deprecated_definitions.h │ ├── list.h │ ├── mpu_wrappers.h │ ├── portable.h │ ├── projdefs.h │ ├── queue.h │ ├── semphr.h │ ├── stack_macros.h │ ├── task.h │ └── timers.h │ ├── list.c │ ├── portable │ ├── GCC │ │ └── ARM_CA53_64_RaspberryPi3 │ │ │ ├── port.c │ │ │ ├── portASM.S │ │ │ └── portmacro.h │ └── MemMang │ │ └── heap_1.c │ ├── queue.c │ ├── tasks.c │ └── timers.c ├── License └── license.txt ├── Makefile ├── README.md └── raspberrypi3.ld /Demo/FreeRTOSConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef FREERTOS_CONFIG_H 29 | #define FREERTOS_CONFIG_H 30 | 31 | #define configUSE_PREEMPTION 1 32 | #define configUSE_IDLE_HOOK 1 33 | #define configUSE_TICK_HOOK 1 34 | #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) 35 | #define configMAX_PRIORITIES ( 8 ) 36 | #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 200 ) 37 | #define configTOTAL_HEAP_SIZE ( 124 * 1024 ) 38 | #define configUSE_16_BIT_TICKS 0 39 | 40 | #define configUSE_MUTEXES 1 41 | 42 | /* Software timer definitions. */ 43 | #define configUSE_TIMERS 1 44 | #define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) 45 | #define configTIMER_QUEUE_LENGTH 5 46 | #define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) 47 | 48 | /* Set the following definitions to 1 to include the API function, or zero 49 | to exclude the API function. */ 50 | #define INCLUDE_vTaskDelay 1 51 | 52 | #define INCLUDE_xSemaphoreGetMutexHolder 1 53 | 54 | void vConfigureTickInterrupt( void ); 55 | #define configSETUP_TICK_INTERRUPT() vConfigureTickInterrupt() 56 | void vClearTickInterrupt( void ); 57 | #define configCLEAR_TICK_INTERRUPT() vClearTickInterrupt() 58 | 59 | #endif /* FREERTOS_CONFIG_H */ 60 | 61 | -------------------------------------------------------------------------------- /Demo/FreeRTOS_asm_vector.S: -------------------------------------------------------------------------------- 1 | .org 0 2 | .text 3 | 4 | .globl _freertos_vector_table 5 | 6 | .section .vectors 7 | .balign 2048 8 | _vector_table: 9 | 10 | .set VBAR, _vector_table 11 | 12 | .org VBAR 13 | b _boot 14 | .org (VBAR + 0x80) 15 | b . 16 | .org (VBAR + 0x100) 17 | b . 18 | .org (VBAR + 0x180) 19 | b . 20 | 21 | .org (VBAR + 0x200) 22 | b . 23 | .org (VBAR + 0x280) 24 | b . 25 | .org (VBAR + 0x300) 26 | b . 27 | .org (VBAR + 0x380) 28 | b . 29 | 30 | .org (VBAR + 0x400) 31 | b . 32 | .org (VBAR + 0x480) 33 | b . 34 | .org (VBAR + 0x500) 35 | b . 36 | .org (VBAR + 0x580) 37 | b . 38 | 39 | .org (VBAR + 0x600) 40 | b . 41 | .org (VBAR + 0x680) 42 | b . 43 | .org (VBAR + 0x700) 44 | b . 45 | .org (VBAR + 0x780) 46 | b . 47 | 48 | /****************************************************************************** 49 | * Vector table to use when FreeRTOS is running. 50 | *****************************************************************************/ 51 | .set FREERTOS_VBAR, (VBAR+0x0800) 52 | 53 | .org(FREERTOS_VBAR) 54 | _freertos_vector_table: 55 | b FreeRTOS_SWI_Handler 56 | .org (FREERTOS_VBAR + 0x80) 57 | b FreeRTOS_IRQ_Handler 58 | .org (FREERTOS_VBAR + 0x100) 59 | b . 60 | .org (FREERTOS_VBAR + 0x180) 61 | b . 62 | 63 | .org (FREERTOS_VBAR + 0x200) 64 | b FreeRTOS_SWI_Handler 65 | .org (FREERTOS_VBAR + 0x280) 66 | b FreeRTOS_IRQ_Handler 67 | .org (FREERTOS_VBAR + 0x300) 68 | b . 69 | .org (FREERTOS_VBAR + 0x380) 70 | b . 71 | 72 | .org (FREERTOS_VBAR + 0x400) 73 | b . 74 | .org (FREERTOS_VBAR + 0x480) 75 | b . 76 | .org (FREERTOS_VBAR + 0x500) 77 | b . 78 | .org (FREERTOS_VBAR + 0x580) 79 | b . 80 | 81 | .org (FREERTOS_VBAR + 0x600) 82 | b . 83 | .org (FREERTOS_VBAR + 0x680) 84 | b . 85 | .org (FREERTOS_VBAR + 0x700) 86 | b . 87 | .org (FREERTOS_VBAR + 0x780) 88 | b . 89 | 90 | .end 91 | -------------------------------------------------------------------------------- /Demo/FreeRTOS_tick_config.c: -------------------------------------------------------------------------------- 1 | /* FreeRTOS includes. */ 2 | #include "FreeRTOS.h" 3 | #include "task.h" 4 | 5 | #include "demo.h" 6 | 7 | /* ARM Generic Timer */ 8 | #define CORE0_TIMER_IRQCNTL ((volatile uint32_t *)(0x40000040)) 9 | static uint32_t timer_cntfrq = 0; 10 | static uint32_t timer_tick = 0; 11 | 12 | void enable_cntv(void) 13 | { 14 | uint32_t cntv_ctl; 15 | cntv_ctl = 1; 16 | asm volatile ("msr cntv_ctl_el0, %0" :: "r" (cntv_ctl)); 17 | } 18 | /*-----------------------------------------------------------*/ 19 | 20 | void write_cntv_tval(uint32_t val) 21 | { 22 | asm volatile ("msr cntv_tval_el0, %0" :: "r" (val)); 23 | return; 24 | } 25 | /*-----------------------------------------------------------*/ 26 | 27 | uint32_t read_cntfrq(void) 28 | { 29 | uint32_t val; 30 | asm volatile ("mrs %0, cntfrq_el0" : "=r" (val)); 31 | return val; 32 | } 33 | /*-----------------------------------------------------------*/ 34 | 35 | void init_timer(void) 36 | { 37 | timer_cntfrq = timer_tick = read_cntfrq(); 38 | write_cntv_tval(timer_cntfrq); // clear cntv interrupt and set next 1 sec timer. 39 | return; 40 | } 41 | /*-----------------------------------------------------------*/ 42 | 43 | void timer_set_tick_rate_hz(uint32_t rate) 44 | { 45 | timer_tick = timer_cntfrq / rate ; 46 | write_cntv_tval(timer_tick); 47 | } 48 | /*-----------------------------------------------------------*/ 49 | 50 | void vConfigureTickInterrupt( void ) 51 | { 52 | /* init timer device. */ 53 | init_timer(); 54 | 55 | /* set tick rate. */ 56 | timer_set_tick_rate_hz(configTICK_RATE_HZ); 57 | 58 | /* timer interrupt routing. */ 59 | *CORE0_TIMER_IRQCNTL = 1 << 3; /* nCNTVIRQ routing to CORE0.*/ 60 | 61 | /* start & enable interrupts in the timer. */ 62 | enable_cntv(); 63 | } 64 | /*-----------------------------------------------------------*/ 65 | 66 | void vClearTickInterrupt( void ) 67 | { 68 | write_cntv_tval(timer_tick); // clear cntv interrupt and set next timer. 69 | return; 70 | } 71 | /*-----------------------------------------------------------*/ 72 | 73 | void vApplicationIRQHandler( uint32_t ulCORE0_INT_SRC ) 74 | { 75 | uint32_t ulInterruptID; 76 | ulInterruptID = ulCORE0_INT_SRC & 0x0007FFFFUL; 77 | 78 | /* call handler function */ 79 | if(ulInterruptID & (1 << 3)) 80 | { 81 | /* Generic Timer */ 82 | FreeRTOS_Tick_Handler(); 83 | } 84 | if(ulInterruptID & (1 << 8)) 85 | { 86 | /* Peripherals */ 87 | irq_handler(); 88 | } 89 | } 90 | 91 | -------------------------------------------------------------------------------- /Demo/demo.h: -------------------------------------------------------------------------------- 1 | /* uart.c */ 2 | void uart_putchar(uint8_t c); 3 | void uart_puts(const char* str); 4 | void uart_puthex(uint64_t v); 5 | uint32_t uart_read_bytes(uint8_t *buf, uint32_t length); 6 | void uart_init(void); 7 | 8 | void irq_handler(void); 9 | 10 | -------------------------------------------------------------------------------- /Demo/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "FreeRTOS.h" 5 | #include "task.h" 6 | #include "queue.h" 7 | #include "timers.h" 8 | #include "semphr.h" 9 | 10 | #include "demo.h" 11 | 12 | /* Prototypes for the standard FreeRTOS callback/hook functions implemented 13 | within this file. */ 14 | void vApplicationMallocFailedHook( void ); 15 | void vApplicationIdleHook( void ); 16 | 17 | static inline void io_halt(void) 18 | { 19 | asm volatile ("wfi"); 20 | } 21 | 22 | /*-----------------------------------------------------------*/ 23 | 24 | void TaskA(void *pvParameters) 25 | { 26 | (void) pvParameters; 27 | 28 | uart_puts("start TaskA\n"); 29 | 30 | for( ;; ) 31 | { 32 | uart_puthex(xTaskGetTickCount()); 33 | uart_putchar('\n'); 34 | vTaskDelay(500 / portTICK_RATE_MS); 35 | } 36 | } 37 | 38 | /*-----------------------------------------------------------*/ 39 | 40 | TimerHandle_t timer; 41 | uint32_t count=0; 42 | void interval_func(TimerHandle_t pxTimer) 43 | { 44 | (void) pxTimer; 45 | uint8_t buf[2]; 46 | uint32_t len = 0; 47 | 48 | len = uart_read_bytes(buf, sizeof(buf) - 1); 49 | if (len) 50 | uart_puts((char *)buf); 51 | } 52 | /*-----------------------------------------------------------*/ 53 | 54 | void main(void) 55 | { 56 | TaskHandle_t task_a; 57 | 58 | uart_init(); 59 | uart_puts("qemu exit: Ctrl-A x / qemu monitor: Ctrl-A c\n"); 60 | uart_puts("hello world\n"); 61 | 62 | xTaskCreate(TaskA, "Task A", 512, NULL, tskIDLE_PRIORITY, &task_a); 63 | 64 | timer = xTimerCreate("print_every_10ms",(10 / portTICK_RATE_MS), pdTRUE, (void *)0, interval_func); 65 | if(timer != NULL) 66 | { 67 | xTimerStart(timer, 0); 68 | } 69 | 70 | vTaskStartScheduler(); 71 | } 72 | /*-----------------------------------------------------------*/ 73 | 74 | void vApplicationIdleHook( void ) 75 | { 76 | } 77 | 78 | /*-----------------------------------------------------------*/ 79 | 80 | void vApplicationTickHook( void ) 81 | { 82 | } 83 | -------------------------------------------------------------------------------- /Demo/startup.S: -------------------------------------------------------------------------------- 1 | .section ".text.boot" 2 | 3 | // Make _start global. 4 | .globl _boot 5 | 6 | _boot: 7 | // in QEMU all of 4 ARM CPUs are started simultaniously by default. 8 | // use core 0 only, disable core 1,2,3. 9 | mrs x1, mpidr_el1 10 | and x1, x1, #3 11 | cmp x1, #0 12 | bne hang 13 | // address for stack pointer. 14 | ldr x1, =_boot 15 | // drop to EL2. 16 | mov x2, #0x5b1 // RW=1, HCE=1, SMD=1, RES=1, NS=1 17 | msr scr_el3, x2 18 | mov x2, #0x3c9 // D=1, A=1, I=1, F=1 M=EL2h 19 | msr spsr_el3, x2 20 | adr x2, start_el2 21 | msr elr_el3, x2 22 | eret 23 | 24 | start_el2: 25 | // set sp in EL1. 26 | msr sp_el1, x1 27 | // enable AArch64 in EL1. 28 | mov x0, #(1 << 31) // AArch64 29 | orr x0, x0, #(1 << 1) // SWIO hardwired on Pi3 30 | msr hcr_el2, x0 31 | mrs x0, hcr_el2 32 | // change execution level to EL1. 33 | mov x2, #0x3c5 // D=1, A=1, I=1, F=1 M=EL1h 34 | msr spsr_el2, x2 35 | adr x2, start_el1 36 | msr elr_el2, x2 37 | eret 38 | 39 | start_el1: 40 | // set sp 41 | mov sp, x1 42 | // clear bss. 43 | ldr x1, =__bss_start 44 | ldr w2, =__bss_size 45 | 1: cbz w2, 2f 46 | str xzr, [x1], #8 47 | sub w2, w2, #1 48 | cbnz w2, 1b 49 | 50 | 2: bl main 51 | 52 | hang: 53 | wfi 54 | b hang 55 | 56 | -------------------------------------------------------------------------------- /Demo/uart.c: -------------------------------------------------------------------------------- 1 | /* uart.c */ 2 | #include 3 | #include 4 | 5 | #include "FreeRTOS.h" 6 | #include "semphr.h" 7 | 8 | #define GPFSEL1 ((volatile uint32_t *)(0x3f200004)) 9 | #define GPPUDCLK0 ((volatile uint32_t *)(0x3f200098)) 10 | 11 | #define AUX_ENABLES ((volatile uint32_t *)(0x3F215004)) 12 | #define AUX_MU_IO ((volatile uint32_t *)(0x3F215040)) 13 | #define AUX_MU_IER ((volatile uint32_t *)(0x3F215044)) 14 | #define AUX_MU_IIR ((volatile uint32_t *)(0x3F215048)) 15 | #define AUX_MU_LCR ((volatile uint32_t *)(0x3F215048)) 16 | #define AUX_MU_LSR ((volatile uint32_t *)(0x3F215054)) 17 | #define AUX_MU_BAUD ((volatile uint32_t *)(0x3F215068)) 18 | 19 | struct UARTCTL { 20 | SemaphoreHandle_t *tx_mux; 21 | QueueHandle_t *rx_queue; 22 | }; 23 | struct UARTCTL *uartctl; 24 | 25 | void uart_putchar(uint8_t c) 26 | { 27 | xSemaphoreTake(uartctl->tx_mux, (portTickType) portMAX_DELAY); 28 | /* wait mini uart for tx idle. */ 29 | while ( !(*AUX_MU_LSR & (1 << 5)) ) { } 30 | *AUX_MU_IO = c; 31 | xSemaphoreGive(uartctl->tx_mux); 32 | } 33 | /*-----------------------------------------------------------*/ 34 | 35 | void uart_putchar_isr(uint8_t c) 36 | { 37 | xSemaphoreTakeFromISR(uartctl->tx_mux, NULL); 38 | /* wait mini uart for tx idle. */ 39 | while ( !(*AUX_MU_LSR & (1 << 5)) ) { } 40 | *AUX_MU_IO = c; 41 | xSemaphoreGiveFromISR(uartctl->tx_mux, NULL); 42 | } 43 | /*-----------------------------------------------------------*/ 44 | 45 | void uart_puts(const char* str) 46 | { 47 | for (size_t i = 0; str[i] != '\0'; i ++) 48 | uart_putchar((uint8_t)str[i]); 49 | } 50 | /*-----------------------------------------------------------*/ 51 | 52 | void uart_puthex(uint64_t v) 53 | { 54 | const char *hexdigits = "0123456789ABSDEF"; 55 | for (int i = 60; i >= 0; i -= 4) 56 | uart_putchar(hexdigits[(v >> i) & 0xf]); 57 | } 58 | /*-----------------------------------------------------------*/ 59 | 60 | uint32_t uart_read_bytes(uint8_t *buf, uint32_t length) 61 | { 62 | uint32_t num = uxQueueMessagesWaiting(uartctl->rx_queue); 63 | uint32_t i; 64 | 65 | for (i = 0; i < num || i < length; i++) { 66 | xQueueReceive(uartctl->rx_queue, &buf[i], (portTickType) portMAX_DELAY); 67 | } 68 | 69 | return i; 70 | } 71 | /*-----------------------------------------------------------*/ 72 | 73 | typedef void (*INTERRUPT_HANDLER) (void); 74 | typedef struct { 75 | INTERRUPT_HANDLER fn; 76 | } INTERRUPT_VECTOR; 77 | 78 | static INTERRUPT_VECTOR g_vector_table[64]; 79 | 80 | #define IRQ_ENABLE_1 ((volatile uint32_t *)(0x3F00B210)) 81 | static void uart_isr_register(void (*fn)(void)) 82 | { 83 | g_vector_table[29].fn = fn; 84 | 85 | /* enable AUX miniuart rx interrupt */ 86 | *AUX_ENABLES = 1; 87 | *AUX_MU_IIR = 6; /* clear tx & rx interrupt*/ 88 | *AUX_MU_IER = 1; 89 | 90 | /* unmask AUX interrupt */ 91 | *IRQ_ENABLE_1 = 1 << 29; 92 | } 93 | /*-----------------------------------------------------------*/ 94 | 95 | void uart_isr(void) 96 | { 97 | /* RX data */ 98 | if(*AUX_MU_LSR & 1 << 0) { 99 | uint8_t c = (uint8_t) 0xFF & *AUX_MU_IO; 100 | xQueueSendToBackFromISR(uartctl->rx_queue, &c, NULL); 101 | } 102 | } 103 | /*-----------------------------------------------------------*/ 104 | 105 | void uart_init(void) 106 | { 107 | uint32_t r; 108 | 109 | /* GPIO14 GPIO15 */ 110 | r = *GPFSEL1; 111 | r &= ~(7<<12|7<<15); 112 | r |= 2<<12|2<<15; /* ALT5 */ 113 | *GPFSEL1 = r; 114 | r = 150; while(r--) { asm volatile("nop"); } 115 | *GPPUDCLK0 = (1<<14)|(1<<15); 116 | r = 150; while(r--) { asm volatile("nop"); } 117 | *GPPUDCLK0 = 0; 118 | 119 | /* 115200/8bit */ 120 | *AUX_MU_BAUD = 270; /* 115200 bps */ 121 | *AUX_MU_LCR = 3; /* 8 bits */ 122 | /* Mini uart only support non parity. */ 123 | 124 | uartctl = pvPortMalloc(sizeof (struct UARTCTL)); 125 | uartctl->tx_mux = xSemaphoreCreateMutex(); 126 | uartctl->rx_queue = xQueueCreate(16, sizeof (uint8_t)); 127 | uart_isr_register(uart_isr); 128 | } 129 | /*-----------------------------------------------------------*/ 130 | #define IRQ_BASIC_PENDING ((volatile uint32_t *)(0x3F00B200)) 131 | #define IRQ_PENDING_1 ((volatile uint32_t *)(0x3F00B204)) 132 | #define IRQ_PENDING_2 ((volatile uint32_t *)(0x3F00B208)) 133 | 134 | static void handle_range(uint32_t pending, const uint32_t base) 135 | { 136 | while (pending) { 137 | /* get index of first set_bit */ 138 | uint32_t bit = 31 - __builtin_clz(pending); 139 | uint32_t irq = base + bit; 140 | 141 | /* call handler */ 142 | if(g_vector_table[irq].fn) 143 | g_vector_table[irq].fn(); 144 | 145 | /* clear bit */ 146 | pending &= ~(1UL << bit); 147 | } 148 | } 149 | 150 | void irq_handler(void) 151 | { 152 | uint32_t basic = *IRQ_BASIC_PENDING & 0x00000300; 153 | 154 | if (basic & 0x100) 155 | handle_range(*IRQ_PENDING_1, 0); 156 | if (basic & 0x200) 157 | handle_range(*IRQ_PENDING_2, 32); 158 | } 159 | 160 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/FreeRTOS.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef INC_FREERTOS_H 29 | #define INC_FREERTOS_H 30 | 31 | /* 32 | * Include the generic headers required for the FreeRTOS port being used. 33 | */ 34 | #include 35 | 36 | /* 37 | * If stdint.h cannot be located then: 38 | * + If using GCC ensure the -nostdint options is *not* being used. 39 | * + Ensure the project's include path includes the directory in which your 40 | * compiler stores stdint.h. 41 | * + Set any compiler options necessary for it to support C99, as technically 42 | * stdint.h is only mandatory with C99 (FreeRTOS does not require C99 in any 43 | * other way). 44 | * + The FreeRTOS download includes a simple stdint.h definition that can be 45 | * used in cases where none is provided by the compiler. The files only 46 | * contains the typedefs required to build FreeRTOS. Read the instructions 47 | * in FreeRTOS/source/stdint.readme for more information. 48 | */ 49 | #include /* READ COMMENT ABOVE. */ 50 | 51 | #ifdef __cplusplus 52 | extern "C" { 53 | #endif 54 | 55 | /* Application specific configuration options. */ 56 | #include "FreeRTOSConfig.h" 57 | 58 | /* Basic FreeRTOS definitions. */ 59 | #include "projdefs.h" 60 | 61 | /* Definitions specific to the port being used. */ 62 | #include "portable.h" 63 | 64 | /* Must be defaulted before configUSE_NEWLIB_REENTRANT is used below. */ 65 | #ifndef configUSE_NEWLIB_REENTRANT 66 | #define configUSE_NEWLIB_REENTRANT 0 67 | #endif 68 | 69 | /* Required if struct _reent is used. */ 70 | #if ( configUSE_NEWLIB_REENTRANT == 1 ) 71 | #include 72 | #endif 73 | /* 74 | * Check all the required application specific macros have been defined. 75 | * These macros are application specific and (as downloaded) are defined 76 | * within FreeRTOSConfig.h. 77 | */ 78 | 79 | #ifndef configMINIMAL_STACK_SIZE 80 | #error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value. 81 | #endif 82 | 83 | #ifndef configMAX_PRIORITIES 84 | #error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. 85 | #endif 86 | 87 | #if configMAX_PRIORITIES < 1 88 | #error configMAX_PRIORITIES must be defined to be greater than or equal to 1. 89 | #endif 90 | 91 | #ifndef configUSE_PREEMPTION 92 | #error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. 93 | #endif 94 | 95 | #ifndef configUSE_IDLE_HOOK 96 | #error Missing definition: configUSE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. 97 | #endif 98 | 99 | #ifndef configUSE_TICK_HOOK 100 | #error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. 101 | #endif 102 | 103 | #ifndef configUSE_16_BIT_TICKS 104 | #error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. 105 | #endif 106 | 107 | #ifndef configUSE_CO_ROUTINES 108 | #define configUSE_CO_ROUTINES 0 109 | #endif 110 | 111 | #ifndef INCLUDE_vTaskPrioritySet 112 | #define INCLUDE_vTaskPrioritySet 0 113 | #endif 114 | 115 | #ifndef INCLUDE_uxTaskPriorityGet 116 | #define INCLUDE_uxTaskPriorityGet 0 117 | #endif 118 | 119 | #ifndef INCLUDE_vTaskDelete 120 | #define INCLUDE_vTaskDelete 0 121 | #endif 122 | 123 | #ifndef INCLUDE_vTaskSuspend 124 | #define INCLUDE_vTaskSuspend 0 125 | #endif 126 | 127 | #ifndef INCLUDE_vTaskDelayUntil 128 | #define INCLUDE_vTaskDelayUntil 0 129 | #endif 130 | 131 | #ifndef INCLUDE_vTaskDelay 132 | #define INCLUDE_vTaskDelay 0 133 | #endif 134 | 135 | #ifndef INCLUDE_xTaskGetIdleTaskHandle 136 | #define INCLUDE_xTaskGetIdleTaskHandle 0 137 | #endif 138 | 139 | #ifndef INCLUDE_xTaskAbortDelay 140 | #define INCLUDE_xTaskAbortDelay 0 141 | #endif 142 | 143 | #ifndef INCLUDE_xQueueGetMutexHolder 144 | #define INCLUDE_xQueueGetMutexHolder 0 145 | #endif 146 | 147 | #ifndef INCLUDE_xSemaphoreGetMutexHolder 148 | #define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder 149 | #endif 150 | 151 | #ifndef INCLUDE_xTaskGetHandle 152 | #define INCLUDE_xTaskGetHandle 0 153 | #endif 154 | 155 | #ifndef INCLUDE_uxTaskGetStackHighWaterMark 156 | #define INCLUDE_uxTaskGetStackHighWaterMark 0 157 | #endif 158 | 159 | #ifndef INCLUDE_eTaskGetState 160 | #define INCLUDE_eTaskGetState 0 161 | #endif 162 | 163 | #ifndef INCLUDE_xTaskResumeFromISR 164 | #define INCLUDE_xTaskResumeFromISR 1 165 | #endif 166 | 167 | #ifndef INCLUDE_xTimerPendFunctionCall 168 | #define INCLUDE_xTimerPendFunctionCall 0 169 | #endif 170 | 171 | #ifndef INCLUDE_xTaskGetSchedulerState 172 | #define INCLUDE_xTaskGetSchedulerState 0 173 | #endif 174 | 175 | #ifndef INCLUDE_xTaskGetCurrentTaskHandle 176 | #define INCLUDE_xTaskGetCurrentTaskHandle 0 177 | #endif 178 | 179 | #if configUSE_CO_ROUTINES != 0 180 | #ifndef configMAX_CO_ROUTINE_PRIORITIES 181 | #error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1. 182 | #endif 183 | #endif 184 | 185 | #ifndef configUSE_DAEMON_TASK_STARTUP_HOOK 186 | #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 187 | #endif 188 | 189 | #ifndef configUSE_APPLICATION_TASK_TAG 190 | #define configUSE_APPLICATION_TASK_TAG 0 191 | #endif 192 | 193 | #ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS 194 | #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 195 | #endif 196 | 197 | #ifndef configUSE_RECURSIVE_MUTEXES 198 | #define configUSE_RECURSIVE_MUTEXES 0 199 | #endif 200 | 201 | #ifndef configUSE_MUTEXES 202 | #define configUSE_MUTEXES 0 203 | #endif 204 | 205 | #ifndef configUSE_TIMERS 206 | #define configUSE_TIMERS 0 207 | #endif 208 | 209 | #ifndef configUSE_COUNTING_SEMAPHORES 210 | #define configUSE_COUNTING_SEMAPHORES 0 211 | #endif 212 | 213 | #ifndef configUSE_ALTERNATIVE_API 214 | #define configUSE_ALTERNATIVE_API 0 215 | #endif 216 | 217 | #ifndef portCRITICAL_NESTING_IN_TCB 218 | #define portCRITICAL_NESTING_IN_TCB 0 219 | #endif 220 | 221 | #ifndef configMAX_TASK_NAME_LEN 222 | #define configMAX_TASK_NAME_LEN 16 223 | #endif 224 | 225 | #ifndef configIDLE_SHOULD_YIELD 226 | #define configIDLE_SHOULD_YIELD 1 227 | #endif 228 | 229 | #if configMAX_TASK_NAME_LEN < 1 230 | #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h 231 | #endif 232 | 233 | #ifndef configASSERT 234 | #define configASSERT( x ) 235 | #define configASSERT_DEFINED 0 236 | #else 237 | #define configASSERT_DEFINED 1 238 | #endif 239 | 240 | /* The timers module relies on xTaskGetSchedulerState(). */ 241 | #if configUSE_TIMERS == 1 242 | 243 | #ifndef configTIMER_TASK_PRIORITY 244 | #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. 245 | #endif /* configTIMER_TASK_PRIORITY */ 246 | 247 | #ifndef configTIMER_QUEUE_LENGTH 248 | #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. 249 | #endif /* configTIMER_QUEUE_LENGTH */ 250 | 251 | #ifndef configTIMER_TASK_STACK_DEPTH 252 | #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. 253 | #endif /* configTIMER_TASK_STACK_DEPTH */ 254 | 255 | #endif /* configUSE_TIMERS */ 256 | 257 | #ifndef portSET_INTERRUPT_MASK_FROM_ISR 258 | #define portSET_INTERRUPT_MASK_FROM_ISR() 0 259 | #endif 260 | 261 | #ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR 262 | #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue 263 | #endif 264 | 265 | #ifndef portCLEAN_UP_TCB 266 | #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB 267 | #endif 268 | 269 | #ifndef portPRE_TASK_DELETE_HOOK 270 | #define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending ) 271 | #endif 272 | 273 | #ifndef portSETUP_TCB 274 | #define portSETUP_TCB( pxTCB ) ( void ) pxTCB 275 | #endif 276 | 277 | #ifndef configQUEUE_REGISTRY_SIZE 278 | #define configQUEUE_REGISTRY_SIZE 0U 279 | #endif 280 | 281 | #if ( configQUEUE_REGISTRY_SIZE < 1 ) 282 | #define vQueueAddToRegistry( xQueue, pcName ) 283 | #define vQueueUnregisterQueue( xQueue ) 284 | #define pcQueueGetName( xQueue ) 285 | #endif 286 | 287 | #ifndef portPOINTER_SIZE_TYPE 288 | #define portPOINTER_SIZE_TYPE uint32_t 289 | #endif 290 | 291 | /* Remove any unused trace macros. */ 292 | #ifndef traceSTART 293 | /* Used to perform any necessary initialisation - for example, open a file 294 | into which trace is to be written. */ 295 | #define traceSTART() 296 | #endif 297 | 298 | #ifndef traceEND 299 | /* Use to close a trace, for example close a file into which trace has been 300 | written. */ 301 | #define traceEND() 302 | #endif 303 | 304 | #ifndef traceTASK_SWITCHED_IN 305 | /* Called after a task has been selected to run. pxCurrentTCB holds a pointer 306 | to the task control block of the selected task. */ 307 | #define traceTASK_SWITCHED_IN() 308 | #endif 309 | 310 | #ifndef traceINCREASE_TICK_COUNT 311 | /* Called before stepping the tick count after waking from tickless idle 312 | sleep. */ 313 | #define traceINCREASE_TICK_COUNT( x ) 314 | #endif 315 | 316 | #ifndef traceLOW_POWER_IDLE_BEGIN 317 | /* Called immediately before entering tickless idle. */ 318 | #define traceLOW_POWER_IDLE_BEGIN() 319 | #endif 320 | 321 | #ifndef traceLOW_POWER_IDLE_END 322 | /* Called when returning to the Idle task after a tickless idle. */ 323 | #define traceLOW_POWER_IDLE_END() 324 | #endif 325 | 326 | #ifndef traceTASK_SWITCHED_OUT 327 | /* Called before a task has been selected to run. pxCurrentTCB holds a pointer 328 | to the task control block of the task being switched out. */ 329 | #define traceTASK_SWITCHED_OUT() 330 | #endif 331 | 332 | #ifndef traceTASK_PRIORITY_INHERIT 333 | /* Called when a task attempts to take a mutex that is already held by a 334 | lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task 335 | that holds the mutex. uxInheritedPriority is the priority the mutex holder 336 | will inherit (the priority of the task that is attempting to obtain the 337 | muted. */ 338 | #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) 339 | #endif 340 | 341 | #ifndef traceTASK_PRIORITY_DISINHERIT 342 | /* Called when a task releases a mutex, the holding of which had resulted in 343 | the task inheriting the priority of a higher priority task. 344 | pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the 345 | mutex. uxOriginalPriority is the task's configured (base) priority. */ 346 | #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) 347 | #endif 348 | 349 | #ifndef traceBLOCKING_ON_QUEUE_RECEIVE 350 | /* Task is about to block because it cannot read from a 351 | queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore 352 | upon which the read was attempted. pxCurrentTCB points to the TCB of the 353 | task that attempted the read. */ 354 | #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) 355 | #endif 356 | 357 | #ifndef traceBLOCKING_ON_QUEUE_PEEK 358 | /* Task is about to block because it cannot read from a 359 | queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore 360 | upon which the read was attempted. pxCurrentTCB points to the TCB of the 361 | task that attempted the read. */ 362 | #define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) 363 | #endif 364 | 365 | #ifndef traceBLOCKING_ON_QUEUE_SEND 366 | /* Task is about to block because it cannot write to a 367 | queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore 368 | upon which the write was attempted. pxCurrentTCB points to the TCB of the 369 | task that attempted the write. */ 370 | #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) 371 | #endif 372 | 373 | #ifndef configCHECK_FOR_STACK_OVERFLOW 374 | #define configCHECK_FOR_STACK_OVERFLOW 0 375 | #endif 376 | 377 | #ifndef configRECORD_STACK_HIGH_ADDRESS 378 | #define configRECORD_STACK_HIGH_ADDRESS 0 379 | #endif 380 | 381 | #ifndef configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 382 | #define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 0 383 | #endif 384 | 385 | /* The following event macros are embedded in the kernel API calls. */ 386 | 387 | #ifndef traceMOVED_TASK_TO_READY_STATE 388 | #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) 389 | #endif 390 | 391 | #ifndef tracePOST_MOVED_TASK_TO_READY_STATE 392 | #define tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) 393 | #endif 394 | 395 | #ifndef traceQUEUE_CREATE 396 | #define traceQUEUE_CREATE( pxNewQueue ) 397 | #endif 398 | 399 | #ifndef traceQUEUE_CREATE_FAILED 400 | #define traceQUEUE_CREATE_FAILED( ucQueueType ) 401 | #endif 402 | 403 | #ifndef traceCREATE_MUTEX 404 | #define traceCREATE_MUTEX( pxNewQueue ) 405 | #endif 406 | 407 | #ifndef traceCREATE_MUTEX_FAILED 408 | #define traceCREATE_MUTEX_FAILED() 409 | #endif 410 | 411 | #ifndef traceGIVE_MUTEX_RECURSIVE 412 | #define traceGIVE_MUTEX_RECURSIVE( pxMutex ) 413 | #endif 414 | 415 | #ifndef traceGIVE_MUTEX_RECURSIVE_FAILED 416 | #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) 417 | #endif 418 | 419 | #ifndef traceTAKE_MUTEX_RECURSIVE 420 | #define traceTAKE_MUTEX_RECURSIVE( pxMutex ) 421 | #endif 422 | 423 | #ifndef traceTAKE_MUTEX_RECURSIVE_FAILED 424 | #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ) 425 | #endif 426 | 427 | #ifndef traceCREATE_COUNTING_SEMAPHORE 428 | #define traceCREATE_COUNTING_SEMAPHORE() 429 | #endif 430 | 431 | #ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED 432 | #define traceCREATE_COUNTING_SEMAPHORE_FAILED() 433 | #endif 434 | 435 | #ifndef traceQUEUE_SEND 436 | #define traceQUEUE_SEND( pxQueue ) 437 | #endif 438 | 439 | #ifndef traceQUEUE_SEND_FAILED 440 | #define traceQUEUE_SEND_FAILED( pxQueue ) 441 | #endif 442 | 443 | #ifndef traceQUEUE_RECEIVE 444 | #define traceQUEUE_RECEIVE( pxQueue ) 445 | #endif 446 | 447 | #ifndef traceQUEUE_PEEK 448 | #define traceQUEUE_PEEK( pxQueue ) 449 | #endif 450 | 451 | #ifndef traceQUEUE_PEEK_FAILED 452 | #define traceQUEUE_PEEK_FAILED( pxQueue ) 453 | #endif 454 | 455 | #ifndef traceQUEUE_PEEK_FROM_ISR 456 | #define traceQUEUE_PEEK_FROM_ISR( pxQueue ) 457 | #endif 458 | 459 | #ifndef traceQUEUE_RECEIVE_FAILED 460 | #define traceQUEUE_RECEIVE_FAILED( pxQueue ) 461 | #endif 462 | 463 | #ifndef traceQUEUE_SEND_FROM_ISR 464 | #define traceQUEUE_SEND_FROM_ISR( pxQueue ) 465 | #endif 466 | 467 | #ifndef traceQUEUE_SEND_FROM_ISR_FAILED 468 | #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) 469 | #endif 470 | 471 | #ifndef traceQUEUE_RECEIVE_FROM_ISR 472 | #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) 473 | #endif 474 | 475 | #ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED 476 | #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) 477 | #endif 478 | 479 | #ifndef traceQUEUE_PEEK_FROM_ISR_FAILED 480 | #define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) 481 | #endif 482 | 483 | #ifndef traceQUEUE_DELETE 484 | #define traceQUEUE_DELETE( pxQueue ) 485 | #endif 486 | 487 | #ifndef traceTASK_CREATE 488 | #define traceTASK_CREATE( pxNewTCB ) 489 | #endif 490 | 491 | #ifndef traceTASK_CREATE_FAILED 492 | #define traceTASK_CREATE_FAILED() 493 | #endif 494 | 495 | #ifndef traceTASK_DELETE 496 | #define traceTASK_DELETE( pxTaskToDelete ) 497 | #endif 498 | 499 | #ifndef traceTASK_DELAY_UNTIL 500 | #define traceTASK_DELAY_UNTIL( x ) 501 | #endif 502 | 503 | #ifndef traceTASK_DELAY 504 | #define traceTASK_DELAY() 505 | #endif 506 | 507 | #ifndef traceTASK_PRIORITY_SET 508 | #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) 509 | #endif 510 | 511 | #ifndef traceTASK_SUSPEND 512 | #define traceTASK_SUSPEND( pxTaskToSuspend ) 513 | #endif 514 | 515 | #ifndef traceTASK_RESUME 516 | #define traceTASK_RESUME( pxTaskToResume ) 517 | #endif 518 | 519 | #ifndef traceTASK_RESUME_FROM_ISR 520 | #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) 521 | #endif 522 | 523 | #ifndef traceTASK_INCREMENT_TICK 524 | #define traceTASK_INCREMENT_TICK( xTickCount ) 525 | #endif 526 | 527 | #ifndef traceTIMER_CREATE 528 | #define traceTIMER_CREATE( pxNewTimer ) 529 | #endif 530 | 531 | #ifndef traceTIMER_CREATE_FAILED 532 | #define traceTIMER_CREATE_FAILED() 533 | #endif 534 | 535 | #ifndef traceTIMER_COMMAND_SEND 536 | #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) 537 | #endif 538 | 539 | #ifndef traceTIMER_EXPIRED 540 | #define traceTIMER_EXPIRED( pxTimer ) 541 | #endif 542 | 543 | #ifndef traceTIMER_COMMAND_RECEIVED 544 | #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) 545 | #endif 546 | 547 | #ifndef traceMALLOC 548 | #define traceMALLOC( pvAddress, uiSize ) 549 | #endif 550 | 551 | #ifndef traceFREE 552 | #define traceFREE( pvAddress, uiSize ) 553 | #endif 554 | 555 | #ifndef traceEVENT_GROUP_CREATE 556 | #define traceEVENT_GROUP_CREATE( xEventGroup ) 557 | #endif 558 | 559 | #ifndef traceEVENT_GROUP_CREATE_FAILED 560 | #define traceEVENT_GROUP_CREATE_FAILED() 561 | #endif 562 | 563 | #ifndef traceEVENT_GROUP_SYNC_BLOCK 564 | #define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ) 565 | #endif 566 | 567 | #ifndef traceEVENT_GROUP_SYNC_END 568 | #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred 569 | #endif 570 | 571 | #ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK 572 | #define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ) 573 | #endif 574 | 575 | #ifndef traceEVENT_GROUP_WAIT_BITS_END 576 | #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred 577 | #endif 578 | 579 | #ifndef traceEVENT_GROUP_CLEAR_BITS 580 | #define traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ) 581 | #endif 582 | 583 | #ifndef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR 584 | #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ) 585 | #endif 586 | 587 | #ifndef traceEVENT_GROUP_SET_BITS 588 | #define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ) 589 | #endif 590 | 591 | #ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR 592 | #define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ) 593 | #endif 594 | 595 | #ifndef traceEVENT_GROUP_DELETE 596 | #define traceEVENT_GROUP_DELETE( xEventGroup ) 597 | #endif 598 | 599 | #ifndef tracePEND_FUNC_CALL 600 | #define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret) 601 | #endif 602 | 603 | #ifndef tracePEND_FUNC_CALL_FROM_ISR 604 | #define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret) 605 | #endif 606 | 607 | #ifndef traceQUEUE_REGISTRY_ADD 608 | #define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName) 609 | #endif 610 | 611 | #ifndef traceTASK_NOTIFY_TAKE_BLOCK 612 | #define traceTASK_NOTIFY_TAKE_BLOCK() 613 | #endif 614 | 615 | #ifndef traceTASK_NOTIFY_TAKE 616 | #define traceTASK_NOTIFY_TAKE() 617 | #endif 618 | 619 | #ifndef traceTASK_NOTIFY_WAIT_BLOCK 620 | #define traceTASK_NOTIFY_WAIT_BLOCK() 621 | #endif 622 | 623 | #ifndef traceTASK_NOTIFY_WAIT 624 | #define traceTASK_NOTIFY_WAIT() 625 | #endif 626 | 627 | #ifndef traceTASK_NOTIFY 628 | #define traceTASK_NOTIFY() 629 | #endif 630 | 631 | #ifndef traceTASK_NOTIFY_FROM_ISR 632 | #define traceTASK_NOTIFY_FROM_ISR() 633 | #endif 634 | 635 | #ifndef traceTASK_NOTIFY_GIVE_FROM_ISR 636 | #define traceTASK_NOTIFY_GIVE_FROM_ISR() 637 | #endif 638 | 639 | #ifndef traceSTREAM_BUFFER_CREATE_FAILED 640 | #define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) 641 | #endif 642 | 643 | #ifndef traceSTREAM_BUFFER_CREATE_STATIC_FAILED 644 | #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) 645 | #endif 646 | 647 | #ifndef traceSTREAM_BUFFER_CREATE 648 | #define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) 649 | #endif 650 | 651 | #ifndef traceSTREAM_BUFFER_DELETE 652 | #define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) 653 | #endif 654 | 655 | #ifndef traceSTREAM_BUFFER_RESET 656 | #define traceSTREAM_BUFFER_RESET( xStreamBuffer ) 657 | #endif 658 | 659 | #ifndef traceBLOCKING_ON_STREAM_BUFFER_SEND 660 | #define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) 661 | #endif 662 | 663 | #ifndef traceSTREAM_BUFFER_SEND 664 | #define traceSTREAM_BUFFER_SEND( xStreamBuffer, xBytesSent ) 665 | #endif 666 | 667 | #ifndef traceSTREAM_BUFFER_SEND_FAILED 668 | #define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) 669 | #endif 670 | 671 | #ifndef traceSTREAM_BUFFER_SEND_FROM_ISR 672 | #define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xBytesSent ) 673 | #endif 674 | 675 | #ifndef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE 676 | #define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) 677 | #endif 678 | 679 | #ifndef traceSTREAM_BUFFER_RECEIVE 680 | #define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) 681 | #endif 682 | 683 | #ifndef traceSTREAM_BUFFER_RECEIVE_FAILED 684 | #define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) 685 | #endif 686 | 687 | #ifndef traceSTREAM_BUFFER_RECEIVE_FROM_ISR 688 | #define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) 689 | #endif 690 | 691 | #ifndef configGENERATE_RUN_TIME_STATS 692 | #define configGENERATE_RUN_TIME_STATS 0 693 | #endif 694 | 695 | #if ( configGENERATE_RUN_TIME_STATS == 1 ) 696 | 697 | #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS 698 | #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. 699 | #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ 700 | 701 | #ifndef portGET_RUN_TIME_COUNTER_VALUE 702 | #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE 703 | #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. 704 | #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ 705 | #endif /* portGET_RUN_TIME_COUNTER_VALUE */ 706 | 707 | #endif /* configGENERATE_RUN_TIME_STATS */ 708 | 709 | #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS 710 | #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() 711 | #endif 712 | 713 | #ifndef configUSE_MALLOC_FAILED_HOOK 714 | #define configUSE_MALLOC_FAILED_HOOK 0 715 | #endif 716 | 717 | #ifndef portPRIVILEGE_BIT 718 | #define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 ) 719 | #endif 720 | 721 | #ifndef portYIELD_WITHIN_API 722 | #define portYIELD_WITHIN_API portYIELD 723 | #endif 724 | 725 | #ifndef portSUPPRESS_TICKS_AND_SLEEP 726 | #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) 727 | #endif 728 | 729 | #ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP 730 | #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 731 | #endif 732 | 733 | #if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2 734 | #error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2 735 | #endif 736 | 737 | #ifndef configUSE_TICKLESS_IDLE 738 | #define configUSE_TICKLESS_IDLE 0 739 | #endif 740 | 741 | #ifndef configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING 742 | #define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x ) 743 | #endif 744 | 745 | #ifndef configPRE_SLEEP_PROCESSING 746 | #define configPRE_SLEEP_PROCESSING( x ) 747 | #endif 748 | 749 | #ifndef configPOST_SLEEP_PROCESSING 750 | #define configPOST_SLEEP_PROCESSING( x ) 751 | #endif 752 | 753 | #ifndef configUSE_QUEUE_SETS 754 | #define configUSE_QUEUE_SETS 0 755 | #endif 756 | 757 | #ifndef portTASK_USES_FLOATING_POINT 758 | #define portTASK_USES_FLOATING_POINT() 759 | #endif 760 | 761 | #ifndef portTASK_CALLS_SECURE_FUNCTIONS 762 | #define portTASK_CALLS_SECURE_FUNCTIONS() 763 | #endif 764 | 765 | #ifndef configUSE_TIME_SLICING 766 | #define configUSE_TIME_SLICING 1 767 | #endif 768 | 769 | #ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 770 | #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 771 | #endif 772 | 773 | #ifndef configUSE_STATS_FORMATTING_FUNCTIONS 774 | #define configUSE_STATS_FORMATTING_FUNCTIONS 0 775 | #endif 776 | 777 | #ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID 778 | #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() 779 | #endif 780 | 781 | #ifndef configUSE_TRACE_FACILITY 782 | #define configUSE_TRACE_FACILITY 0 783 | #endif 784 | 785 | #ifndef mtCOVERAGE_TEST_MARKER 786 | #define mtCOVERAGE_TEST_MARKER() 787 | #endif 788 | 789 | #ifndef mtCOVERAGE_TEST_DELAY 790 | #define mtCOVERAGE_TEST_DELAY() 791 | #endif 792 | 793 | #ifndef portASSERT_IF_IN_ISR 794 | #define portASSERT_IF_IN_ISR() 795 | #endif 796 | 797 | #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION 798 | #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 799 | #endif 800 | 801 | #ifndef configAPPLICATION_ALLOCATED_HEAP 802 | #define configAPPLICATION_ALLOCATED_HEAP 0 803 | #endif 804 | 805 | #ifndef configUSE_TASK_NOTIFICATIONS 806 | #define configUSE_TASK_NOTIFICATIONS 1 807 | #endif 808 | 809 | #ifndef portTICK_TYPE_IS_ATOMIC 810 | #define portTICK_TYPE_IS_ATOMIC 0 811 | #endif 812 | 813 | #ifndef configSUPPORT_STATIC_ALLOCATION 814 | /* Defaults to 0 for backward compatibility. */ 815 | #define configSUPPORT_STATIC_ALLOCATION 0 816 | #endif 817 | 818 | #ifndef configSUPPORT_DYNAMIC_ALLOCATION 819 | /* Defaults to 1 for backward compatibility. */ 820 | #define configSUPPORT_DYNAMIC_ALLOCATION 1 821 | #endif 822 | 823 | #ifndef configSTACK_DEPTH_TYPE 824 | /* Defaults to uint16_t for backward compatibility, but can be overridden 825 | in FreeRTOSConfig.h if uint16_t is too restrictive. */ 826 | #define configSTACK_DEPTH_TYPE uint16_t 827 | #endif 828 | 829 | /* Sanity check the configuration. */ 830 | #if( configUSE_TICKLESS_IDLE != 0 ) 831 | #if( INCLUDE_vTaskSuspend != 1 ) 832 | #error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0 833 | #endif /* INCLUDE_vTaskSuspend */ 834 | #endif /* configUSE_TICKLESS_IDLE */ 835 | 836 | #if( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) ) 837 | #error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1. 838 | #endif 839 | 840 | #if( ( configUSE_RECURSIVE_MUTEXES == 1 ) && ( configUSE_MUTEXES != 1 ) ) 841 | #error configUSE_MUTEXES must be set to 1 to use recursive mutexes 842 | #endif 843 | 844 | #ifndef configINITIAL_TICK_COUNT 845 | #define configINITIAL_TICK_COUNT 0 846 | #endif 847 | 848 | #if( portTICK_TYPE_IS_ATOMIC == 0 ) 849 | /* Either variables of tick type cannot be read atomically, or 850 | portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when 851 | the tick count is returned to the standard critical section macros. */ 852 | #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL() 853 | #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL() 854 | #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() 855 | #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) ) 856 | #else 857 | /* The tick type can be read atomically, so critical sections used when the 858 | tick count is returned can be defined away. */ 859 | #define portTICK_TYPE_ENTER_CRITICAL() 860 | #define portTICK_TYPE_EXIT_CRITICAL() 861 | #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0 862 | #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) x 863 | #endif 864 | 865 | /* Definitions to allow backward compatibility with FreeRTOS versions prior to 866 | V8 if desired. */ 867 | #ifndef configENABLE_BACKWARD_COMPATIBILITY 868 | #define configENABLE_BACKWARD_COMPATIBILITY 1 869 | #endif 870 | 871 | #ifndef configPRINTF 872 | /* configPRINTF() was not defined, so define it away to nothing. To use 873 | configPRINTF() then define it as follows (where MyPrintFunction() is 874 | provided by the application writer): 875 | 876 | void MyPrintFunction(const char *pcFormat, ... ); 877 | #define configPRINTF( X ) MyPrintFunction X 878 | 879 | Then call like a standard printf() function, but placing brackets around 880 | all parameters so they are passed as a single parameter. For example: 881 | configPRINTF( ("Value = %d", MyVariable) ); */ 882 | #define configPRINTF( X ) 883 | #endif 884 | 885 | #ifndef configMAX 886 | /* The application writer has not provided their own MAX macro, so define 887 | the following generic implementation. */ 888 | #define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) 889 | #endif 890 | 891 | #ifndef configMIN 892 | /* The application writer has not provided their own MAX macro, so define 893 | the following generic implementation. */ 894 | #define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) 895 | #endif 896 | 897 | #if configENABLE_BACKWARD_COMPATIBILITY == 1 898 | #define eTaskStateGet eTaskGetState 899 | #define portTickType TickType_t 900 | #define xTaskHandle TaskHandle_t 901 | #define xQueueHandle QueueHandle_t 902 | #define xSemaphoreHandle SemaphoreHandle_t 903 | #define xQueueSetHandle QueueSetHandle_t 904 | #define xQueueSetMemberHandle QueueSetMemberHandle_t 905 | #define xTimeOutType TimeOut_t 906 | #define xMemoryRegion MemoryRegion_t 907 | #define xTaskParameters TaskParameters_t 908 | #define xTaskStatusType TaskStatus_t 909 | #define xTimerHandle TimerHandle_t 910 | #define xCoRoutineHandle CoRoutineHandle_t 911 | #define pdTASK_HOOK_CODE TaskHookFunction_t 912 | #define portTICK_RATE_MS portTICK_PERIOD_MS 913 | #define pcTaskGetTaskName pcTaskGetName 914 | #define pcTimerGetTimerName pcTimerGetName 915 | #define pcQueueGetQueueName pcQueueGetName 916 | #define vTaskGetTaskInfo vTaskGetInfo 917 | 918 | /* Backward compatibility within the scheduler code only - these definitions 919 | are not really required but are included for completeness. */ 920 | #define tmrTIMER_CALLBACK TimerCallbackFunction_t 921 | #define pdTASK_CODE TaskFunction_t 922 | #define xListItem ListItem_t 923 | #define xList List_t 924 | #endif /* configENABLE_BACKWARD_COMPATIBILITY */ 925 | 926 | #if( configUSE_ALTERNATIVE_API != 0 ) 927 | #error The alternative API was deprecated some time ago, and was removed in FreeRTOS V9.0 0 928 | #endif 929 | 930 | /* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even 931 | if floating point hardware is otherwise supported by the FreeRTOS port in use. 932 | This constant is not supported by all FreeRTOS ports that include floating 933 | point support. */ 934 | #ifndef configUSE_TASK_FPU_SUPPORT 935 | #define configUSE_TASK_FPU_SUPPORT 1 936 | #endif 937 | 938 | /* 939 | * In line with software engineering best practice, FreeRTOS implements a strict 940 | * data hiding policy, so the real structures used by FreeRTOS to maintain the 941 | * state of tasks, queues, semaphores, etc. are not accessible to the application 942 | * code. However, if the application writer wants to statically allocate such 943 | * an object then the size of the object needs to be know. Dummy structures 944 | * that are guaranteed to have the same size and alignment requirements of the 945 | * real objects are used for this purpose. The dummy list and list item 946 | * structures below are used for inclusion in such a dummy structure. 947 | */ 948 | struct xSTATIC_LIST_ITEM 949 | { 950 | TickType_t xDummy1; 951 | void *pvDummy2[ 4 ]; 952 | }; 953 | typedef struct xSTATIC_LIST_ITEM StaticListItem_t; 954 | 955 | /* See the comments above the struct xSTATIC_LIST_ITEM definition. */ 956 | struct xSTATIC_MINI_LIST_ITEM 957 | { 958 | TickType_t xDummy1; 959 | void *pvDummy2[ 2 ]; 960 | }; 961 | typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; 962 | 963 | /* See the comments above the struct xSTATIC_LIST_ITEM definition. */ 964 | typedef struct xSTATIC_LIST 965 | { 966 | UBaseType_t uxDummy1; 967 | void *pvDummy2; 968 | StaticMiniListItem_t xDummy3; 969 | } StaticList_t; 970 | 971 | /* 972 | * In line with software engineering best practice, especially when supplying a 973 | * library that is likely to change in future versions, FreeRTOS implements a 974 | * strict data hiding policy. This means the Task structure used internally by 975 | * FreeRTOS is not accessible to application code. However, if the application 976 | * writer wants to statically allocate the memory required to create a task then 977 | * the size of the task object needs to be know. The StaticTask_t structure 978 | * below is provided for this purpose. Its sizes and alignment requirements are 979 | * guaranteed to match those of the genuine structure, no matter which 980 | * architecture is being used, and no matter how the values in FreeRTOSConfig.h 981 | * are set. Its contents are somewhat obfuscated in the hope users will 982 | * recognise that it would be unwise to make direct use of the structure members. 983 | */ 984 | typedef struct xSTATIC_TCB 985 | { 986 | void *pxDummy1; 987 | #if ( portUSING_MPU_WRAPPERS == 1 ) 988 | xMPU_SETTINGS xDummy2; 989 | #endif 990 | StaticListItem_t xDummy3[ 2 ]; 991 | UBaseType_t uxDummy5; 992 | void *pxDummy6; 993 | uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; 994 | #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) 995 | void *pxDummy8; 996 | #endif 997 | #if ( portCRITICAL_NESTING_IN_TCB == 1 ) 998 | UBaseType_t uxDummy9; 999 | #endif 1000 | #if ( configUSE_TRACE_FACILITY == 1 ) 1001 | UBaseType_t uxDummy10[ 2 ]; 1002 | #endif 1003 | #if ( configUSE_MUTEXES == 1 ) 1004 | UBaseType_t uxDummy12[ 2 ]; 1005 | #endif 1006 | #if ( configUSE_APPLICATION_TASK_TAG == 1 ) 1007 | void *pxDummy14; 1008 | #endif 1009 | #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) 1010 | void *pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; 1011 | #endif 1012 | #if ( configGENERATE_RUN_TIME_STATS == 1 ) 1013 | uint32_t ulDummy16; 1014 | #endif 1015 | #if ( configUSE_NEWLIB_REENTRANT == 1 ) 1016 | struct _reent xDummy17; 1017 | #endif 1018 | #if ( configUSE_TASK_NOTIFICATIONS == 1 ) 1019 | uint32_t ulDummy18; 1020 | uint8_t ucDummy19; 1021 | #endif 1022 | #if( ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) || ( portUSING_MPU_WRAPPERS == 1 ) ) 1023 | uint8_t uxDummy20; 1024 | #endif 1025 | 1026 | #if( INCLUDE_xTaskAbortDelay == 1 ) 1027 | uint8_t ucDummy21; 1028 | #endif 1029 | 1030 | } StaticTask_t; 1031 | 1032 | /* 1033 | * In line with software engineering best practice, especially when supplying a 1034 | * library that is likely to change in future versions, FreeRTOS implements a 1035 | * strict data hiding policy. This means the Queue structure used internally by 1036 | * FreeRTOS is not accessible to application code. However, if the application 1037 | * writer wants to statically allocate the memory required to create a queue 1038 | * then the size of the queue object needs to be know. The StaticQueue_t 1039 | * structure below is provided for this purpose. Its sizes and alignment 1040 | * requirements are guaranteed to match those of the genuine structure, no 1041 | * matter which architecture is being used, and no matter how the values in 1042 | * FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in the hope 1043 | * users will recognise that it would be unwise to make direct use of the 1044 | * structure members. 1045 | */ 1046 | typedef struct xSTATIC_QUEUE 1047 | { 1048 | void *pvDummy1[ 3 ]; 1049 | 1050 | union 1051 | { 1052 | void *pvDummy2; 1053 | UBaseType_t uxDummy2; 1054 | } u; 1055 | 1056 | StaticList_t xDummy3[ 2 ]; 1057 | UBaseType_t uxDummy4[ 3 ]; 1058 | uint8_t ucDummy5[ 2 ]; 1059 | 1060 | #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) 1061 | uint8_t ucDummy6; 1062 | #endif 1063 | 1064 | #if ( configUSE_QUEUE_SETS == 1 ) 1065 | void *pvDummy7; 1066 | #endif 1067 | 1068 | #if ( configUSE_TRACE_FACILITY == 1 ) 1069 | UBaseType_t uxDummy8; 1070 | uint8_t ucDummy9; 1071 | #endif 1072 | 1073 | } StaticQueue_t; 1074 | typedef StaticQueue_t StaticSemaphore_t; 1075 | 1076 | /* 1077 | * In line with software engineering best practice, especially when supplying a 1078 | * library that is likely to change in future versions, FreeRTOS implements a 1079 | * strict data hiding policy. This means the event group structure used 1080 | * internally by FreeRTOS is not accessible to application code. However, if 1081 | * the application writer wants to statically allocate the memory required to 1082 | * create an event group then the size of the event group object needs to be 1083 | * know. The StaticEventGroup_t structure below is provided for this purpose. 1084 | * Its sizes and alignment requirements are guaranteed to match those of the 1085 | * genuine structure, no matter which architecture is being used, and no matter 1086 | * how the values in FreeRTOSConfig.h are set. Its contents are somewhat 1087 | * obfuscated in the hope users will recognise that it would be unwise to make 1088 | * direct use of the structure members. 1089 | */ 1090 | typedef struct xSTATIC_EVENT_GROUP 1091 | { 1092 | TickType_t xDummy1; 1093 | StaticList_t xDummy2; 1094 | 1095 | #if( configUSE_TRACE_FACILITY == 1 ) 1096 | UBaseType_t uxDummy3; 1097 | #endif 1098 | 1099 | #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) 1100 | uint8_t ucDummy4; 1101 | #endif 1102 | 1103 | } StaticEventGroup_t; 1104 | 1105 | /* 1106 | * In line with software engineering best practice, especially when supplying a 1107 | * library that is likely to change in future versions, FreeRTOS implements a 1108 | * strict data hiding policy. This means the software timer structure used 1109 | * internally by FreeRTOS is not accessible to application code. However, if 1110 | * the application writer wants to statically allocate the memory required to 1111 | * create a software timer then the size of the queue object needs to be know. 1112 | * The StaticTimer_t structure below is provided for this purpose. Its sizes 1113 | * and alignment requirements are guaranteed to match those of the genuine 1114 | * structure, no matter which architecture is being used, and no matter how the 1115 | * values in FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in 1116 | * the hope users will recognise that it would be unwise to make direct use of 1117 | * the structure members. 1118 | */ 1119 | typedef struct xSTATIC_TIMER 1120 | { 1121 | void *pvDummy1; 1122 | StaticListItem_t xDummy2; 1123 | TickType_t xDummy3; 1124 | UBaseType_t uxDummy4; 1125 | void *pvDummy5[ 2 ]; 1126 | #if( configUSE_TRACE_FACILITY == 1 ) 1127 | UBaseType_t uxDummy6; 1128 | #endif 1129 | 1130 | #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) 1131 | uint8_t ucDummy7; 1132 | #endif 1133 | 1134 | } StaticTimer_t; 1135 | 1136 | /* 1137 | * In line with software engineering best practice, especially when supplying a 1138 | * library that is likely to change in future versions, FreeRTOS implements a 1139 | * strict data hiding policy. This means the stream buffer structure used 1140 | * internally by FreeRTOS is not accessible to application code. However, if 1141 | * the application writer wants to statically allocate the memory required to 1142 | * create a stream buffer then the size of the stream buffer object needs to be 1143 | * know. The StaticStreamBuffer_t structure below is provided for this purpose. 1144 | * Its size and alignment requirements are guaranteed to match those of the 1145 | * genuine structure, no matter which architecture is being used, and no matter 1146 | * how the values in FreeRTOSConfig.h are set. Its contents are somewhat 1147 | * obfuscated in the hope users will recognise that it would be unwise to make 1148 | * direct use of the structure members. 1149 | */ 1150 | typedef struct xSTATIC_STREAM_BUFFER 1151 | { 1152 | size_t uxDummy1[ 4 ]; 1153 | void * pvDummy2[ 3 ]; 1154 | uint8_t ucDummy3; 1155 | #if ( configUSE_TRACE_FACILITY == 1 ) 1156 | UBaseType_t uxDummy4; 1157 | #endif 1158 | } StaticStreamBuffer_t; 1159 | 1160 | /* Message buffers are built on stream buffers. */ 1161 | typedef StaticStreamBuffer_t StaticMessageBuffer_t; 1162 | 1163 | #ifdef __cplusplus 1164 | } 1165 | #endif 1166 | 1167 | #endif /* INC_FREERTOS_H */ 1168 | 1169 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/deprecated_definitions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef DEPRECATED_DEFINITIONS_H 29 | #define DEPRECATED_DEFINITIONS_H 30 | 31 | 32 | /* Each FreeRTOS port has a unique portmacro.h header file. Originally a 33 | pre-processor definition was used to ensure the pre-processor found the correct 34 | portmacro.h file for the port being used. That scheme was deprecated in favour 35 | of setting the compiler's include path such that it found the correct 36 | portmacro.h file - removing the need for the constant and allowing the 37 | portmacro.h file to be located anywhere in relation to the port being used. The 38 | definitions below remain in the code for backward compatibility only. New 39 | projects should not use them. */ 40 | 41 | #ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT 42 | #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" 43 | typedef void ( __interrupt __far *pxISR )(); 44 | #endif 45 | 46 | #ifdef OPEN_WATCOM_FLASH_LITE_186_PORT 47 | #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" 48 | typedef void ( __interrupt __far *pxISR )(); 49 | #endif 50 | 51 | #ifdef GCC_MEGA_AVR 52 | #include "../portable/GCC/ATMega323/portmacro.h" 53 | #endif 54 | 55 | #ifdef IAR_MEGA_AVR 56 | #include "../portable/IAR/ATMega323/portmacro.h" 57 | #endif 58 | 59 | #ifdef MPLAB_PIC24_PORT 60 | #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" 61 | #endif 62 | 63 | #ifdef MPLAB_DSPIC_PORT 64 | #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" 65 | #endif 66 | 67 | #ifdef MPLAB_PIC18F_PORT 68 | #include "../../Source/portable/MPLAB/PIC18F/portmacro.h" 69 | #endif 70 | 71 | #ifdef MPLAB_PIC32MX_PORT 72 | #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" 73 | #endif 74 | 75 | #ifdef _FEDPICC 76 | #include "libFreeRTOS/Include/portmacro.h" 77 | #endif 78 | 79 | #ifdef SDCC_CYGNAL 80 | #include "../../Source/portable/SDCC/Cygnal/portmacro.h" 81 | #endif 82 | 83 | #ifdef GCC_ARM7 84 | #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" 85 | #endif 86 | 87 | #ifdef GCC_ARM7_ECLIPSE 88 | #include "portmacro.h" 89 | #endif 90 | 91 | #ifdef ROWLEY_LPC23xx 92 | #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" 93 | #endif 94 | 95 | #ifdef IAR_MSP430 96 | #include "..\..\Source\portable\IAR\MSP430\portmacro.h" 97 | #endif 98 | 99 | #ifdef GCC_MSP430 100 | #include "../../Source/portable/GCC/MSP430F449/portmacro.h" 101 | #endif 102 | 103 | #ifdef ROWLEY_MSP430 104 | #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" 105 | #endif 106 | 107 | #ifdef ARM7_LPC21xx_KEIL_RVDS 108 | #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" 109 | #endif 110 | 111 | #ifdef SAM7_GCC 112 | #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" 113 | #endif 114 | 115 | #ifdef SAM7_IAR 116 | #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" 117 | #endif 118 | 119 | #ifdef SAM9XE_IAR 120 | #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" 121 | #endif 122 | 123 | #ifdef LPC2000_IAR 124 | #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" 125 | #endif 126 | 127 | #ifdef STR71X_IAR 128 | #include "..\..\Source\portable\IAR\STR71x\portmacro.h" 129 | #endif 130 | 131 | #ifdef STR75X_IAR 132 | #include "..\..\Source\portable\IAR\STR75x\portmacro.h" 133 | #endif 134 | 135 | #ifdef STR75X_GCC 136 | #include "..\..\Source\portable\GCC\STR75x\portmacro.h" 137 | #endif 138 | 139 | #ifdef STR91X_IAR 140 | #include "..\..\Source\portable\IAR\STR91x\portmacro.h" 141 | #endif 142 | 143 | #ifdef GCC_H8S 144 | #include "../../Source/portable/GCC/H8S2329/portmacro.h" 145 | #endif 146 | 147 | #ifdef GCC_AT91FR40008 148 | #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" 149 | #endif 150 | 151 | #ifdef RVDS_ARMCM3_LM3S102 152 | #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" 153 | #endif 154 | 155 | #ifdef GCC_ARMCM3_LM3S102 156 | #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" 157 | #endif 158 | 159 | #ifdef GCC_ARMCM3 160 | #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" 161 | #endif 162 | 163 | #ifdef IAR_ARM_CM3 164 | #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" 165 | #endif 166 | 167 | #ifdef IAR_ARMCM3_LM 168 | #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" 169 | #endif 170 | 171 | #ifdef HCS12_CODE_WARRIOR 172 | #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" 173 | #endif 174 | 175 | #ifdef MICROBLAZE_GCC 176 | #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" 177 | #endif 178 | 179 | #ifdef TERN_EE 180 | #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" 181 | #endif 182 | 183 | #ifdef GCC_HCS12 184 | #include "../../Source/portable/GCC/HCS12/portmacro.h" 185 | #endif 186 | 187 | #ifdef GCC_MCF5235 188 | #include "../../Source/portable/GCC/MCF5235/portmacro.h" 189 | #endif 190 | 191 | #ifdef COLDFIRE_V2_GCC 192 | #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" 193 | #endif 194 | 195 | #ifdef COLDFIRE_V2_CODEWARRIOR 196 | #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" 197 | #endif 198 | 199 | #ifdef GCC_PPC405 200 | #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" 201 | #endif 202 | 203 | #ifdef GCC_PPC440 204 | #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" 205 | #endif 206 | 207 | #ifdef _16FX_SOFTUNE 208 | #include "..\..\Source\portable\Softune\MB96340\portmacro.h" 209 | #endif 210 | 211 | #ifdef BCC_INDUSTRIAL_PC_PORT 212 | /* A short file name has to be used in place of the normal 213 | FreeRTOSConfig.h when using the Borland compiler. */ 214 | #include "frconfig.h" 215 | #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" 216 | typedef void ( __interrupt __far *pxISR )(); 217 | #endif 218 | 219 | #ifdef BCC_FLASH_LITE_186_PORT 220 | /* A short file name has to be used in place of the normal 221 | FreeRTOSConfig.h when using the Borland compiler. */ 222 | #include "frconfig.h" 223 | #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" 224 | typedef void ( __interrupt __far *pxISR )(); 225 | #endif 226 | 227 | #ifdef __GNUC__ 228 | #ifdef __AVR32_AVR32A__ 229 | #include "portmacro.h" 230 | #endif 231 | #endif 232 | 233 | #ifdef __ICCAVR32__ 234 | #ifdef __CORE__ 235 | #if __CORE__ == __AVR32A__ 236 | #include "portmacro.h" 237 | #endif 238 | #endif 239 | #endif 240 | 241 | #ifdef __91467D 242 | #include "portmacro.h" 243 | #endif 244 | 245 | #ifdef __96340 246 | #include "portmacro.h" 247 | #endif 248 | 249 | 250 | #ifdef __IAR_V850ES_Fx3__ 251 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 252 | #endif 253 | 254 | #ifdef __IAR_V850ES_Jx3__ 255 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 256 | #endif 257 | 258 | #ifdef __IAR_V850ES_Jx3_L__ 259 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 260 | #endif 261 | 262 | #ifdef __IAR_V850ES_Jx2__ 263 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 264 | #endif 265 | 266 | #ifdef __IAR_V850ES_Hx2__ 267 | #include "../../Source/portable/IAR/V850ES/portmacro.h" 268 | #endif 269 | 270 | #ifdef __IAR_78K0R_Kx3__ 271 | #include "../../Source/portable/IAR/78K0R/portmacro.h" 272 | #endif 273 | 274 | #ifdef __IAR_78K0R_Kx3L__ 275 | #include "../../Source/portable/IAR/78K0R/portmacro.h" 276 | #endif 277 | 278 | #endif /* DEPRECATED_DEFINITIONS_H */ 279 | 280 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /* 29 | * This is the list implementation used by the scheduler. While it is tailored 30 | * heavily for the schedulers needs, it is also available for use by 31 | * application code. 32 | * 33 | * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a 34 | * numeric value (xItemValue). Most of the time the lists are sorted in 35 | * descending item value order. 36 | * 37 | * Lists are created already containing one list item. The value of this 38 | * item is the maximum possible that can be stored, it is therefore always at 39 | * the end of the list and acts as a marker. The list member pxHead always 40 | * points to this marker - even though it is at the tail of the list. This 41 | * is because the tail contains a wrap back pointer to the true head of 42 | * the list. 43 | * 44 | * In addition to it's value, each list item contains a pointer to the next 45 | * item in the list (pxNext), a pointer to the list it is in (pxContainer) 46 | * and a pointer to back to the object that contains it. These later two 47 | * pointers are included for efficiency of list manipulation. There is 48 | * effectively a two way link between the object containing the list item and 49 | * the list item itself. 50 | * 51 | * 52 | * \page ListIntroduction List Implementation 53 | * \ingroup FreeRTOSIntro 54 | */ 55 | 56 | #ifndef INC_FREERTOS_H 57 | #error FreeRTOS.h must be included before list.h 58 | #endif 59 | 60 | #ifndef LIST_H 61 | #define LIST_H 62 | 63 | /* 64 | * The list structure members are modified from within interrupts, and therefore 65 | * by rights should be declared volatile. However, they are only modified in a 66 | * functionally atomic way (within critical sections of with the scheduler 67 | * suspended) and are either passed by reference into a function or indexed via 68 | * a volatile variable. Therefore, in all use cases tested so far, the volatile 69 | * qualifier can be omitted in order to provide a moderate performance 70 | * improvement without adversely affecting functional behaviour. The assembly 71 | * instructions generated by the IAR, ARM and GCC compilers when the respective 72 | * compiler's options were set for maximum optimisation has been inspected and 73 | * deemed to be as intended. That said, as compiler technology advances, and 74 | * especially if aggressive cross module optimisation is used (a use case that 75 | * has not been exercised to any great extend) then it is feasible that the 76 | * volatile qualifier will be needed for correct optimisation. It is expected 77 | * that a compiler removing essential code because, without the volatile 78 | * qualifier on the list structure members and with aggressive cross module 79 | * optimisation, the compiler deemed the code unnecessary will result in 80 | * complete and obvious failure of the scheduler. If this is ever experienced 81 | * then the volatile qualifier can be inserted in the relevant places within the 82 | * list structures by simply defining configLIST_VOLATILE to volatile in 83 | * FreeRTOSConfig.h (as per the example at the bottom of this comment block). 84 | * If configLIST_VOLATILE is not defined then the preprocessor directives below 85 | * will simply #define configLIST_VOLATILE away completely. 86 | * 87 | * To use volatile list structure members then add the following line to 88 | * FreeRTOSConfig.h (without the quotes): 89 | * "#define configLIST_VOLATILE volatile" 90 | */ 91 | #ifndef configLIST_VOLATILE 92 | #define configLIST_VOLATILE 93 | #endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ 94 | 95 | #ifdef __cplusplus 96 | extern "C" { 97 | #endif 98 | 99 | /* Macros that can be used to place known values within the list structures, 100 | then check that the known values do not get corrupted during the execution of 101 | the application. These may catch the list data structures being overwritten in 102 | memory. They will not catch data errors caused by incorrect configuration or 103 | use of FreeRTOS.*/ 104 | #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) 105 | /* Define the macros to do nothing. */ 106 | #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE 107 | #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE 108 | #define listFIRST_LIST_INTEGRITY_CHECK_VALUE 109 | #define listSECOND_LIST_INTEGRITY_CHECK_VALUE 110 | #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) 111 | #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) 112 | #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) 113 | #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) 114 | #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) 115 | #define listTEST_LIST_INTEGRITY( pxList ) 116 | #else 117 | /* Define macros that add new members into the list structures. */ 118 | #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; 119 | #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; 120 | #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1; 121 | #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2; 122 | 123 | /* Define macros that set the new structure members to known values. */ 124 | #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE 125 | #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE 126 | #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE 127 | #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE 128 | 129 | /* Define macros that will assert if one of the structure members does not 130 | contain its expected value. */ 131 | #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) 132 | #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) 133 | #endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ 134 | 135 | 136 | /* 137 | * Definition of the only type of object that a list can contain. 138 | */ 139 | struct xLIST_ITEM 140 | { 141 | listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 142 | configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ 143 | struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ 144 | struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ 145 | void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ 146 | void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */ 147 | listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 148 | }; 149 | typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ 150 | 151 | struct xMINI_LIST_ITEM 152 | { 153 | listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 154 | configLIST_VOLATILE TickType_t xItemValue; 155 | struct xLIST_ITEM * configLIST_VOLATILE pxNext; 156 | struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; 157 | }; 158 | typedef struct xMINI_LIST_ITEM MiniListItem_t; 159 | 160 | /* 161 | * Definition of the type of queue used by the scheduler. 162 | */ 163 | typedef struct xLIST 164 | { 165 | listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 166 | volatile UBaseType_t uxNumberOfItems; 167 | ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ 168 | MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ 169 | listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 170 | } List_t; 171 | 172 | /* 173 | * Access macro to set the owner of a list item. The owner of a list item 174 | * is the object (usually a TCB) that contains the list item. 175 | * 176 | * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER 177 | * \ingroup LinkedList 178 | */ 179 | #define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) 180 | 181 | /* 182 | * Access macro to get the owner of a list item. The owner of a list item 183 | * is the object (usually a TCB) that contains the list item. 184 | * 185 | * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER 186 | * \ingroup LinkedList 187 | */ 188 | #define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner ) 189 | 190 | /* 191 | * Access macro to set the value of the list item. In most cases the value is 192 | * used to sort the list in descending order. 193 | * 194 | * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE 195 | * \ingroup LinkedList 196 | */ 197 | #define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) 198 | 199 | /* 200 | * Access macro to retrieve the value of the list item. The value can 201 | * represent anything - for example the priority of a task, or the time at 202 | * which a task should be unblocked. 203 | * 204 | * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE 205 | * \ingroup LinkedList 206 | */ 207 | #define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) 208 | 209 | /* 210 | * Access macro to retrieve the value of the list item at the head of a given 211 | * list. 212 | * 213 | * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE 214 | * \ingroup LinkedList 215 | */ 216 | #define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) 217 | 218 | /* 219 | * Return the list item at the head of the list. 220 | * 221 | * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY 222 | * \ingroup LinkedList 223 | */ 224 | #define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext ) 225 | 226 | /* 227 | * Return the list item at the head of the list. 228 | * 229 | * \page listGET_NEXT listGET_NEXT 230 | * \ingroup LinkedList 231 | */ 232 | #define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext ) 233 | 234 | /* 235 | * Return the list item that marks the end of the list 236 | * 237 | * \page listGET_END_MARKER listGET_END_MARKER 238 | * \ingroup LinkedList 239 | */ 240 | #define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) 241 | 242 | /* 243 | * Access macro to determine if a list contains any items. The macro will 244 | * only have the value true if the list is empty. 245 | * 246 | * \page listLIST_IS_EMPTY listLIST_IS_EMPTY 247 | * \ingroup LinkedList 248 | */ 249 | #define listLIST_IS_EMPTY( pxList ) ( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ) 250 | 251 | /* 252 | * Access macro to return the number of items in the list. 253 | */ 254 | #define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) 255 | 256 | /* 257 | * Access function to obtain the owner of the next entry in a list. 258 | * 259 | * The list member pxIndex is used to walk through a list. Calling 260 | * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list 261 | * and returns that entry's pxOwner parameter. Using multiple calls to this 262 | * function it is therefore possible to move through every item contained in 263 | * a list. 264 | * 265 | * The pxOwner parameter of a list item is a pointer to the object that owns 266 | * the list item. In the scheduler this is normally a task control block. 267 | * The pxOwner parameter effectively creates a two way link between the list 268 | * item and its owner. 269 | * 270 | * @param pxTCB pxTCB is set to the address of the owner of the next list item. 271 | * @param pxList The list from which the next item owner is to be returned. 272 | * 273 | * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY 274 | * \ingroup LinkedList 275 | */ 276 | #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ 277 | { \ 278 | List_t * const pxConstList = ( pxList ); \ 279 | /* Increment the index to the next item and return the item, ensuring */ \ 280 | /* we don't return the marker used at the end of the list. */ \ 281 | ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ 282 | if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ 283 | { \ 284 | ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ 285 | } \ 286 | ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ 287 | } 288 | 289 | 290 | /* 291 | * Access function to obtain the owner of the first entry in a list. Lists 292 | * are normally sorted in ascending item value order. 293 | * 294 | * This function returns the pxOwner member of the first item in the list. 295 | * The pxOwner parameter of a list item is a pointer to the object that owns 296 | * the list item. In the scheduler this is normally a task control block. 297 | * The pxOwner parameter effectively creates a two way link between the list 298 | * item and its owner. 299 | * 300 | * @param pxList The list from which the owner of the head item is to be 301 | * returned. 302 | * 303 | * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY 304 | * \ingroup LinkedList 305 | */ 306 | #define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) 307 | 308 | /* 309 | * Check to see if a list item is within a list. The list item maintains a 310 | * "container" pointer that points to the list it is in. All this macro does 311 | * is check to see if the container and the list match. 312 | * 313 | * @param pxList The list we want to know if the list item is within. 314 | * @param pxListItem The list item we want to know if is in the list. 315 | * @return pdTRUE if the list item is in the list, otherwise pdFALSE. 316 | */ 317 | #define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( BaseType_t ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) ) 318 | 319 | /* 320 | * Return the list a list item is contained within (referenced from). 321 | * 322 | * @param pxListItem The list item being queried. 323 | * @return A pointer to the List_t object that references the pxListItem 324 | */ 325 | #define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer ) 326 | 327 | /* 328 | * This provides a crude means of knowing if a list has been initialised, as 329 | * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() 330 | * function. 331 | */ 332 | #define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) 333 | 334 | /* 335 | * Must be called before a list is used! This initialises all the members 336 | * of the list structure and inserts the xListEnd item into the list as a 337 | * marker to the back of the list. 338 | * 339 | * @param pxList Pointer to the list being initialised. 340 | * 341 | * \page vListInitialise vListInitialise 342 | * \ingroup LinkedList 343 | */ 344 | void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION; 345 | 346 | /* 347 | * Must be called before a list item is used. This sets the list container to 348 | * null so the item does not think that it is already contained in a list. 349 | * 350 | * @param pxItem Pointer to the list item being initialised. 351 | * 352 | * \page vListInitialiseItem vListInitialiseItem 353 | * \ingroup LinkedList 354 | */ 355 | void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION; 356 | 357 | /* 358 | * Insert a list item into a list. The item will be inserted into the list in 359 | * a position determined by its item value (descending item value order). 360 | * 361 | * @param pxList The list into which the item is to be inserted. 362 | * 363 | * @param pxNewListItem The item that is to be placed in the list. 364 | * 365 | * \page vListInsert vListInsert 366 | * \ingroup LinkedList 367 | */ 368 | void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; 369 | 370 | /* 371 | * Insert a list item into a list. The item will be inserted in a position 372 | * such that it will be the last item within the list returned by multiple 373 | * calls to listGET_OWNER_OF_NEXT_ENTRY. 374 | * 375 | * The list member pxIndex is used to walk through a list. Calling 376 | * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. 377 | * Placing an item in a list using vListInsertEnd effectively places the item 378 | * in the list position pointed to by pxIndex. This means that every other 379 | * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before 380 | * the pxIndex parameter again points to the item being inserted. 381 | * 382 | * @param pxList The list into which the item is to be inserted. 383 | * 384 | * @param pxNewListItem The list item to be inserted into the list. 385 | * 386 | * \page vListInsertEnd vListInsertEnd 387 | * \ingroup LinkedList 388 | */ 389 | void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; 390 | 391 | /* 392 | * Remove an item from a list. The list item has a pointer to the list that 393 | * it is in, so only the list item need be passed into the function. 394 | * 395 | * @param uxListRemove The item to be removed. The item will remove itself from 396 | * the list pointed to by it's pxContainer parameter. 397 | * 398 | * @return The number of items that remain in the list after the list item has 399 | * been removed. 400 | * 401 | * \page uxListRemove uxListRemove 402 | * \ingroup LinkedList 403 | */ 404 | UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION; 405 | 406 | #ifdef __cplusplus 407 | } 408 | #endif 409 | 410 | #endif 411 | 412 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/mpu_wrappers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef MPU_WRAPPERS_H 29 | #define MPU_WRAPPERS_H 30 | 31 | /* This file redefines API functions to be called through a wrapper macro, but 32 | only for ports that are using the MPU. */ 33 | #ifdef portUSING_MPU_WRAPPERS 34 | 35 | /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is 36 | included from queue.c or task.c to prevent it from having an effect within 37 | those files. */ 38 | #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 39 | 40 | /* 41 | * Map standard (non MPU) API functions to equivalents that start 42 | * "MPU_". This will cause the application code to call the MPU_ 43 | * version, which wraps the non-MPU version with privilege promoting 44 | * then demoting code, so the kernel code always runs will full 45 | * privileges. 46 | */ 47 | 48 | /* Map standard tasks.h API functions to the MPU equivalents. */ 49 | #define xTaskCreate MPU_xTaskCreate 50 | #define xTaskCreateStatic MPU_xTaskCreateStatic 51 | #define xTaskCreateRestricted MPU_xTaskCreateRestricted 52 | #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions 53 | #define vTaskDelete MPU_vTaskDelete 54 | #define vTaskDelay MPU_vTaskDelay 55 | #define vTaskDelayUntil MPU_vTaskDelayUntil 56 | #define xTaskAbortDelay MPU_xTaskAbortDelay 57 | #define uxTaskPriorityGet MPU_uxTaskPriorityGet 58 | #define eTaskGetState MPU_eTaskGetState 59 | #define vTaskGetInfo MPU_vTaskGetInfo 60 | #define vTaskPrioritySet MPU_vTaskPrioritySet 61 | #define vTaskSuspend MPU_vTaskSuspend 62 | #define vTaskResume MPU_vTaskResume 63 | #define vTaskSuspendAll MPU_vTaskSuspendAll 64 | #define xTaskResumeAll MPU_xTaskResumeAll 65 | #define xTaskGetTickCount MPU_xTaskGetTickCount 66 | #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks 67 | #define pcTaskGetName MPU_pcTaskGetName 68 | #define xTaskGetHandle MPU_xTaskGetHandle 69 | #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark 70 | #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag 71 | #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag 72 | #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer 73 | #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer 74 | #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook 75 | #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle 76 | #define uxTaskGetSystemState MPU_uxTaskGetSystemState 77 | #define vTaskList MPU_vTaskList 78 | #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats 79 | #define xTaskGenericNotify MPU_xTaskGenericNotify 80 | #define xTaskNotifyWait MPU_xTaskNotifyWait 81 | #define ulTaskNotifyTake MPU_ulTaskNotifyTake 82 | #define xTaskNotifyStateClear MPU_xTaskNotifyStateClear 83 | 84 | #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle 85 | #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState 86 | #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut 87 | #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState 88 | 89 | /* Map standard queue.h API functions to the MPU equivalents. */ 90 | #define xQueueGenericSend MPU_xQueueGenericSend 91 | #define xQueueReceive MPU_xQueueReceive 92 | #define xQueuePeek MPU_xQueuePeek 93 | #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake 94 | #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting 95 | #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable 96 | #define vQueueDelete MPU_vQueueDelete 97 | #define xQueueCreateMutex MPU_xQueueCreateMutex 98 | #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic 99 | #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore 100 | #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic 101 | #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder 102 | #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive 103 | #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive 104 | #define xQueueGenericCreate MPU_xQueueGenericCreate 105 | #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic 106 | #define xQueueCreateSet MPU_xQueueCreateSet 107 | #define xQueueAddToSet MPU_xQueueAddToSet 108 | #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet 109 | #define xQueueSelectFromSet MPU_xQueueSelectFromSet 110 | #define xQueueGenericReset MPU_xQueueGenericReset 111 | 112 | #if( configQUEUE_REGISTRY_SIZE > 0 ) 113 | #define vQueueAddToRegistry MPU_vQueueAddToRegistry 114 | #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue 115 | #define pcQueueGetName MPU_pcQueueGetName 116 | #endif 117 | 118 | /* Map standard timer.h API functions to the MPU equivalents. */ 119 | #define xTimerCreate MPU_xTimerCreate 120 | #define xTimerCreateStatic MPU_xTimerCreateStatic 121 | #define pvTimerGetTimerID MPU_pvTimerGetTimerID 122 | #define vTimerSetTimerID MPU_vTimerSetTimerID 123 | #define xTimerIsTimerActive MPU_xTimerIsTimerActive 124 | #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle 125 | #define xTimerPendFunctionCall MPU_xTimerPendFunctionCall 126 | #define pcTimerGetName MPU_pcTimerGetName 127 | #define xTimerGetPeriod MPU_xTimerGetPeriod 128 | #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime 129 | #define xTimerGenericCommand MPU_xTimerGenericCommand 130 | 131 | /* Map standard event_group.h API functions to the MPU equivalents. */ 132 | #define xEventGroupCreate MPU_xEventGroupCreate 133 | #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic 134 | #define xEventGroupWaitBits MPU_xEventGroupWaitBits 135 | #define xEventGroupClearBits MPU_xEventGroupClearBits 136 | #define xEventGroupSetBits MPU_xEventGroupSetBits 137 | #define xEventGroupSync MPU_xEventGroupSync 138 | #define vEventGroupDelete MPU_vEventGroupDelete 139 | 140 | /* Map standard message/stream_buffer.h API functions to the MPU 141 | equivalents. */ 142 | #define xStreamBufferSend MPU_xStreamBufferSend 143 | #define xStreamBufferSendFromISR MPU_xStreamBufferSendFromISR 144 | #define xStreamBufferReceive MPU_xStreamBufferReceive 145 | #define xStreamBufferReceiveFromISR MPU_xStreamBufferReceiveFromISR 146 | #define vStreamBufferDelete MPU_vStreamBufferDelete 147 | #define xStreamBufferIsFull MPU_xStreamBufferIsFull 148 | #define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty 149 | #define xStreamBufferReset MPU_xStreamBufferReset 150 | #define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable 151 | #define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable 152 | #define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel 153 | #define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate 154 | #define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic 155 | 156 | 157 | /* Remove the privileged function macro, but keep the PRIVILEGED_DATA 158 | macro so applications can place data in privileged access sections 159 | (useful when using statically allocated objects). */ 160 | #define PRIVILEGED_FUNCTION 161 | #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) 162 | 163 | #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ 164 | 165 | /* Ensure API functions go in the privileged execution section. */ 166 | #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) 167 | #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) 168 | 169 | #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ 170 | 171 | #else /* portUSING_MPU_WRAPPERS */ 172 | 173 | #define PRIVILEGED_FUNCTION 174 | #define PRIVILEGED_DATA 175 | #define portUSING_MPU_WRAPPERS 0 176 | 177 | #endif /* portUSING_MPU_WRAPPERS */ 178 | 179 | 180 | #endif /* MPU_WRAPPERS_H */ 181 | 182 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/portable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /*----------------------------------------------------------- 29 | * Portable layer API. Each function must be defined for each port. 30 | *----------------------------------------------------------*/ 31 | 32 | #ifndef PORTABLE_H 33 | #define PORTABLE_H 34 | 35 | /* Each FreeRTOS port has a unique portmacro.h header file. Originally a 36 | pre-processor definition was used to ensure the pre-processor found the correct 37 | portmacro.h file for the port being used. That scheme was deprecated in favour 38 | of setting the compiler's include path such that it found the correct 39 | portmacro.h file - removing the need for the constant and allowing the 40 | portmacro.h file to be located anywhere in relation to the port being used. 41 | Purely for reasons of backward compatibility the old method is still valid, but 42 | to make it clear that new projects should not use it, support for the port 43 | specific constants has been moved into the deprecated_definitions.h header 44 | file. */ 45 | #include "deprecated_definitions.h" 46 | 47 | /* If portENTER_CRITICAL is not defined then including deprecated_definitions.h 48 | did not result in a portmacro.h header file being included - and it should be 49 | included here. In this case the path to the correct portmacro.h header file 50 | must be set in the compiler's include path. */ 51 | #ifndef portENTER_CRITICAL 52 | #include "portmacro.h" 53 | #endif 54 | 55 | #if portBYTE_ALIGNMENT == 32 56 | #define portBYTE_ALIGNMENT_MASK ( 0x001f ) 57 | #endif 58 | 59 | #if portBYTE_ALIGNMENT == 16 60 | #define portBYTE_ALIGNMENT_MASK ( 0x000f ) 61 | #endif 62 | 63 | #if portBYTE_ALIGNMENT == 8 64 | #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) 65 | #endif 66 | 67 | #if portBYTE_ALIGNMENT == 4 68 | #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) 69 | #endif 70 | 71 | #if portBYTE_ALIGNMENT == 2 72 | #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) 73 | #endif 74 | 75 | #if portBYTE_ALIGNMENT == 1 76 | #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) 77 | #endif 78 | 79 | #ifndef portBYTE_ALIGNMENT_MASK 80 | #error "Invalid portBYTE_ALIGNMENT definition" 81 | #endif 82 | 83 | #ifndef portNUM_CONFIGURABLE_REGIONS 84 | #define portNUM_CONFIGURABLE_REGIONS 1 85 | #endif 86 | 87 | #ifdef __cplusplus 88 | extern "C" { 89 | #endif 90 | 91 | #include "mpu_wrappers.h" 92 | 93 | /* 94 | * Setup the stack of a new task so it is ready to be placed under the 95 | * scheduler control. The registers have to be placed on the stack in 96 | * the order that the port expects to find them. 97 | * 98 | */ 99 | #if( portUSING_MPU_WRAPPERS == 1 ) 100 | StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; 101 | #else 102 | StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; 103 | #endif 104 | 105 | /* Used by heap_5.c. */ 106 | typedef struct HeapRegion 107 | { 108 | uint8_t *pucStartAddress; 109 | size_t xSizeInBytes; 110 | } HeapRegion_t; 111 | 112 | /* 113 | * Used to define multiple heap regions for use by heap_5.c. This function 114 | * must be called before any calls to pvPortMalloc() - not creating a task, 115 | * queue, semaphore, mutex, software timer, event group, etc. will result in 116 | * pvPortMalloc being called. 117 | * 118 | * pxHeapRegions passes in an array of HeapRegion_t structures - each of which 119 | * defines a region of memory that can be used as the heap. The array is 120 | * terminated by a HeapRegions_t structure that has a size of 0. The region 121 | * with the lowest start address must appear first in the array. 122 | */ 123 | void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION; 124 | 125 | 126 | /* 127 | * Map to the memory management routines required for the port. 128 | */ 129 | void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; 130 | void vPortFree( void *pv ) PRIVILEGED_FUNCTION; 131 | void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; 132 | size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; 133 | size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; 134 | 135 | /* 136 | * Setup the hardware ready for the scheduler to take control. This generally 137 | * sets up a tick interrupt and sets timers for the correct tick frequency. 138 | */ 139 | BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; 140 | 141 | /* 142 | * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so 143 | * the hardware is left in its original condition after the scheduler stops 144 | * executing. 145 | */ 146 | void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; 147 | 148 | /* 149 | * The structures and methods of manipulating the MPU are contained within the 150 | * port layer. 151 | * 152 | * Fills the xMPUSettings structure with the memory region information 153 | * contained in xRegions. 154 | */ 155 | #if( portUSING_MPU_WRAPPERS == 1 ) 156 | struct xMEMORY_REGION; 157 | void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; 158 | #endif 159 | 160 | #ifdef __cplusplus 161 | } 162 | #endif 163 | 164 | #endif /* PORTABLE_H */ 165 | 166 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/projdefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef PROJDEFS_H 29 | #define PROJDEFS_H 30 | 31 | /* 32 | * Defines the prototype to which task functions must conform. Defined in this 33 | * file to ensure the type is known before portable.h is included. 34 | */ 35 | typedef void (*TaskFunction_t)( void * ); 36 | 37 | /* Converts a time in milliseconds to a time in ticks. This macro can be 38 | overridden by a macro of the same name defined in FreeRTOSConfig.h in case the 39 | definition here is not suitable for your application. */ 40 | #ifndef pdMS_TO_TICKS 41 | #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) 42 | #endif 43 | 44 | #define pdFALSE ( ( BaseType_t ) 0 ) 45 | #define pdTRUE ( ( BaseType_t ) 1 ) 46 | 47 | #define pdPASS ( pdTRUE ) 48 | #define pdFAIL ( pdFALSE ) 49 | #define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) 50 | #define errQUEUE_FULL ( ( BaseType_t ) 0 ) 51 | 52 | /* FreeRTOS error definitions. */ 53 | #define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) 54 | #define errQUEUE_BLOCKED ( -4 ) 55 | #define errQUEUE_YIELD ( -5 ) 56 | 57 | /* Macros used for basic data corruption checks. */ 58 | #ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 59 | #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 60 | #endif 61 | 62 | #if( configUSE_16_BIT_TICKS == 1 ) 63 | #define pdINTEGRITY_CHECK_VALUE 0x5a5a 64 | #else 65 | #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL 66 | #endif 67 | 68 | /* The following errno values are used by FreeRTOS+ components, not FreeRTOS 69 | itself. */ 70 | #define pdFREERTOS_ERRNO_NONE 0 /* No errors */ 71 | #define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ 72 | #define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ 73 | #define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ 74 | #define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ 75 | #define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ 76 | #define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ 77 | #define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ 78 | #define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ 79 | #define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ 80 | #define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ 81 | #define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ 82 | #define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ 83 | #define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ 84 | #define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ 85 | #define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ 86 | #define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ 87 | #define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ 88 | #define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ 89 | #define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ 90 | #define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ 91 | #define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ 92 | #define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ 93 | #define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ 94 | #define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ 95 | #define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ 96 | #define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ 97 | #define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ 98 | #define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ 99 | #define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ 100 | #define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ 101 | #define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ 102 | #define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ 103 | #define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ 104 | #define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ 105 | #define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ 106 | #define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ 107 | #define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ 108 | #define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ 109 | #define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ 110 | 111 | /* The following endian values are used by FreeRTOS+ components, not FreeRTOS 112 | itself. */ 113 | #define pdFREERTOS_LITTLE_ENDIAN 0 114 | #define pdFREERTOS_BIG_ENDIAN 1 115 | 116 | /* Re-defining endian values for generic naming. */ 117 | #define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN 118 | #define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN 119 | 120 | 121 | #endif /* PROJDEFS_H */ 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /FreeRTOS/Source/include/stack_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef STACK_MACROS_H 29 | #define STACK_MACROS_H 30 | 31 | /* 32 | * Call the stack overflow hook function if the stack of the task being swapped 33 | * out is currently overflowed, or looks like it might have overflowed in the 34 | * past. 35 | * 36 | * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check 37 | * the current stack state only - comparing the current top of stack value to 38 | * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 39 | * will also cause the last few stack bytes to be checked to ensure the value 40 | * to which the bytes were set when the task was created have not been 41 | * overwritten. Note this second test does not guarantee that an overflowed 42 | * stack will always be recognised. 43 | */ 44 | 45 | /*-----------------------------------------------------------*/ 46 | 47 | #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) 48 | 49 | /* Only the current stack state is to be checked. */ 50 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 51 | { \ 52 | /* Is the currently saved stack pointer within the stack limit? */ \ 53 | if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ 54 | { \ 55 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 56 | } \ 57 | } 58 | 59 | #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ 60 | /*-----------------------------------------------------------*/ 61 | 62 | #if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) 63 | 64 | /* Only the current stack state is to be checked. */ 65 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 66 | { \ 67 | \ 68 | /* Is the currently saved stack pointer within the stack limit? */ \ 69 | if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ 70 | { \ 71 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 72 | } \ 73 | } 74 | 75 | #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ 76 | /*-----------------------------------------------------------*/ 77 | 78 | #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) 79 | 80 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 81 | { \ 82 | const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ 83 | const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ 84 | \ 85 | if( ( pulStack[ 0 ] != ulCheckValue ) || \ 86 | ( pulStack[ 1 ] != ulCheckValue ) || \ 87 | ( pulStack[ 2 ] != ulCheckValue ) || \ 88 | ( pulStack[ 3 ] != ulCheckValue ) ) \ 89 | { \ 90 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 91 | } \ 92 | } 93 | 94 | #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 95 | /*-----------------------------------------------------------*/ 96 | 97 | #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) 98 | 99 | #define taskCHECK_FOR_STACK_OVERFLOW() \ 100 | { \ 101 | int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ 102 | static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 103 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 104 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 105 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 106 | tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ 107 | \ 108 | \ 109 | pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ 110 | \ 111 | /* Has the extremity of the task stack ever been written over? */ \ 112 | if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ 113 | { \ 114 | vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ 115 | } \ 116 | } 117 | 118 | #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ 119 | /*-----------------------------------------------------------*/ 120 | 121 | /* Remove stack overflow macro if not being used. */ 122 | #ifndef taskCHECK_FOR_STACK_OVERFLOW 123 | #define taskCHECK_FOR_STACK_OVERFLOW() 124 | #endif 125 | 126 | 127 | 128 | #endif /* STACK_MACROS_H */ 129 | 130 | -------------------------------------------------------------------------------- /FreeRTOS/Source/list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | 29 | #include 30 | #include "FreeRTOS.h" 31 | #include "list.h" 32 | 33 | /*----------------------------------------------------------- 34 | * PUBLIC LIST API documented in list.h 35 | *----------------------------------------------------------*/ 36 | 37 | void vListInitialise( List_t * const pxList ) 38 | { 39 | /* The list structure contains a list item which is used to mark the 40 | end of the list. To initialise the list the list end is inserted 41 | as the only list entry. */ 42 | pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 43 | 44 | /* The list end value is the highest possible value in the list to 45 | ensure it remains at the end of the list. */ 46 | pxList->xListEnd.xItemValue = portMAX_DELAY; 47 | 48 | /* The list end next and previous pointers point to itself so we know 49 | when the list is empty. */ 50 | pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 51 | pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 52 | 53 | pxList->uxNumberOfItems = ( UBaseType_t ) 0U; 54 | 55 | /* Write known values into the list if 56 | configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 57 | listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); 58 | listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); 59 | } 60 | /*-----------------------------------------------------------*/ 61 | 62 | void vListInitialiseItem( ListItem_t * const pxItem ) 63 | { 64 | /* Make sure the list item is not recorded as being on a list. */ 65 | pxItem->pvContainer = NULL; 66 | 67 | /* Write known values into the list item if 68 | configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ 69 | listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); 70 | listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); 71 | } 72 | /*-----------------------------------------------------------*/ 73 | 74 | void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) 75 | { 76 | ListItem_t * const pxIndex = pxList->pxIndex; 77 | 78 | /* Only effective when configASSERT() is also defined, these tests may catch 79 | the list data structures being overwritten in memory. They will not catch 80 | data errors caused by incorrect configuration or use of FreeRTOS. */ 81 | listTEST_LIST_INTEGRITY( pxList ); 82 | listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); 83 | 84 | /* Insert a new list item into pxList, but rather than sort the list, 85 | makes the new list item the last item to be removed by a call to 86 | listGET_OWNER_OF_NEXT_ENTRY(). */ 87 | pxNewListItem->pxNext = pxIndex; 88 | pxNewListItem->pxPrevious = pxIndex->pxPrevious; 89 | 90 | /* Only used during decision coverage testing. */ 91 | mtCOVERAGE_TEST_DELAY(); 92 | 93 | pxIndex->pxPrevious->pxNext = pxNewListItem; 94 | pxIndex->pxPrevious = pxNewListItem; 95 | 96 | /* Remember which list the item is in. */ 97 | pxNewListItem->pvContainer = ( void * ) pxList; 98 | 99 | ( pxList->uxNumberOfItems )++; 100 | } 101 | /*-----------------------------------------------------------*/ 102 | 103 | void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) 104 | { 105 | ListItem_t *pxIterator; 106 | const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; 107 | 108 | /* Only effective when configASSERT() is also defined, these tests may catch 109 | the list data structures being overwritten in memory. They will not catch 110 | data errors caused by incorrect configuration or use of FreeRTOS. */ 111 | listTEST_LIST_INTEGRITY( pxList ); 112 | listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); 113 | 114 | /* Insert the new list item into the list, sorted in xItemValue order. 115 | 116 | If the list already contains a list item with the same item value then the 117 | new list item should be placed after it. This ensures that TCB's which are 118 | stored in ready lists (all of which have the same xItemValue value) get a 119 | share of the CPU. However, if the xItemValue is the same as the back marker 120 | the iteration loop below will not end. Therefore the value is checked 121 | first, and the algorithm slightly modified if necessary. */ 122 | if( xValueOfInsertion == portMAX_DELAY ) 123 | { 124 | pxIterator = pxList->xListEnd.pxPrevious; 125 | } 126 | else 127 | { 128 | /* *** NOTE *********************************************************** 129 | If you find your application is crashing here then likely causes are 130 | listed below. In addition see http://www.freertos.org/FAQHelp.html for 131 | more tips, and ensure configASSERT() is defined! 132 | http://www.freertos.org/a00110.html#configASSERT 133 | 134 | 1) Stack overflow - 135 | see http://www.freertos.org/Stacks-and-stack-overflow-checking.html 136 | 2) Incorrect interrupt priority assignment, especially on Cortex-M 137 | parts where numerically high priority values denote low actual 138 | interrupt priorities, which can seem counter intuitive. See 139 | http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition 140 | of configMAX_SYSCALL_INTERRUPT_PRIORITY on 141 | http://www.freertos.org/a00110.html 142 | 3) Calling an API function from within a critical section or when 143 | the scheduler is suspended, or calling an API function that does 144 | not end in "FromISR" from an interrupt. 145 | 4) Using a queue or semaphore before it has been initialised or 146 | before the scheduler has been started (are interrupts firing 147 | before vTaskStartScheduler() has been called?). 148 | **********************************************************************/ 149 | 150 | for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ 151 | { 152 | /* There is nothing to do here, just iterating to the wanted 153 | insertion position. */ 154 | } 155 | } 156 | 157 | pxNewListItem->pxNext = pxIterator->pxNext; 158 | pxNewListItem->pxNext->pxPrevious = pxNewListItem; 159 | pxNewListItem->pxPrevious = pxIterator; 160 | pxIterator->pxNext = pxNewListItem; 161 | 162 | /* Remember which list the item is in. This allows fast removal of the 163 | item later. */ 164 | pxNewListItem->pvContainer = ( void * ) pxList; 165 | 166 | ( pxList->uxNumberOfItems )++; 167 | } 168 | /*-----------------------------------------------------------*/ 169 | 170 | UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) 171 | { 172 | /* The list item knows which list it is in. Obtain the list from the list 173 | item. */ 174 | List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer; 175 | 176 | pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; 177 | pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; 178 | 179 | /* Only used during decision coverage testing. */ 180 | mtCOVERAGE_TEST_DELAY(); 181 | 182 | /* Make sure the index is left pointing to a valid item. */ 183 | if( pxList->pxIndex == pxItemToRemove ) 184 | { 185 | pxList->pxIndex = pxItemToRemove->pxPrevious; 186 | } 187 | else 188 | { 189 | mtCOVERAGE_TEST_MARKER(); 190 | } 191 | 192 | pxItemToRemove->pvContainer = NULL; 193 | ( pxList->uxNumberOfItems )--; 194 | 195 | return pxList->uxNumberOfItems; 196 | } 197 | /*-----------------------------------------------------------*/ 198 | 199 | -------------------------------------------------------------------------------- /FreeRTOS/Source/portable/GCC/ARM_CA53_64_RaspberryPi3/port.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /* Standard includes. */ 29 | #include 30 | 31 | /* Scheduler includes. */ 32 | #include "FreeRTOS.h" 33 | #include "task.h" 34 | 35 | #ifndef configSETUP_TICK_INTERRUPT 36 | #error configSETUP_TICK_INTERRUPT() must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html 37 | #endif /* configSETUP_TICK_INTERRUPT */ 38 | 39 | /* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in 40 | portmacro.h. */ 41 | #ifndef configCLEAR_TICK_INTERRUPT 42 | #define configCLEAR_TICK_INTERRUPT() 43 | #endif 44 | 45 | /* A critical section is exited when the critical section nesting count reaches 46 | this value. */ 47 | #define portNO_CRITICAL_NESTING ( ( size_t ) 0 ) 48 | 49 | /* Tasks are not created with a floating point context, but can be given a 50 | floating point context after they have been created. A variable is stored as 51 | part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task 52 | does not have an FPU context, or any other value if the task does have an FPU 53 | context. */ 54 | #define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) 55 | 56 | /* Constants required to setup the initial task context. */ 57 | #define portSP_ELx ( ( StackType_t ) 0x01 ) 58 | #define portSP_EL0 ( ( StackType_t ) 0x00 ) 59 | 60 | #define portEL1 ( ( StackType_t ) 0x04 ) 61 | #define portINITIAL_PSTATE ( portEL1 | portSP_EL0 ) 62 | 63 | /* Masks all bits in the APSR other than the mode bits. */ 64 | #define portAPSR_MODE_BITS_MASK ( 0x0C ) 65 | 66 | /* Used in the ASM code. */ 67 | __attribute__(( used )) const uint64_t ulCORE0_INT_SRC = 0x40000060; 68 | 69 | /*-----------------------------------------------------------*/ 70 | 71 | /* 72 | * Starts the first task executing. This function is necessarily written in 73 | * assembly code so is implemented in portASM.s. 74 | */ 75 | extern void vPortRestoreTaskContext( void ); 76 | 77 | /*-----------------------------------------------------------*/ 78 | 79 | /* A variable is used to keep track of the critical section nesting. This 80 | variable has to be stored as part of the task context and must be initialised to 81 | a non zero value to ensure interrupts don't inadvertently become unmasked before 82 | the scheduler starts. As it is stored as part of the task context it will 83 | automatically be set to 0 when the first task is started. */ 84 | volatile uint64_t ullCriticalNesting = 9999ULL; 85 | 86 | /* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero 87 | then floating point context must be saved and restored for the task. */ 88 | uint64_t ullPortTaskHasFPUContext = pdFALSE; 89 | 90 | /* Set to 1 to pend a context switch from an ISR. */ 91 | uint64_t ullPortYieldRequired = pdFALSE; 92 | 93 | /* Counts the interrupt nesting depth. A context switch is only performed if 94 | if the nesting depth is 0. */ 95 | uint64_t ullPortInterruptNesting = 0; 96 | 97 | /*-----------------------------------------------------------*/ 98 | /* 99 | * See header file for description. 100 | */ 101 | StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) 102 | { 103 | /* Setup the initial stack of the task. The stack is set exactly as 104 | expected by the portRESTORE_CONTEXT() macro. */ 105 | 106 | /* First all the general purpose registers. */ 107 | pxTopOfStack--; 108 | *pxTopOfStack = 0x0101010101010101ULL; /* R1 */ 109 | pxTopOfStack--; 110 | *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ 111 | pxTopOfStack--; 112 | *pxTopOfStack = 0x0303030303030303ULL; /* R3 */ 113 | pxTopOfStack--; 114 | *pxTopOfStack = 0x0202020202020202ULL; /* R2 */ 115 | pxTopOfStack--; 116 | *pxTopOfStack = 0x0505050505050505ULL; /* R5 */ 117 | pxTopOfStack--; 118 | *pxTopOfStack = 0x0404040404040404ULL; /* R4 */ 119 | pxTopOfStack--; 120 | *pxTopOfStack = 0x0707070707070707ULL; /* R7 */ 121 | pxTopOfStack--; 122 | *pxTopOfStack = 0x0606060606060606ULL; /* R6 */ 123 | pxTopOfStack--; 124 | *pxTopOfStack = 0x0909090909090909ULL; /* R9 */ 125 | pxTopOfStack--; 126 | *pxTopOfStack = 0x0808080808080808ULL; /* R8 */ 127 | pxTopOfStack--; 128 | *pxTopOfStack = 0x1111111111111111ULL; /* R11 */ 129 | pxTopOfStack--; 130 | *pxTopOfStack = 0x1010101010101010ULL; /* R10 */ 131 | pxTopOfStack--; 132 | *pxTopOfStack = 0x1313131313131313ULL; /* R13 */ 133 | pxTopOfStack--; 134 | *pxTopOfStack = 0x1212121212121212ULL; /* R12 */ 135 | pxTopOfStack--; 136 | *pxTopOfStack = 0x1515151515151515ULL; /* R15 */ 137 | pxTopOfStack--; 138 | *pxTopOfStack = 0x1414141414141414ULL; /* R14 */ 139 | pxTopOfStack--; 140 | *pxTopOfStack = 0x1717171717171717ULL; /* R17 */ 141 | pxTopOfStack--; 142 | *pxTopOfStack = 0x1616161616161616ULL; /* R16 */ 143 | pxTopOfStack--; 144 | *pxTopOfStack = 0x1919191919191919ULL; /* R19 */ 145 | pxTopOfStack--; 146 | *pxTopOfStack = 0x1818181818181818ULL; /* R18 */ 147 | pxTopOfStack--; 148 | *pxTopOfStack = 0x2121212121212121ULL; /* R21 */ 149 | pxTopOfStack--; 150 | *pxTopOfStack = 0x2020202020202020ULL; /* R20 */ 151 | pxTopOfStack--; 152 | *pxTopOfStack = 0x2323232323232323ULL; /* R23 */ 153 | pxTopOfStack--; 154 | *pxTopOfStack = 0x2222222222222222ULL; /* R22 */ 155 | pxTopOfStack--; 156 | *pxTopOfStack = 0x2525252525252525ULL; /* R25 */ 157 | pxTopOfStack--; 158 | *pxTopOfStack = 0x2424242424242424ULL; /* R24 */ 159 | pxTopOfStack--; 160 | *pxTopOfStack = 0x2727272727272727ULL; /* R27 */ 161 | pxTopOfStack--; 162 | *pxTopOfStack = 0x2626262626262626ULL; /* R26 */ 163 | pxTopOfStack--; 164 | *pxTopOfStack = 0x2929292929292929ULL; /* R29 */ 165 | pxTopOfStack--; 166 | *pxTopOfStack = 0x2828282828282828ULL; /* R28 */ 167 | pxTopOfStack--; 168 | *pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */ 169 | pxTopOfStack--; 170 | *pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */ 171 | pxTopOfStack--; 172 | 173 | *pxTopOfStack = portINITIAL_PSTATE; 174 | pxTopOfStack--; 175 | 176 | *pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */ 177 | pxTopOfStack--; 178 | 179 | /* The task will start with a critical nesting count of 0 as interrupts are 180 | enabled. */ 181 | *pxTopOfStack = portNO_CRITICAL_NESTING; 182 | pxTopOfStack--; 183 | 184 | /* The task will start without a floating point context. A task that uses 185 | the floating point hardware must call vPortTaskUsesFPU() before executing 186 | any floating point instructions. */ 187 | *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; 188 | 189 | return pxTopOfStack; 190 | } 191 | /*-----------------------------------------------------------*/ 192 | 193 | BaseType_t xPortStartScheduler( void ) 194 | { 195 | uint32_t ulAPSR; 196 | 197 | /* At the time of writing, the BSP only supports EL3. */ 198 | __asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) ); 199 | ulAPSR &= portAPSR_MODE_BITS_MASK; 200 | 201 | configASSERT( ulAPSR == portEL1 ); 202 | if( ulAPSR == portEL1 ) 203 | { 204 | { 205 | /* Interrupts are turned off in the CPU itself to ensure a tick does 206 | not execute while the scheduler is being started. Interrupts are 207 | automatically turned back on in the CPU when the first task starts 208 | executing. */ 209 | portDISABLE_INTERRUPTS(); 210 | 211 | /* Start the timer that generates the tick ISR. */ 212 | configSETUP_TICK_INTERRUPT(); 213 | 214 | /* Start the first task executing. */ 215 | vPortRestoreTaskContext(); 216 | } 217 | } 218 | 219 | return 0; 220 | } 221 | /*-----------------------------------------------------------*/ 222 | 223 | void vPortEndScheduler( void ) 224 | { 225 | /* Not implemented in ports where there is nothing to return to. 226 | Artificially force an assert. */ 227 | configASSERT( ullCriticalNesting == 1000ULL ); 228 | } 229 | /*-----------------------------------------------------------*/ 230 | 231 | void vPortEnterCritical( void ) 232 | { 233 | portDISABLE_INTERRUPTS(); 234 | 235 | /* Now interrupts are disabled ullCriticalNesting can be accessed 236 | directly. Increment ullCriticalNesting to keep a count of how many times 237 | portENTER_CRITICAL() has been called. */ 238 | ullCriticalNesting++; 239 | 240 | /* This is not the interrupt safe version of the enter critical function so 241 | assert() if it is being called from an interrupt context. Only API 242 | functions that end in "FromISR" can be used in an interrupt. Only assert if 243 | the critical nesting count is 1 to protect against recursive calls if the 244 | assert function also uses a critical section. */ 245 | if( ullCriticalNesting == 1ULL ) 246 | { 247 | configASSERT( ullPortInterruptNesting == 0 ); 248 | } 249 | } 250 | /*-----------------------------------------------------------*/ 251 | 252 | void vPortExitCritical( void ) 253 | { 254 | if( ullCriticalNesting > portNO_CRITICAL_NESTING ) 255 | { 256 | /* Decrement the nesting count as the critical section is being 257 | exited. */ 258 | ullCriticalNesting--; 259 | 260 | /* If the nesting level has reached zero then all interrupt 261 | priorities must be re-enabled. */ 262 | if( ullCriticalNesting == portNO_CRITICAL_NESTING ) 263 | { 264 | /* Critical nesting has reached zero so interrupts 265 | should be enabled. */ 266 | portENABLE_INTERRUPTS(); 267 | } 268 | } 269 | } 270 | /*-----------------------------------------------------------*/ 271 | 272 | void FreeRTOS_Tick_Handler( void ) 273 | { 274 | /* Interrupts should not be enabled before this point. */ 275 | #if( configASSERT_DEFINED == 1 ) 276 | { 277 | uint32_t ulMaskBits; 278 | 279 | __asm volatile( "mrs %0, daif" : "=r"( ulMaskBits ) :: "memory" ); 280 | configASSERT( ( ulMaskBits & portDAIF_I ) != 0 ); 281 | } 282 | #endif /* configASSERT_DEFINED */ 283 | 284 | /* Ok to enable interrupts after the interrupt source has been cleared. */ 285 | configCLEAR_TICK_INTERRUPT(); 286 | portENABLE_INTERRUPTS(); 287 | 288 | /* Increment the RTOS tick. */ 289 | if( xTaskIncrementTick() != pdFALSE ) 290 | { 291 | ullPortYieldRequired = pdTRUE; 292 | } 293 | } 294 | /*-----------------------------------------------------------*/ 295 | 296 | void *memcpy(void *dst, const void *src, size_t n) 297 | { 298 | /* copy per 1 byte */ 299 | const char *p = src; 300 | char *q = dst; 301 | 302 | while (n--) { 303 | *q++ = *p++; 304 | } 305 | 306 | return dst; 307 | } 308 | 309 | -------------------------------------------------------------------------------- /FreeRTOS/Source/portable/GCC/ARM_CA53_64_RaspberryPi3/portASM.S: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | .text 29 | 30 | /* Variables and functions. */ 31 | .extern ullMaxAPIPriorityMask 32 | .extern pxCurrentTCB 33 | .extern _freertos_vector_table 34 | 35 | .globl FreeRTOS_SWI_Handler 36 | .globl FreeRTOS_IRQ_Handler 37 | .globl vPortRestoreTaskContext 38 | 39 | ; /**********************************************************************/ 40 | 41 | .macro portSAVE_CONTEXT 42 | 43 | /* Switch to use the EL0 stack pointer. */ 44 | MSR SPSEL, #0 45 | 46 | /* Save the entire context. */ 47 | STP X0, X1, [SP, #-0x10]! 48 | STP X2, X3, [SP, #-0x10]! 49 | STP X4, X5, [SP, #-0x10]! 50 | STP X6, X7, [SP, #-0x10]! 51 | STP X8, X9, [SP, #-0x10]! 52 | STP X10, X11, [SP, #-0x10]! 53 | STP X12, X13, [SP, #-0x10]! 54 | STP X14, X15, [SP, #-0x10]! 55 | STP X16, X17, [SP, #-0x10]! 56 | STP X18, X19, [SP, #-0x10]! 57 | STP X20, X21, [SP, #-0x10]! 58 | STP X22, X23, [SP, #-0x10]! 59 | STP X24, X25, [SP, #-0x10]! 60 | STP X26, X27, [SP, #-0x10]! 61 | STP X28, X29, [SP, #-0x10]! 62 | STP X30, XZR, [SP, #-0x10]! 63 | 64 | /* Save the SPSR. */ 65 | MRS X3, SPSR_EL1 66 | MRS X2, ELR_EL1 67 | 68 | STP X2, X3, [SP, #-0x10]! 69 | 70 | /* Save the critical section nesting depth. */ 71 | LDR X0, ullCriticalNestingConst 72 | LDR X3, [X0] 73 | 74 | /* Save the FPU context indicator. */ 75 | LDR X0, ullPortTaskHasFPUContextConst 76 | LDR X2, [X0] 77 | 78 | /* Save the FPU context, if any (32 128-bit registers). */ 79 | CMP X2, #0 80 | B.EQ 1f 81 | STP Q0, Q1, [SP,#-0x20]! 82 | STP Q2, Q3, [SP,#-0x20]! 83 | STP Q4, Q5, [SP,#-0x20]! 84 | STP Q6, Q7, [SP,#-0x20]! 85 | STP Q8, Q9, [SP,#-0x20]! 86 | STP Q10, Q11, [SP,#-0x20]! 87 | STP Q12, Q13, [SP,#-0x20]! 88 | STP Q14, Q15, [SP,#-0x20]! 89 | STP Q16, Q17, [SP,#-0x20]! 90 | STP Q18, Q19, [SP,#-0x20]! 91 | STP Q20, Q21, [SP,#-0x20]! 92 | STP Q22, Q23, [SP,#-0x20]! 93 | STP Q24, Q25, [SP,#-0x20]! 94 | STP Q26, Q27, [SP,#-0x20]! 95 | STP Q28, Q29, [SP,#-0x20]! 96 | STP Q30, Q31, [SP,#-0x20]! 97 | 98 | 1: 99 | /* Store the critical nesting count and FPU context indicator. */ 100 | STP X2, X3, [SP, #-0x10]! 101 | 102 | LDR X0, pxCurrentTCBConst 103 | LDR X1, [X0] 104 | MOV X0, SP /* Move SP into X0 for saving. */ 105 | STR X0, [X1] 106 | 107 | /* Switch to use the ELx stack pointer. */ 108 | MSR SPSEL, #1 109 | 110 | .endm 111 | 112 | 113 | .macro portRESTORE_CONTEXT 114 | 115 | /* Switch to use the EL0 stack pointer. */ 116 | MSR SPSEL, #0 117 | 118 | /* Set the SP to point to the stack of the task being restored. */ 119 | LDR X0, pxCurrentTCBConst 120 | LDR X1, [X0] 121 | LDR X0, [X1] 122 | MOV SP, X0 123 | 124 | LDP X2, X3, [SP], #0x10 /* Critical nesting and FPU context. */ 125 | 126 | /* Set the PMR register to be correct for the current critical nesting 127 | depth. */ 128 | LDR X0, ullCriticalNestingConst /* X0 holds the address of ullCriticalNesting. */ 129 | STR X3, [X0] /* Restore the task's critical nesting count. */ 130 | 131 | /* Restore the FPU context indicator. */ 132 | LDR X0, ullPortTaskHasFPUContextConst 133 | STR X2, [X0] 134 | 135 | /* Restore the FPU context, if any. */ 136 | CMP X2, #0 137 | B.EQ 1f 138 | LDP Q30, Q31, [SP], #0x20 139 | LDP Q28, Q29, [SP], #0x20 140 | LDP Q26, Q27, [SP], #0x20 141 | LDP Q24, Q25, [SP], #0x20 142 | LDP Q22, Q23, [SP], #0x20 143 | LDP Q20, Q21, [SP], #0x20 144 | LDP Q18, Q19, [SP], #0x20 145 | LDP Q16, Q17, [SP], #0x20 146 | LDP Q14, Q15, [SP], #0x20 147 | LDP Q12, Q13, [SP], #0x20 148 | LDP Q10, Q11, [SP], #0x20 149 | LDP Q8, Q9, [SP], #0x20 150 | LDP Q6, Q7, [SP], #0x20 151 | LDP Q4, Q5, [SP], #0x20 152 | LDP Q2, Q3, [SP], #0x20 153 | LDP Q0, Q1, [SP], #0x20 154 | 1: 155 | LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ 156 | 157 | /* Restore the SPSR. */ 158 | MSR SPSR_EL1, X3 159 | /* Restore the ELR. */ 160 | MSR ELR_EL1, X2 161 | 162 | LDP X30, XZR, [SP], #0x10 163 | LDP X28, X29, [SP], #0x10 164 | LDP X26, X27, [SP], #0x10 165 | LDP X24, X25, [SP], #0x10 166 | LDP X22, X23, [SP], #0x10 167 | LDP X20, X21, [SP], #0x10 168 | LDP X18, X19, [SP], #0x10 169 | LDP X16, X17, [SP], #0x10 170 | LDP X14, X15, [SP], #0x10 171 | LDP X12, X13, [SP], #0x10 172 | LDP X10, X11, [SP], #0x10 173 | LDP X8, X9, [SP], #0x10 174 | LDP X6, X7, [SP], #0x10 175 | LDP X4, X5, [SP], #0x10 176 | LDP X2, X3, [SP], #0x10 177 | LDP X0, X1, [SP], #0x10 178 | 179 | /* Switch to use the ELx stack pointer. _RB_ Might not be required. */ 180 | MSR SPSEL, #1 181 | 182 | ERET 183 | 184 | .endm 185 | 186 | /****************************************************************************** 187 | * FreeRTOS_SWI_Handler handler is used to perform a context switch. 188 | *****************************************************************************/ 189 | .align 8 190 | .type FreeRTOS_SWI_Handler, %function 191 | FreeRTOS_SWI_Handler: 192 | /* Save the context of the current task and select a new task to run. */ 193 | portSAVE_CONTEXT 194 | MRS X0, ESR_EL1 195 | 196 | LSR X1, X0, #26 197 | 198 | CMP X1, #0x15 /* 0x15 = SVC instruction. */ 199 | 200 | B.NE FreeRTOS_Abort 201 | BL vTaskSwitchContext 202 | 203 | portRESTORE_CONTEXT 204 | 205 | FreeRTOS_Abort: 206 | /* Full ESR is in X0, exception class code is in X1. */ 207 | B . 208 | 209 | /****************************************************************************** 210 | * vPortRestoreTaskContext is used to start the scheduler. 211 | *****************************************************************************/ 212 | .align 8 213 | .type vPortRestoreTaskContext, %function 214 | vPortRestoreTaskContext: 215 | .set freertos_vector_base, _freertos_vector_table 216 | 217 | /* Install the FreeRTOS interrupt handlers. */ 218 | LDR X1, =freertos_vector_base 219 | MSR VBAR_EL1, X1 220 | DSB SY 221 | ISB SY 222 | 223 | /* Start the first task. */ 224 | portRESTORE_CONTEXT 225 | 226 | /****************************************************************************** 227 | * FreeRTOS_IRQ_Handler handles IRQ entry and exit. 228 | *****************************************************************************/ 229 | .align 8 230 | .type FreeRTOS_IRQ_Handler, %function 231 | FreeRTOS_IRQ_Handler: 232 | /* Save volatile registers. */ 233 | STP X0, X1, [SP, #-0x10]! 234 | STP X2, X3, [SP, #-0x10]! 235 | STP X4, X5, [SP, #-0x10]! 236 | STP X6, X7, [SP, #-0x10]! 237 | STP X8, X9, [SP, #-0x10]! 238 | STP X10, X11, [SP, #-0x10]! 239 | STP X12, X13, [SP, #-0x10]! 240 | STP X14, X15, [SP, #-0x10]! 241 | STP X16, X17, [SP, #-0x10]! 242 | STP X18, X19, [SP, #-0x10]! 243 | STP X29, X30, [SP, #-0x10]! 244 | 245 | /* Save the SPSR and ELR. */ 246 | MRS X3, SPSR_EL1 247 | MRS X2, ELR_EL1 248 | STP X2, X3, [SP, #-0x10]! 249 | 250 | /* Increment the interrupt nesting counter. */ 251 | LDR X5, ullPortInterruptNestingConst 252 | LDR X1, [X5] /* Old nesting count in X1. */ 253 | ADD X6, X1, #1 254 | STR X6, [X5] /* Address of nesting count variable in X5. */ 255 | 256 | /* Maintain the interrupt nesting information across the function call. */ 257 | STP X1, X5, [SP, #-0x10]! 258 | 259 | /* Read Cor0 interrupt Source */ 260 | ldr x2, ulCORE0_INT_SRCConst 261 | ldr x3, [x2] 262 | ldr w0, [x3] /* set parametor for handler */ 263 | 264 | /* Call the C handler. */ 265 | BL vApplicationIRQHandler 266 | 267 | /* Disable interrupts. */ 268 | MSR DAIFSET, #2 269 | DSB SY 270 | ISB SY 271 | 272 | /* Restore the critical nesting count. */ 273 | LDP X1, X5, [SP], #0x10 274 | STR X1, [X5] 275 | 276 | /* Has interrupt nesting unwound? */ 277 | CMP X1, #0 278 | B.NE Exit_IRQ_No_Context_Switch 279 | 280 | /* Is a context switch required? */ 281 | LDR X0, ullPortYieldRequiredConst 282 | LDR X1, [X0] 283 | CMP X1, #0 284 | B.EQ Exit_IRQ_No_Context_Switch 285 | 286 | /* Reset ullPortYieldRequired to 0. */ 287 | MOV X2, #0 288 | STR X2, [X0] 289 | 290 | /* Restore volatile registers. */ 291 | LDP X4, X5, [SP], #0x10 /* SPSR and ELR. */ 292 | MSR SPSR_EL1, X5 293 | MSR ELR_EL1, X4 294 | DSB SY 295 | ISB SY 296 | 297 | LDP X29, X30, [SP], #0x10 298 | LDP X18, X19, [SP], #0x10 299 | LDP X16, X17, [SP], #0x10 300 | LDP X14, X15, [SP], #0x10 301 | LDP X12, X13, [SP], #0x10 302 | LDP X10, X11, [SP], #0x10 303 | LDP X8, X9, [SP], #0x10 304 | LDP X6, X7, [SP], #0x10 305 | LDP X4, X5, [SP], #0x10 306 | LDP X2, X3, [SP], #0x10 307 | LDP X0, X1, [SP], #0x10 308 | 309 | /* Save the context of the current task and select a new task to run. */ 310 | portSAVE_CONTEXT 311 | BL vTaskSwitchContext 312 | portRESTORE_CONTEXT 313 | 314 | Exit_IRQ_No_Context_Switch: 315 | /* Restore volatile registers. */ 316 | LDP X4, X5, [SP], #0x10 /* SPSR and ELR. */ 317 | MSR SPSR_EL1, X5 318 | MSR ELR_EL1, X4 319 | DSB SY 320 | ISB SY 321 | 322 | LDP X29, X30, [SP], #0x10 323 | LDP X18, X19, [SP], #0x10 324 | LDP X16, X17, [SP], #0x10 325 | LDP X14, X15, [SP], #0x10 326 | LDP X12, X13, [SP], #0x10 327 | LDP X10, X11, [SP], #0x10 328 | LDP X8, X9, [SP], #0x10 329 | LDP X6, X7, [SP], #0x10 330 | LDP X4, X5, [SP], #0x10 331 | LDP X2, X3, [SP], #0x10 332 | LDP X0, X1, [SP], #0x10 333 | 334 | ERET 335 | 336 | 337 | .align 8 338 | pxCurrentTCBConst: .dword pxCurrentTCB 339 | ullCriticalNestingConst: .dword ullCriticalNesting 340 | ullPortTaskHasFPUContextConst: .dword ullPortTaskHasFPUContext 341 | 342 | vApplicationIRQHandlerConst: .word vApplicationIRQHandler 343 | ullPortInterruptNestingConst: .dword ullPortInterruptNesting 344 | ullPortYieldRequiredConst: .dword ullPortYieldRequired 345 | 346 | ulCORE0_INT_SRCConst: .dword ulCORE0_INT_SRC 347 | .end 348 | -------------------------------------------------------------------------------- /FreeRTOS/Source/portable/GCC/ARM_CA53_64_RaspberryPi3/portmacro.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | #ifndef PORTMACRO_H 29 | #define PORTMACRO_H 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | /*----------------------------------------------------------- 36 | * Port specific definitions. 37 | * 38 | * The settings in this file configure FreeRTOS correctly for the given hardware 39 | * and compiler. 40 | * 41 | * These settings should not be altered. 42 | *----------------------------------------------------------- 43 | */ 44 | 45 | /* Type definitions. */ 46 | #define portCHAR char 47 | #define portFLOAT float 48 | #define portDOUBLE double 49 | #define portLONG long 50 | #define portSHORT short 51 | #define portSTACK_TYPE size_t 52 | #define portBASE_TYPE long 53 | 54 | typedef portSTACK_TYPE StackType_t; 55 | typedef portBASE_TYPE BaseType_t; 56 | typedef uint64_t UBaseType_t; 57 | 58 | typedef uint64_t TickType_t; 59 | #define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff ) 60 | 61 | /*-----------------------------------------------------------*/ 62 | 63 | /* Task utilities. */ 64 | 65 | #define portYIELD() __asm volatile ( "SVC 0" ::: "memory" ) 66 | 67 | /*----------------------------------------------------------- 68 | * Critical section control 69 | *----------------------------------------------------------*/ 70 | 71 | extern void vPortEnterCritical( void ); 72 | extern void vPortExitCritical( void ); 73 | 74 | #define portDISABLE_INTERRUPTS() \ 75 | __asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \ 76 | __asm volatile ( "DSB SY" ); \ 77 | __asm volatile ( "ISB SY" ); 78 | 79 | #define portENABLE_INTERRUPTS() \ 80 | __asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \ 81 | __asm volatile ( "DSB SY" ); \ 82 | __asm volatile ( "ISB SY" ); 83 | 84 | 85 | 86 | /* These macros do not globally disable/enable interrupts. They do mask off 87 | interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ 88 | #define portENTER_CRITICAL() vPortEnterCritical(); 89 | #define portEXIT_CRITICAL() vPortExitCritical(); 90 | 91 | /*-----------------------------------------------------------*/ 92 | 93 | /* Task function macros as described on the FreeRTOS.org WEB site. These are 94 | not required for this port but included in case common demo code that uses these 95 | macros is used. */ 96 | #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) 97 | #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) 98 | 99 | /* Prototype of the FreeRTOS tick handler. This must be installed as the 100 | handler for whichever peripheral is used to generate the RTOS tick. */ 101 | void FreeRTOS_Tick_Handler( void ); 102 | 103 | /*-----------------------------------------------------------*/ 104 | 105 | /* Hardware specifics. */ 106 | #define portSTACK_GROWTH ( -1 ) 107 | #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) 108 | #define portBYTE_ALIGNMENT 16 109 | #define portPOINTER_SIZE_TYPE uint64_t 110 | 111 | #ifdef __cplusplus 112 | } /* extern C */ 113 | #endif 114 | 115 | #endif /* PORTMACRO_H */ 116 | 117 | -------------------------------------------------------------------------------- /FreeRTOS/Source/portable/MemMang/heap_1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | 29 | /* 30 | * The simplest possible implementation of pvPortMalloc(). Note that this 31 | * implementation does NOT allow allocated memory to be freed again. 32 | * 33 | * See heap_2.c, heap_3.c and heap_4.c for alternative implementations, and the 34 | * memory management pages of http://www.FreeRTOS.org for more information. 35 | */ 36 | #include 37 | 38 | /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 39 | all the API functions to use the MPU wrappers. That should only be done when 40 | task.h is included from an application file. */ 41 | #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 42 | 43 | #include "FreeRTOS.h" 44 | #include "task.h" 45 | 46 | #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE 47 | 48 | #if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) 49 | #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 50 | #endif 51 | 52 | /* A few bytes might be lost to byte aligning the heap start address. */ 53 | #define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) 54 | 55 | /* Allocate the memory for the heap. */ 56 | /* Allocate the memory for the heap. */ 57 | #if( configAPPLICATION_ALLOCATED_HEAP == 1 ) 58 | /* The application writer has already defined the array used for the RTOS 59 | heap - probably so it can be placed in a special segment or address. */ 60 | extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 61 | #else 62 | static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; 63 | #endif /* configAPPLICATION_ALLOCATED_HEAP */ 64 | 65 | /* Index into the ucHeap array. */ 66 | static size_t xNextFreeByte = ( size_t ) 0; 67 | 68 | /*-----------------------------------------------------------*/ 69 | 70 | void *pvPortMalloc( size_t xWantedSize ) 71 | { 72 | void *pvReturn = NULL; 73 | static uint8_t *pucAlignedHeap = NULL; 74 | 75 | /* Ensure that blocks are always aligned to the required number of bytes. */ 76 | #if( portBYTE_ALIGNMENT != 1 ) 77 | { 78 | if( xWantedSize & portBYTE_ALIGNMENT_MASK ) 79 | { 80 | /* Byte alignment required. */ 81 | xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); 82 | } 83 | } 84 | #endif 85 | 86 | vTaskSuspendAll(); 87 | { 88 | if( pucAlignedHeap == NULL ) 89 | { 90 | /* Ensure the heap starts on a correctly aligned boundary. */ 91 | pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); 92 | } 93 | 94 | /* Check there is enough room left for the allocation. */ 95 | if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) && 96 | ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */ 97 | { 98 | /* Return the next free byte then increment the index past this 99 | block. */ 100 | pvReturn = pucAlignedHeap + xNextFreeByte; 101 | xNextFreeByte += xWantedSize; 102 | } 103 | 104 | traceMALLOC( pvReturn, xWantedSize ); 105 | } 106 | ( void ) xTaskResumeAll(); 107 | 108 | #if( configUSE_MALLOC_FAILED_HOOK == 1 ) 109 | { 110 | if( pvReturn == NULL ) 111 | { 112 | extern void vApplicationMallocFailedHook( void ); 113 | vApplicationMallocFailedHook(); 114 | } 115 | } 116 | #endif 117 | 118 | return pvReturn; 119 | } 120 | /*-----------------------------------------------------------*/ 121 | 122 | void vPortFree( void *pv ) 123 | { 124 | /* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and 125 | heap_4.c for alternative implementations, and the memory management pages of 126 | http://www.FreeRTOS.org for more information. */ 127 | ( void ) pv; 128 | 129 | /* Force an assert as it is invalid to call this function. */ 130 | configASSERT( pv == NULL ); 131 | } 132 | /*-----------------------------------------------------------*/ 133 | 134 | void vPortInitialiseBlocks( void ) 135 | { 136 | /* Only required when static memory is not cleared. */ 137 | xNextFreeByte = ( size_t ) 0; 138 | } 139 | /*-----------------------------------------------------------*/ 140 | 141 | size_t xPortGetFreeHeapSize( void ) 142 | { 143 | return ( configADJUSTED_HEAP_SIZE - xNextFreeByte ); 144 | } 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /FreeRTOS/Source/timers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.0.1 3 | * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /* Standard includes. */ 29 | #include 30 | 31 | /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 32 | all the API functions to use the MPU wrappers. That should only be done when 33 | task.h is included from an application file. */ 34 | #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 35 | 36 | #include "FreeRTOS.h" 37 | #include "task.h" 38 | #include "queue.h" 39 | #include "timers.h" 40 | 41 | #if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 ) 42 | #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available. 43 | #endif 44 | 45 | /* Lint e961 and e750 are suppressed as a MISRA exception justified because the 46 | MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the 47 | header files above, but not in this file, in order to generate the correct 48 | privileged Vs unprivileged linkage and placement. */ 49 | #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ 50 | 51 | 52 | /* This entire source file will be skipped if the application is not configured 53 | to include software timer functionality. This #if is closed at the very bottom 54 | of this file. If you want to include software timer functionality then ensure 55 | configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ 56 | #if ( configUSE_TIMERS == 1 ) 57 | 58 | /* Misc definitions. */ 59 | #define tmrNO_DELAY ( TickType_t ) 0U 60 | 61 | /* The name assigned to the timer service task. This can be overridden by 62 | defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */ 63 | #ifndef configTIMER_SERVICE_TASK_NAME 64 | #define configTIMER_SERVICE_TASK_NAME "Tmr Svc" 65 | #endif 66 | 67 | /* The definition of the timers themselves. */ 68 | typedef struct tmrTimerControl 69 | { 70 | const char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ 71 | ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ 72 | TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */ 73 | UBaseType_t uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one-shot timer. */ 74 | void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ 75 | TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */ 76 | #if( configUSE_TRACE_FACILITY == 1 ) 77 | UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */ 78 | #endif 79 | 80 | #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) 81 | uint8_t ucStaticallyAllocated; /*<< Set to pdTRUE if the timer was created statically so no attempt is made to free the memory again if the timer is later deleted. */ 82 | #endif 83 | } xTIMER; 84 | 85 | /* The old xTIMER name is maintained above then typedefed to the new Timer_t 86 | name below to enable the use of older kernel aware debuggers. */ 87 | typedef xTIMER Timer_t; 88 | 89 | /* The definition of messages that can be sent and received on the timer queue. 90 | Two types of message can be queued - messages that manipulate a software timer, 91 | and messages that request the execution of a non-timer related callback. The 92 | two message types are defined in two separate structures, xTimerParametersType 93 | and xCallbackParametersType respectively. */ 94 | typedef struct tmrTimerParameters 95 | { 96 | TickType_t xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ 97 | Timer_t * pxTimer; /*<< The timer to which the command will be applied. */ 98 | } TimerParameter_t; 99 | 100 | 101 | typedef struct tmrCallbackParameters 102 | { 103 | PendedFunction_t pxCallbackFunction; /* << The callback function to execute. */ 104 | void *pvParameter1; /* << The value that will be used as the callback functions first parameter. */ 105 | uint32_t ulParameter2; /* << The value that will be used as the callback functions second parameter. */ 106 | } CallbackParameters_t; 107 | 108 | /* The structure that contains the two message types, along with an identifier 109 | that is used to determine which message type is valid. */ 110 | typedef struct tmrTimerQueueMessage 111 | { 112 | BaseType_t xMessageID; /*<< The command being sent to the timer service task. */ 113 | union 114 | { 115 | TimerParameter_t xTimerParameters; 116 | 117 | /* Don't include xCallbackParameters if it is not going to be used as 118 | it makes the structure (and therefore the timer queue) larger. */ 119 | #if ( INCLUDE_xTimerPendFunctionCall == 1 ) 120 | CallbackParameters_t xCallbackParameters; 121 | #endif /* INCLUDE_xTimerPendFunctionCall */ 122 | } u; 123 | } DaemonTaskMessage_t; 124 | 125 | /*lint -save -e956 A manual analysis and inspection has been used to determine 126 | which static variables must be declared volatile. */ 127 | 128 | /* The list in which active timers are stored. Timers are referenced in expire 129 | time order, with the nearest expiry time at the front of the list. Only the 130 | timer service task is allowed to access these lists. */ 131 | PRIVILEGED_DATA static List_t xActiveTimerList1; 132 | PRIVILEGED_DATA static List_t xActiveTimerList2; 133 | PRIVILEGED_DATA static List_t *pxCurrentTimerList; 134 | PRIVILEGED_DATA static List_t *pxOverflowTimerList; 135 | 136 | /* A queue that is used to send commands to the timer service task. */ 137 | PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL; 138 | PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL; 139 | 140 | /*lint -restore */ 141 | 142 | /*-----------------------------------------------------------*/ 143 | 144 | #if( configSUPPORT_STATIC_ALLOCATION == 1 ) 145 | 146 | /* If static allocation is supported then the application must provide the 147 | following callback function - which enables the application to optionally 148 | provide the memory that will be used by the timer task as the task's stack 149 | and TCB. */ 150 | extern void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ); 151 | 152 | #endif 153 | 154 | /* 155 | * Initialise the infrastructure used by the timer service task if it has not 156 | * been initialised already. 157 | */ 158 | static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION; 159 | 160 | /* 161 | * The timer service task (daemon). Timer functionality is controlled by this 162 | * task. Other tasks communicate with the timer service task using the 163 | * xTimerQueue queue. 164 | */ 165 | static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION; 166 | 167 | /* 168 | * Called by the timer service task to interpret and process a command it 169 | * received on the timer queue. 170 | */ 171 | static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION; 172 | 173 | /* 174 | * Insert the timer into either xActiveTimerList1, or xActiveTimerList2, 175 | * depending on if the expire time causes a timer counter overflow. 176 | */ 177 | static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) PRIVILEGED_FUNCTION; 178 | 179 | /* 180 | * An active timer has reached its expire time. Reload the timer if it is an 181 | * auto reload timer, then call its callback. 182 | */ 183 | static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION; 184 | 185 | /* 186 | * The tick count has overflowed. Switch the timer lists after ensuring the 187 | * current timer list does not still reference some timers. 188 | */ 189 | static void prvSwitchTimerLists( void ) PRIVILEGED_FUNCTION; 190 | 191 | /* 192 | * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE 193 | * if a tick count overflow occurred since prvSampleTimeNow() was last called. 194 | */ 195 | static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION; 196 | 197 | /* 198 | * If the timer list contains any active timers then return the expire time of 199 | * the timer that will expire first and set *pxListWasEmpty to false. If the 200 | * timer list does not contain any timers then return 0 and set *pxListWasEmpty 201 | * to pdTRUE. 202 | */ 203 | static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIVILEGED_FUNCTION; 204 | 205 | /* 206 | * If a timer has expired, process it. Otherwise, block the timer service task 207 | * until either a timer does expire or a command is received. 208 | */ 209 | static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION; 210 | 211 | /* 212 | * Called after a Timer_t structure has been allocated either statically or 213 | * dynamically to fill in the structure's members. 214 | */ 215 | static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ 216 | const TickType_t xTimerPeriodInTicks, 217 | const UBaseType_t uxAutoReload, 218 | void * const pvTimerID, 219 | TimerCallbackFunction_t pxCallbackFunction, 220 | Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION; 221 | /*-----------------------------------------------------------*/ 222 | 223 | BaseType_t xTimerCreateTimerTask( void ) 224 | { 225 | BaseType_t xReturn = pdFAIL; 226 | 227 | /* This function is called when the scheduler is started if 228 | configUSE_TIMERS is set to 1. Check that the infrastructure used by the 229 | timer service task has been created/initialised. If timers have already 230 | been created then the initialisation will already have been performed. */ 231 | prvCheckForValidListAndQueue(); 232 | 233 | if( xTimerQueue != NULL ) 234 | { 235 | #if( configSUPPORT_STATIC_ALLOCATION == 1 ) 236 | { 237 | StaticTask_t *pxTimerTaskTCBBuffer = NULL; 238 | StackType_t *pxTimerTaskStackBuffer = NULL; 239 | uint32_t ulTimerTaskStackSize; 240 | 241 | vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize ); 242 | xTimerTaskHandle = xTaskCreateStatic( prvTimerTask, 243 | configTIMER_SERVICE_TASK_NAME, 244 | ulTimerTaskStackSize, 245 | NULL, 246 | ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, 247 | pxTimerTaskStackBuffer, 248 | pxTimerTaskTCBBuffer ); 249 | 250 | if( xTimerTaskHandle != NULL ) 251 | { 252 | xReturn = pdPASS; 253 | } 254 | } 255 | #else 256 | { 257 | xReturn = xTaskCreate( prvTimerTask, 258 | configTIMER_SERVICE_TASK_NAME, 259 | configTIMER_TASK_STACK_DEPTH, 260 | NULL, 261 | ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, 262 | &xTimerTaskHandle ); 263 | } 264 | #endif /* configSUPPORT_STATIC_ALLOCATION */ 265 | } 266 | else 267 | { 268 | mtCOVERAGE_TEST_MARKER(); 269 | } 270 | 271 | configASSERT( xReturn ); 272 | return xReturn; 273 | } 274 | /*-----------------------------------------------------------*/ 275 | 276 | #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) 277 | 278 | TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ 279 | const TickType_t xTimerPeriodInTicks, 280 | const UBaseType_t uxAutoReload, 281 | void * const pvTimerID, 282 | TimerCallbackFunction_t pxCallbackFunction ) 283 | { 284 | Timer_t *pxNewTimer; 285 | 286 | pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) ); 287 | 288 | if( pxNewTimer != NULL ) 289 | { 290 | prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); 291 | 292 | #if( configSUPPORT_STATIC_ALLOCATION == 1 ) 293 | { 294 | /* Timers can be created statically or dynamically, so note this 295 | timer was created dynamically in case the timer is later 296 | deleted. */ 297 | pxNewTimer->ucStaticallyAllocated = pdFALSE; 298 | } 299 | #endif /* configSUPPORT_STATIC_ALLOCATION */ 300 | } 301 | 302 | return pxNewTimer; 303 | } 304 | 305 | #endif /* configSUPPORT_STATIC_ALLOCATION */ 306 | /*-----------------------------------------------------------*/ 307 | 308 | #if( configSUPPORT_STATIC_ALLOCATION == 1 ) 309 | 310 | TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ 311 | const TickType_t xTimerPeriodInTicks, 312 | const UBaseType_t uxAutoReload, 313 | void * const pvTimerID, 314 | TimerCallbackFunction_t pxCallbackFunction, 315 | StaticTimer_t *pxTimerBuffer ) 316 | { 317 | Timer_t *pxNewTimer; 318 | 319 | #if( configASSERT_DEFINED == 1 ) 320 | { 321 | /* Sanity check that the size of the structure used to declare a 322 | variable of type StaticTimer_t equals the size of the real timer 323 | structure. */ 324 | volatile size_t xSize = sizeof( StaticTimer_t ); 325 | configASSERT( xSize == sizeof( Timer_t ) ); 326 | } 327 | #endif /* configASSERT_DEFINED */ 328 | 329 | /* A pointer to a StaticTimer_t structure MUST be provided, use it. */ 330 | configASSERT( pxTimerBuffer ); 331 | pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ 332 | 333 | if( pxNewTimer != NULL ) 334 | { 335 | prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); 336 | 337 | #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) 338 | { 339 | /* Timers can be created statically or dynamically so note this 340 | timer was created statically in case it is later deleted. */ 341 | pxNewTimer->ucStaticallyAllocated = pdTRUE; 342 | } 343 | #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ 344 | } 345 | 346 | return pxNewTimer; 347 | } 348 | 349 | #endif /* configSUPPORT_STATIC_ALLOCATION */ 350 | /*-----------------------------------------------------------*/ 351 | 352 | static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ 353 | const TickType_t xTimerPeriodInTicks, 354 | const UBaseType_t uxAutoReload, 355 | void * const pvTimerID, 356 | TimerCallbackFunction_t pxCallbackFunction, 357 | Timer_t *pxNewTimer ) 358 | { 359 | /* 0 is not a valid value for xTimerPeriodInTicks. */ 360 | configASSERT( ( xTimerPeriodInTicks > 0 ) ); 361 | 362 | if( pxNewTimer != NULL ) 363 | { 364 | /* Ensure the infrastructure used by the timer service task has been 365 | created/initialised. */ 366 | prvCheckForValidListAndQueue(); 367 | 368 | /* Initialise the timer structure members using the function 369 | parameters. */ 370 | pxNewTimer->pcTimerName = pcTimerName; 371 | pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; 372 | pxNewTimer->uxAutoReload = uxAutoReload; 373 | pxNewTimer->pvTimerID = pvTimerID; 374 | pxNewTimer->pxCallbackFunction = pxCallbackFunction; 375 | vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); 376 | traceTIMER_CREATE( pxNewTimer ); 377 | } 378 | } 379 | /*-----------------------------------------------------------*/ 380 | 381 | BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) 382 | { 383 | BaseType_t xReturn = pdFAIL; 384 | DaemonTaskMessage_t xMessage; 385 | 386 | configASSERT( xTimer ); 387 | 388 | /* Send a message to the timer service task to perform a particular action 389 | on a particular timer definition. */ 390 | if( xTimerQueue != NULL ) 391 | { 392 | /* Send a command to the timer service task to start the xTimer timer. */ 393 | xMessage.xMessageID = xCommandID; 394 | xMessage.u.xTimerParameters.xMessageValue = xOptionalValue; 395 | xMessage.u.xTimerParameters.pxTimer = ( Timer_t * ) xTimer; 396 | 397 | if( xCommandID < tmrFIRST_FROM_ISR_COMMAND ) 398 | { 399 | if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) 400 | { 401 | xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); 402 | } 403 | else 404 | { 405 | xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY ); 406 | } 407 | } 408 | else 409 | { 410 | xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); 411 | } 412 | 413 | traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn ); 414 | } 415 | else 416 | { 417 | mtCOVERAGE_TEST_MARKER(); 418 | } 419 | 420 | return xReturn; 421 | } 422 | /*-----------------------------------------------------------*/ 423 | 424 | TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) 425 | { 426 | /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been 427 | started, then xTimerTaskHandle will be NULL. */ 428 | configASSERT( ( xTimerTaskHandle != NULL ) ); 429 | return xTimerTaskHandle; 430 | } 431 | /*-----------------------------------------------------------*/ 432 | 433 | TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) 434 | { 435 | Timer_t *pxTimer = ( Timer_t * ) xTimer; 436 | 437 | configASSERT( xTimer ); 438 | return pxTimer->xTimerPeriodInTicks; 439 | } 440 | /*-----------------------------------------------------------*/ 441 | 442 | TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) 443 | { 444 | Timer_t * pxTimer = ( Timer_t * ) xTimer; 445 | TickType_t xReturn; 446 | 447 | configASSERT( xTimer ); 448 | xReturn = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) ); 449 | return xReturn; 450 | } 451 | /*-----------------------------------------------------------*/ 452 | 453 | const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ 454 | { 455 | Timer_t *pxTimer = ( Timer_t * ) xTimer; 456 | 457 | configASSERT( xTimer ); 458 | return pxTimer->pcTimerName; 459 | } 460 | /*-----------------------------------------------------------*/ 461 | 462 | static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) 463 | { 464 | BaseType_t xResult; 465 | Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); 466 | 467 | /* Remove the timer from the list of active timers. A check has already 468 | been performed to ensure the list is not empty. */ 469 | ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); 470 | traceTIMER_EXPIRED( pxTimer ); 471 | 472 | /* If the timer is an auto reload timer then calculate the next 473 | expiry time and re-insert the timer in the list of active timers. */ 474 | if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) 475 | { 476 | /* The timer is inserted into a list using a time relative to anything 477 | other than the current time. It will therefore be inserted into the 478 | correct list relative to the time this task thinks it is now. */ 479 | if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) != pdFALSE ) 480 | { 481 | /* The timer expired before it was added to the active timer 482 | list. Reload it now. */ 483 | xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); 484 | configASSERT( xResult ); 485 | ( void ) xResult; 486 | } 487 | else 488 | { 489 | mtCOVERAGE_TEST_MARKER(); 490 | } 491 | } 492 | else 493 | { 494 | mtCOVERAGE_TEST_MARKER(); 495 | } 496 | 497 | /* Call the timer callback. */ 498 | pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); 499 | } 500 | /*-----------------------------------------------------------*/ 501 | 502 | static void prvTimerTask( void *pvParameters ) 503 | { 504 | TickType_t xNextExpireTime; 505 | BaseType_t xListWasEmpty; 506 | 507 | /* Just to avoid compiler warnings. */ 508 | ( void ) pvParameters; 509 | 510 | #if( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 ) 511 | { 512 | extern void vApplicationDaemonTaskStartupHook( void ); 513 | 514 | /* Allow the application writer to execute some code in the context of 515 | this task at the point the task starts executing. This is useful if the 516 | application includes initialisation code that would benefit from 517 | executing after the scheduler has been started. */ 518 | vApplicationDaemonTaskStartupHook(); 519 | } 520 | #endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */ 521 | 522 | for( ;; ) 523 | { 524 | /* Query the timers list to see if it contains any timers, and if so, 525 | obtain the time at which the next timer will expire. */ 526 | xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty ); 527 | 528 | /* If a timer has expired, process it. Otherwise, block this task 529 | until either a timer does expire, or a command is received. */ 530 | prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty ); 531 | 532 | /* Empty the command queue. */ 533 | prvProcessReceivedCommands(); 534 | } 535 | } 536 | /*-----------------------------------------------------------*/ 537 | 538 | static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) 539 | { 540 | TickType_t xTimeNow; 541 | BaseType_t xTimerListsWereSwitched; 542 | 543 | vTaskSuspendAll(); 544 | { 545 | /* Obtain the time now to make an assessment as to whether the timer 546 | has expired or not. If obtaining the time causes the lists to switch 547 | then don't process this timer as any timers that remained in the list 548 | when the lists were switched will have been processed within the 549 | prvSampleTimeNow() function. */ 550 | xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); 551 | if( xTimerListsWereSwitched == pdFALSE ) 552 | { 553 | /* The tick count has not overflowed, has the timer expired? */ 554 | if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) 555 | { 556 | ( void ) xTaskResumeAll(); 557 | prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); 558 | } 559 | else 560 | { 561 | /* The tick count has not overflowed, and the next expire 562 | time has not been reached yet. This task should therefore 563 | block to wait for the next expire time or a command to be 564 | received - whichever comes first. The following line cannot 565 | be reached unless xNextExpireTime > xTimeNow, except in the 566 | case when the current timer list is empty. */ 567 | if( xListWasEmpty != pdFALSE ) 568 | { 569 | /* The current timer list is empty - is the overflow list 570 | also empty? */ 571 | xListWasEmpty = listLIST_IS_EMPTY( pxOverflowTimerList ); 572 | } 573 | 574 | vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ), xListWasEmpty ); 575 | 576 | if( xTaskResumeAll() == pdFALSE ) 577 | { 578 | /* Yield to wait for either a command to arrive, or the 579 | block time to expire. If a command arrived between the 580 | critical section being exited and this yield then the yield 581 | will not cause the task to block. */ 582 | portYIELD_WITHIN_API(); 583 | } 584 | else 585 | { 586 | mtCOVERAGE_TEST_MARKER(); 587 | } 588 | } 589 | } 590 | else 591 | { 592 | ( void ) xTaskResumeAll(); 593 | } 594 | } 595 | } 596 | /*-----------------------------------------------------------*/ 597 | 598 | static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) 599 | { 600 | TickType_t xNextExpireTime; 601 | 602 | /* Timers are listed in expiry time order, with the head of the list 603 | referencing the task that will expire first. Obtain the time at which 604 | the timer with the nearest expiry time will expire. If there are no 605 | active timers then just set the next expire time to 0. That will cause 606 | this task to unblock when the tick count overflows, at which point the 607 | timer lists will be switched and the next expiry time can be 608 | re-assessed. */ 609 | *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); 610 | if( *pxListWasEmpty == pdFALSE ) 611 | { 612 | xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); 613 | } 614 | else 615 | { 616 | /* Ensure the task unblocks when the tick count rolls over. */ 617 | xNextExpireTime = ( TickType_t ) 0U; 618 | } 619 | 620 | return xNextExpireTime; 621 | } 622 | /*-----------------------------------------------------------*/ 623 | 624 | static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) 625 | { 626 | TickType_t xTimeNow; 627 | PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U; /*lint !e956 Variable is only accessible to one task. */ 628 | 629 | xTimeNow = xTaskGetTickCount(); 630 | 631 | if( xTimeNow < xLastTime ) 632 | { 633 | prvSwitchTimerLists(); 634 | *pxTimerListsWereSwitched = pdTRUE; 635 | } 636 | else 637 | { 638 | *pxTimerListsWereSwitched = pdFALSE; 639 | } 640 | 641 | xLastTime = xTimeNow; 642 | 643 | return xTimeNow; 644 | } 645 | /*-----------------------------------------------------------*/ 646 | 647 | static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) 648 | { 649 | BaseType_t xProcessTimerNow = pdFALSE; 650 | 651 | listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); 652 | listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); 653 | 654 | if( xNextExpiryTime <= xTimeNow ) 655 | { 656 | /* Has the expiry time elapsed between the command to start/reset a 657 | timer was issued, and the time the command was processed? */ 658 | if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ 659 | { 660 | /* The time between a command being issued and the command being 661 | processed actually exceeds the timers period. */ 662 | xProcessTimerNow = pdTRUE; 663 | } 664 | else 665 | { 666 | vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); 667 | } 668 | } 669 | else 670 | { 671 | if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) 672 | { 673 | /* If, since the command was issued, the tick count has overflowed 674 | but the expiry time has not, then the timer must have already passed 675 | its expiry time and should be processed immediately. */ 676 | xProcessTimerNow = pdTRUE; 677 | } 678 | else 679 | { 680 | vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); 681 | } 682 | } 683 | 684 | return xProcessTimerNow; 685 | } 686 | /*-----------------------------------------------------------*/ 687 | 688 | static void prvProcessReceivedCommands( void ) 689 | { 690 | DaemonTaskMessage_t xMessage; 691 | Timer_t *pxTimer; 692 | BaseType_t xTimerListsWereSwitched, xResult; 693 | TickType_t xTimeNow; 694 | 695 | while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */ 696 | { 697 | #if ( INCLUDE_xTimerPendFunctionCall == 1 ) 698 | { 699 | /* Negative commands are pended function calls rather than timer 700 | commands. */ 701 | if( xMessage.xMessageID < ( BaseType_t ) 0 ) 702 | { 703 | const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters ); 704 | 705 | /* The timer uses the xCallbackParameters member to request a 706 | callback be executed. Check the callback is not NULL. */ 707 | configASSERT( pxCallback ); 708 | 709 | /* Call the function. */ 710 | pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 ); 711 | } 712 | else 713 | { 714 | mtCOVERAGE_TEST_MARKER(); 715 | } 716 | } 717 | #endif /* INCLUDE_xTimerPendFunctionCall */ 718 | 719 | /* Commands that are positive are timer commands rather than pended 720 | function calls. */ 721 | if( xMessage.xMessageID >= ( BaseType_t ) 0 ) 722 | { 723 | /* The messages uses the xTimerParameters member to work on a 724 | software timer. */ 725 | pxTimer = xMessage.u.xTimerParameters.pxTimer; 726 | 727 | if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */ 728 | { 729 | /* The timer is in a list, remove it. */ 730 | ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); 731 | } 732 | else 733 | { 734 | mtCOVERAGE_TEST_MARKER(); 735 | } 736 | 737 | traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue ); 738 | 739 | /* In this case the xTimerListsWereSwitched parameter is not used, but 740 | it must be present in the function call. prvSampleTimeNow() must be 741 | called after the message is received from xTimerQueue so there is no 742 | possibility of a higher priority task adding a message to the message 743 | queue with a time that is ahead of the timer daemon task (because it 744 | pre-empted the timer daemon task after the xTimeNow value was set). */ 745 | xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); 746 | 747 | switch( xMessage.xMessageID ) 748 | { 749 | case tmrCOMMAND_START : 750 | case tmrCOMMAND_START_FROM_ISR : 751 | case tmrCOMMAND_RESET : 752 | case tmrCOMMAND_RESET_FROM_ISR : 753 | case tmrCOMMAND_START_DONT_TRACE : 754 | /* Start or restart a timer. */ 755 | if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE ) 756 | { 757 | /* The timer expired before it was added to the active 758 | timer list. Process it now. */ 759 | pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); 760 | traceTIMER_EXPIRED( pxTimer ); 761 | 762 | if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) 763 | { 764 | xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); 765 | configASSERT( xResult ); 766 | ( void ) xResult; 767 | } 768 | else 769 | { 770 | mtCOVERAGE_TEST_MARKER(); 771 | } 772 | } 773 | else 774 | { 775 | mtCOVERAGE_TEST_MARKER(); 776 | } 777 | break; 778 | 779 | case tmrCOMMAND_STOP : 780 | case tmrCOMMAND_STOP_FROM_ISR : 781 | /* The timer has already been removed from the active list. 782 | There is nothing to do here. */ 783 | break; 784 | 785 | case tmrCOMMAND_CHANGE_PERIOD : 786 | case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR : 787 | pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue; 788 | configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); 789 | 790 | /* The new period does not really have a reference, and can 791 | be longer or shorter than the old one. The command time is 792 | therefore set to the current time, and as the period cannot 793 | be zero the next expiry time can only be in the future, 794 | meaning (unlike for the xTimerStart() case above) there is 795 | no fail case that needs to be handled here. */ 796 | ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); 797 | break; 798 | 799 | case tmrCOMMAND_DELETE : 800 | /* The timer has already been removed from the active list, 801 | just free up the memory if the memory was dynamically 802 | allocated. */ 803 | #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) 804 | { 805 | /* The timer can only have been allocated dynamically - 806 | free it again. */ 807 | vPortFree( pxTimer ); 808 | } 809 | #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) 810 | { 811 | /* The timer could have been allocated statically or 812 | dynamically, so check before attempting to free the 813 | memory. */ 814 | if( pxTimer->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) 815 | { 816 | vPortFree( pxTimer ); 817 | } 818 | else 819 | { 820 | mtCOVERAGE_TEST_MARKER(); 821 | } 822 | } 823 | #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ 824 | break; 825 | 826 | default : 827 | /* Don't expect to get here. */ 828 | break; 829 | } 830 | } 831 | } 832 | } 833 | /*-----------------------------------------------------------*/ 834 | 835 | static void prvSwitchTimerLists( void ) 836 | { 837 | TickType_t xNextExpireTime, xReloadTime; 838 | List_t *pxTemp; 839 | Timer_t *pxTimer; 840 | BaseType_t xResult; 841 | 842 | /* The tick count has overflowed. The timer lists must be switched. 843 | If there are any timers still referenced from the current timer list 844 | then they must have expired and should be processed before the lists 845 | are switched. */ 846 | while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) 847 | { 848 | xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); 849 | 850 | /* Remove the timer from the list. */ 851 | pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); 852 | ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); 853 | traceTIMER_EXPIRED( pxTimer ); 854 | 855 | /* Execute its callback, then send a command to restart the timer if 856 | it is an auto-reload timer. It cannot be restarted here as the lists 857 | have not yet been switched. */ 858 | pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); 859 | 860 | if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) 861 | { 862 | /* Calculate the reload value, and if the reload value results in 863 | the timer going into the same timer list then it has already expired 864 | and the timer should be re-inserted into the current list so it is 865 | processed again within this loop. Otherwise a command should be sent 866 | to restart the timer to ensure it is only inserted into a list after 867 | the lists have been swapped. */ 868 | xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ); 869 | if( xReloadTime > xNextExpireTime ) 870 | { 871 | listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime ); 872 | listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); 873 | vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); 874 | } 875 | else 876 | { 877 | xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); 878 | configASSERT( xResult ); 879 | ( void ) xResult; 880 | } 881 | } 882 | else 883 | { 884 | mtCOVERAGE_TEST_MARKER(); 885 | } 886 | } 887 | 888 | pxTemp = pxCurrentTimerList; 889 | pxCurrentTimerList = pxOverflowTimerList; 890 | pxOverflowTimerList = pxTemp; 891 | } 892 | /*-----------------------------------------------------------*/ 893 | 894 | static void prvCheckForValidListAndQueue( void ) 895 | { 896 | /* Check that the list from which active timers are referenced, and the 897 | queue used to communicate with the timer service, have been 898 | initialised. */ 899 | taskENTER_CRITICAL(); 900 | { 901 | if( xTimerQueue == NULL ) 902 | { 903 | vListInitialise( &xActiveTimerList1 ); 904 | vListInitialise( &xActiveTimerList2 ); 905 | pxCurrentTimerList = &xActiveTimerList1; 906 | pxOverflowTimerList = &xActiveTimerList2; 907 | 908 | #if( configSUPPORT_STATIC_ALLOCATION == 1 ) 909 | { 910 | /* The timer queue is allocated statically in case 911 | configSUPPORT_DYNAMIC_ALLOCATION is 0. */ 912 | static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ 913 | static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ 914 | 915 | xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue ); 916 | } 917 | #else 918 | { 919 | xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) ); 920 | } 921 | #endif 922 | 923 | #if ( configQUEUE_REGISTRY_SIZE > 0 ) 924 | { 925 | if( xTimerQueue != NULL ) 926 | { 927 | vQueueAddToRegistry( xTimerQueue, "TmrQ" ); 928 | } 929 | else 930 | { 931 | mtCOVERAGE_TEST_MARKER(); 932 | } 933 | } 934 | #endif /* configQUEUE_REGISTRY_SIZE */ 935 | } 936 | else 937 | { 938 | mtCOVERAGE_TEST_MARKER(); 939 | } 940 | } 941 | taskEXIT_CRITICAL(); 942 | } 943 | /*-----------------------------------------------------------*/ 944 | 945 | BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) 946 | { 947 | BaseType_t xTimerIsInActiveList; 948 | Timer_t *pxTimer = ( Timer_t * ) xTimer; 949 | 950 | configASSERT( xTimer ); 951 | 952 | /* Is the timer in the list of active timers? */ 953 | taskENTER_CRITICAL(); 954 | { 955 | /* Checking to see if it is in the NULL list in effect checks to see if 956 | it is referenced from either the current or the overflow timer lists in 957 | one go, but the logic has to be reversed, hence the '!'. */ 958 | xTimerIsInActiveList = ( BaseType_t ) !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) ); /*lint !e961. Cast is only redundant when NULL is passed into the macro. */ 959 | } 960 | taskEXIT_CRITICAL(); 961 | 962 | return xTimerIsInActiveList; 963 | } /*lint !e818 Can't be pointer to const due to the typedef. */ 964 | /*-----------------------------------------------------------*/ 965 | 966 | void *pvTimerGetTimerID( const TimerHandle_t xTimer ) 967 | { 968 | Timer_t * const pxTimer = ( Timer_t * ) xTimer; 969 | void *pvReturn; 970 | 971 | configASSERT( xTimer ); 972 | 973 | taskENTER_CRITICAL(); 974 | { 975 | pvReturn = pxTimer->pvTimerID; 976 | } 977 | taskEXIT_CRITICAL(); 978 | 979 | return pvReturn; 980 | } 981 | /*-----------------------------------------------------------*/ 982 | 983 | void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) 984 | { 985 | Timer_t * const pxTimer = ( Timer_t * ) xTimer; 986 | 987 | configASSERT( xTimer ); 988 | 989 | taskENTER_CRITICAL(); 990 | { 991 | pxTimer->pvTimerID = pvNewID; 992 | } 993 | taskEXIT_CRITICAL(); 994 | } 995 | /*-----------------------------------------------------------*/ 996 | 997 | #if( INCLUDE_xTimerPendFunctionCall == 1 ) 998 | 999 | BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) 1000 | { 1001 | DaemonTaskMessage_t xMessage; 1002 | BaseType_t xReturn; 1003 | 1004 | /* Complete the message with the function parameters and post it to the 1005 | daemon task. */ 1006 | xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR; 1007 | xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; 1008 | xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; 1009 | xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; 1010 | 1011 | xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); 1012 | 1013 | tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); 1014 | 1015 | return xReturn; 1016 | } 1017 | 1018 | #endif /* INCLUDE_xTimerPendFunctionCall */ 1019 | /*-----------------------------------------------------------*/ 1020 | 1021 | #if( INCLUDE_xTimerPendFunctionCall == 1 ) 1022 | 1023 | BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) 1024 | { 1025 | DaemonTaskMessage_t xMessage; 1026 | BaseType_t xReturn; 1027 | 1028 | /* This function can only be called after a timer has been created or 1029 | after the scheduler has been started because, until then, the timer 1030 | queue does not exist. */ 1031 | configASSERT( xTimerQueue ); 1032 | 1033 | /* Complete the message with the function parameters and post it to the 1034 | daemon task. */ 1035 | xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; 1036 | xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; 1037 | xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; 1038 | xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; 1039 | 1040 | xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); 1041 | 1042 | tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); 1043 | 1044 | return xReturn; 1045 | } 1046 | 1047 | #endif /* INCLUDE_xTimerPendFunctionCall */ 1048 | /*-----------------------------------------------------------*/ 1049 | 1050 | #if ( configUSE_TRACE_FACILITY == 1 ) 1051 | 1052 | UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) 1053 | { 1054 | return ( ( Timer_t * ) xTimer )->uxTimerNumber; 1055 | } 1056 | 1057 | #endif /* configUSE_TRACE_FACILITY */ 1058 | /*-----------------------------------------------------------*/ 1059 | 1060 | #if ( configUSE_TRACE_FACILITY == 1 ) 1061 | 1062 | void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) 1063 | { 1064 | ( ( Timer_t * ) xTimer )->uxTimerNumber = uxTimerNumber; 1065 | } 1066 | 1067 | #endif /* configUSE_TRACE_FACILITY */ 1068 | /*-----------------------------------------------------------*/ 1069 | 1070 | /* This entire source file will be skipped if the application is not configured 1071 | to include software timer functionality. If you want to include software timer 1072 | functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ 1073 | #endif /* configUSE_TIMERS == 1 */ 1074 | 1075 | 1076 | 1077 | -------------------------------------------------------------------------------- /License/license.txt: -------------------------------------------------------------------------------- 1 | The FreeRTOS kernel is released under the MIT open source license, the text of 2 | which is provided below. 3 | 4 | This license covers the FreeRTOS kernel source files, which are located in the 5 | /FreeRTOS/Source directory of the official FreeRTOS kernel download. It also 6 | covers most of the source files in the demo application projects, which are 7 | located in the /FreeRTOS/Demo directory of the official FreeRTOS download. The 8 | demo projects may also include third party software that is not part of FreeRTOS 9 | and is licensed separately to FreeRTOS. Examples of third party software 10 | includes header files provided by chip or tools vendors, linker scripts, 11 | peripheral drivers, etc. All the software in subdirectories of the /FreeRTOS 12 | directory is either open source or distributed with permission, and is free for 13 | use. For the avoidance of doubt, refer to the comments at the top of each 14 | source file. 15 | 16 | 17 | License text: 18 | ------------- 19 | 20 | Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 21 | Permission is hereby granted, free of charge, to any person obtaining a copy of 22 | this software and associated documentation files (the "Software"), to deal in 23 | the Software without restriction, including without limitation the rights to 24 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 25 | the Software, and to permit persons to whom the Software is furnished to do so, 26 | subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 33 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 34 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 35 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 36 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 37 | 38 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CROSS ?= aarch64-none-elf 2 | CFLAGS = -mcpu=cortex-a53 -fpic -ffreestanding -std=gnu99 -O2 -Wall -Wextra -I$(INCLUDEPATH1) -I$(INCLUDEPATH2) -I$(INCLUDEPATH3) 3 | ASMFLAGS = -mcpu=cortex-a53 4 | 5 | BUILDPATH = build 6 | INCLUDEPATH1 ?= FreeRTOS/Source/include 7 | INCLUDEPATH2 ?= FreeRTOS/Source/portable/GCC/ARM_CA53_64_RaspberryPi3 8 | INCLUDEPATH3 ?= Demo 9 | 10 | OBJS = build/startup.o 11 | OBJS +=build/FreeRTOS_asm_vector.o 12 | OBJS +=build/FreeRTOS_tick_config.o 13 | OBJS +=build/uart.o 14 | OBJS +=build/main.o 15 | 16 | OBJS +=build/port.o 17 | OBJS +=build/portASM.o 18 | 19 | OBJS +=build/list.o 20 | OBJS +=build/tasks.o 21 | OBJS +=build/queue.o 22 | OBJS +=build/timers.o 23 | 24 | OBJS +=build/heap_1.o 25 | 26 | kernel8.elf : raspberrypi3.ld $(OBJS) 27 | $(CROSS)-gcc -Wl,--build-id=none -std=gnu11 -T raspberrypi3.ld -o $@ -ffreestanding -O2 -nostdlib $(OBJS) 28 | $(CROSS)-objdump -D kernel8.elf > kernel8.list 29 | 30 | build/%.o : Demo/%.S $(BUILDPATH) 31 | $(CROSS)-as $(ASMFLAGS) -c -o $@ $< 32 | 33 | build/%.o : Demo/%.c 34 | $(CROSS)-gcc $(CFLAGS) -c -o $@ $< 35 | 36 | build/%.o : FreeRTOS/Source/%.c 37 | $(CROSS)-gcc $(CFLAGS) -c -o $@ $< 38 | 39 | build/%.o : FreeRTOS/Source/portable/GCC/ARM_CA53_64_RaspberryPi3/%.c 40 | $(CROSS)-gcc $(CFLAGS) -c -o $@ $< 41 | 42 | build/%.o : FreeRTOS/Source/portable/GCC/ARM_CA53_64_RaspberryPi3/%.S 43 | $(CROSS)-as $(ASMFLAGS) -c -o $@ $< 44 | 45 | build/%.o : FreeRTOS/Source/portable/MemMang/%.c 46 | $(CROSS)-gcc $(CFLAGS) -c -o $@ $< 47 | 48 | $(BUILDPATH): 49 | @if [ ! -d $(BUILDPATH) ]; then \ 50 | echo " mkdir $(BUILDPATH)"; mkdir $(BUILDPATH); \ 51 | fi 52 | 53 | clean : 54 | rm -f build/*.o 55 | rm -f *.elf 56 | rm -f *.list 57 | 58 | run : 59 | $(MAKE) kernel8.elf 60 | qemu-system-aarch64 -M raspi3 -m 1024 -serial null -serial mon:stdio -nographic -kernel kernel8.elf 61 | 62 | runasm : 63 | $(MAKE) kernel8.elf 64 | qemu-system-aarch64 -M raspi3 -m 1024 -serial null -serial mon:stdio -nographic -kernel kernel8.elf -d in_asm 65 | 66 | 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | FreeRTOS ported to Raspberry Pi 3 (64bit) 2 | 3 | I have not yte test on real hardware yet. 4 | 5 | I test with QEMU 6.1.0 6 | 7 | # How to Build 8 | 9 | * install aarch64 toolchain. 10 | * make 11 | 12 | # How to run with QEMU 13 | 14 | * make run 15 | ``` 16 | $ make run 17 | qemu-system-aarch64 -M raspi3 -m 1024 -serial null -serial mon:stdio -nographic -kernel kernel8.elf 18 | hello world 19 | 0000000000000001 20 | 00000000000001F6 21 | ``` 22 | 23 | This port based on Xilinx Cortex-A53 port. 24 | 25 | 26 | -------------------------------------------------------------------------------- /raspberrypi3.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_boot) 2 | 3 | SECTIONS 4 | { 5 | /* Starts at LOADER_ADDR. */ 6 | . = 0x80000; 7 | __start = .; 8 | __text_start = .; 9 | .text : 10 | { 11 | KEEP(*(.vectors)) 12 | KEEP(*(.text.boot)) 13 | *(.text) 14 | } 15 | . = ALIGN(4096); /* align to page size */ 16 | __text_end = .; 17 | 18 | __data_start = .; 19 | .data : 20 | { 21 | *(.data) 22 | } 23 | . = ALIGN(4096); /* align to page size */ 24 | __data_end = .; 25 | 26 | __bss_start = .; 27 | .bss : 28 | { 29 | bss = .; 30 | *(.bss) 31 | } 32 | . = ALIGN(4096); /* align to page size */ 33 | __bss_end = .; 34 | __end = .; 35 | } 36 | __bss_size = (__bss_end - __bss_start)>>3; 37 | --------------------------------------------------------------------------------