1 /* 2 * FreeRTOS Kernel V11.1.0 3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 * 5 * SPDX-License-Identifier: MIT 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 * this software and associated documentation files (the "Software"), to deal in 9 * the Software without restriction, including without limitation the rights to 10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 * the Software, and to permit persons to whom the Software is furnished to do so, 12 * subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in all 15 * copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * https://www.FreeRTOS.org 25 * https://github.com/FreeRTOS 26 * 27 */ 28 29 #ifndef PORTMACRO_H 30 #define PORTMACRO_H 31 32 /* *INDENT-OFF* */ 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 /* *INDENT-ON* */ 37 38 /*----------------------------------------------------------- 39 * Port specific definitions. 40 * 41 * The settings in this file configure FreeRTOS correctly for the given hardware 42 * and compiler. 43 * 44 * These settings should not be altered. 45 *----------------------------------------------------------- 46 */ 47 48 /* Type definitions. */ 49 #define portCHAR char 50 #define portFLOAT float 51 #define portDOUBLE double 52 #define portLONG long 53 #define portSHORT short 54 #define portSTACK_TYPE uint32_t 55 #define portBASE_TYPE long 56 57 typedef portSTACK_TYPE StackType_t; 58 typedef long BaseType_t; 59 typedef unsigned long UBaseType_t; 60 61 typedef uint32_t TickType_t; 62 #define portMAX_DELAY ( ( TickType_t ) 0xffffffffUL ) 63 64 /*-----------------------------------------------------------*/ 65 66 /* Hardware specifics. */ 67 #define portSTACK_GROWTH ( -1 ) 68 #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) 69 #define portBYTE_ALIGNMENT 32 70 71 /*-----------------------------------------------------------*/ 72 73 /* Task utilities. */ 74 75 /* The interrupt priority (for vectors 16 to 255) is determined using vector/16. 76 * The quotient is rounded to the nearest integer with 1 being the lowest priority 77 * and 15 is the highest. Therefore the following two interrupts are at the lowest 78 * priority. *NOTE 1* If the yield vector is changed then it must also be changed 79 * in the portYIELD_INTERRUPT definition immediately below. */ 80 #define portAPIC_TIMER_INT_VECTOR ( 0x21 ) 81 #define portAPIC_YIELD_INT_VECTOR ( 0x20 ) 82 83 /* Build yield interrupt instruction. */ 84 #define portYIELD_INTERRUPT "int $0x20" 85 86 /* APIC register addresses. */ 87 #define portAPIC_EOI ( *( ( volatile uint32_t * ) 0xFEE000B0UL ) ) 88 89 /* APIC bit definitions. */ 90 #define portAPIC_ENABLE_BIT ( 1UL << 8UL ) 91 #define portAPIC_TIMER_PERIODIC ( 1UL << 17UL ) 92 #define portAPIC_DISABLE ( 1UL << 16UL ) 93 #define portAPIC_NMI ( 4 << 8 ) 94 #define portAPIC_DIV_16 ( 0x03 ) 95 96 /* Define local API register addresses. */ 97 #define portAPIC_ID_REGISTER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x20UL ) ) ) 98 #define portAPIC_SPURIOUS_INT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xF0UL ) ) ) 99 #define portAPIC_LVT_TIMER ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x320UL ) ) ) 100 #define portAPIC_TIMER_INITIAL_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x380UL ) ) ) 101 #define portAPIC_TIMER_CURRENT_COUNT ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x390UL ) ) ) 102 #define portAPIC_TASK_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x80UL ) ) ) 103 #define portAPIC_LVT_ERROR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x370UL ) ) ) 104 #define portAPIC_ERROR_STATUS ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x280UL ) ) ) 105 #define portAPIC_LDR ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xD0UL ) ) ) 106 #define portAPIC_TMRDIV ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x3E0UL ) ) ) 107 #define portAPIC_LVT_PERF ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x340UL ) ) ) 108 #define portAPIC_LVT_LINT0 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x350UL ) ) ) 109 #define portAPIC_LVT_LINT1 ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0x360UL ) ) ) 110 111 /* Don't yield if inside a critical section - instead hold the yield pending 112 * so it is performed when the critical section is exited. */ 113 #define portYIELD() \ 114 { \ 115 extern volatile uint32_t ulCriticalNesting; \ 116 extern volatile uint32_t ulPortYieldPending; \ 117 if( ulCriticalNesting != 0 ) \ 118 { \ 119 ulPortYieldPending = pdTRUE; \ 120 } \ 121 else \ 122 { \ 123 __asm volatile ( portYIELD_INTERRUPT ); \ 124 } \ 125 } 126 127 /* Called at the end of an ISR that can cause a context switch - pend a yield if 128 * xSwitchRequired is not false. */ 129 #define portEND_SWITCHING_ISR( xSwitchRequired ) \ 130 { \ 131 extern volatile uint32_t ulPortYieldPending; \ 132 if( xSwitchRequired != pdFALSE ) \ 133 { \ 134 ulPortYieldPending = 1; \ 135 } \ 136 } 137 138 /* Same as portEND_SWITCHING_ISR() - take your pick which name to use. */ 139 #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) 140 141 /*----------------------------------------------------------- 142 * Critical section control 143 *----------------------------------------------------------*/ 144 145 /* Critical sections for use in interrupts. */ 146 #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() 147 #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x ) 148 149 extern void vPortEnterCritical( void ); 150 extern void vPortExitCritical( void ); 151 extern uint32_t ulPortSetInterruptMask( void ); 152 extern void vPortClearInterruptMask( uint32_t ulNewMaskValue ); 153 154 /* These macros do not globally disable/enable interrupts. They do mask off 155 * interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ 156 #define portENTER_CRITICAL() vPortEnterCritical() 157 #define portEXIT_CRITICAL() vPortExitCritical() 158 #define portDISABLE_INTERRUPTS() __asm volatile ( "cli" ) 159 #define portENABLE_INTERRUPTS() __asm volatile ( "sti" ) 160 161 /*-----------------------------------------------------------*/ 162 163 /* Task function macros as described on the FreeRTOS.org WEB site. These are 164 * not required for this port but included in case common demo code that uses these 165 * macros is used. */ 166 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) 167 #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) 168 169 /* Architecture specific optimisations. */ 170 #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 171 172 /* Store/clear the ready priorities in a bit map. */ 173 #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \ 174 __asm volatile ( "bsr %1, %0\n\t" \ 175 : "=r" ( uxTopPriority ) : "rm" ( uxReadyPriorities ) : "cc" ) 176 177 #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) 178 #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) 179 180 #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ 181 182 #define portNOP() __asm volatile ( "NOP" ) 183 184 /*----------------------------------------------------------- 185 * Misc 186 *----------------------------------------------------------*/ 187 188 #define portNUM_VECTORS 256 189 #define portMAX_PRIORITY 15 190 typedef void ( * ISR_Handler_t ) ( void ); 191 192 /* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() 193 * before any floating point instructions are executed. */ 194 #ifndef configSUPPORT_FPU 195 #define configSUPPORT_FPU 0 196 #endif 197 198 #if configSUPPORT_FPU == 1 199 void vPortTaskUsesFPU( void ); 200 #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() 201 #endif 202 203 /* See the comments under the configUSE_COMMON_INTERRUPT_ENTRY_POINT definition 204 * below. */ 205 BaseType_t xPortRegisterCInterruptHandler( ISR_Handler_t pxHandler, 206 uint32_t ulVectorNumber ); 207 BaseType_t xPortInstallInterruptHandler( ISR_Handler_t pxHandler, 208 uint32_t ulVectorNumber ); 209 210 #ifndef configAPIC_BASE 211 212 /* configAPIC_BASE_ADDRESS sets the base address of the local APIC. It can 213 * be overridden in FreeRTOSConfig.h should it not be constant. */ 214 #define configAPIC_BASE 0xFEE00000UL 215 #endif 216 217 #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION 218 219 /* The FreeRTOS scheduling algorithm selects the task that will enter the 220 * Running state. configUSE_PORT_OPTIMISED_TASK_SELECTION is used to set how 221 * that is done. 222 * 223 * If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 0 then the task to 224 * enter the Running state is selected using a portable algorithm written in 225 * C. This is the slowest method, but the algorithm does not restrict the 226 * maximum number of unique RTOS task priorities that are available. 227 * 228 * If configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 1 then the task to 229 * enter the Running state is selected using a single assembly instruction. 230 * This is the fastest method, but restricts the maximum number of unique RTOS 231 * task priorities to 32 (the same task priority can be assigned to any number 232 * of RTOS tasks). */ 233 #warning configUSE_PORT_OPTIMISED_TASK_SELECTION was not defined in FreeRTOSConfig.h and has been defaulted to 1 234 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 235 #endif 236 237 #ifndef configUSE_COMMON_INTERRUPT_ENTRY_POINT 238 239 /* There are two ways of implementing interrupt handlers: 240 * 241 * 1) As standard C functions - 242 * 243 * This method can only be used if configUSE_COMMON_INTERRUPT_ENTRY_POINT 244 * is set to 1. The C function is installed using 245 * xPortRegisterCInterruptHandler(). 246 * 247 * This is the simplest of the two methods but incurs a slightly longer 248 * interrupt entry time. 249 * 250 * 2) By using an assembly stub that wraps the handler in the FreeRTOS 251 * portFREERTOS_INTERRUPT_ENTRY and portFREERTOS_INTERRUPT_EXIT macros. 252 * 253 * This method can always be used. It is slightly more complex than 254 * method 1 but benefits from a faster interrupt entry time. */ 255 #warning configUSE_COMMON_INTERRUPT_ENTRY_POINT was not defined in FreeRTOSConfig.h and has been defaulted to 1. 256 #define configUSE_COMMON_INTERRUPT_ENTRY_POINT 1 257 #endif 258 259 #ifndef configISR_STACK_SIZE 260 261 /* Interrupt entry code will switch the stack in use to a dedicated system 262 * stack. 263 * 264 * configISR_STACK_SIZE defines the number of 32-bit values that can be stored 265 * on the system stack, and must be large enough to hold a potentially nested 266 * interrupt stack frame. */ 267 268 #error configISR_STACK_SIZE was not defined in FreeRTOSConfig.h. 269 #endif 270 271 #ifndef configMAX_API_CALL_INTERRUPT_PRIORITY 272 273 /* Interrupt safe FreeRTOS functions (those that end in "FromISR" must not 274 * be called from an interrupt that has a priority above that set by 275 * configMAX_API_CALL_INTERRUPT_PRIORITY. */ 276 #warning configMAX_API_CALL_INTERRUPT_PRIORITY was not defined in FreeRTOSConfig.h and has been defaulted to 10 277 #define configMAX_API_CALL_INTERRUPT_PRIORITY 10 278 #endif 279 280 #ifndef configSUPPORT_FPU 281 #warning configSUPPORT_FPU was not defined in FreeRTOSConfig.h and has been defaulted to 0 282 #define configSUPPORT_FPU 0 283 #endif 284 285 /* The value written to the task priority register to raise the interrupt mask 286 * to the maximum from which FreeRTOS API calls can be made. */ 287 #define portAPIC_PRIORITY_SHIFT ( 4UL ) 288 #define portAPIC_MAX_SUB_PRIORITY ( 0x0fUL ) 289 #define portMAX_API_CALL_PRIORITY ( ( configMAX_API_CALL_INTERRUPT_PRIORITY << portAPIC_PRIORITY_SHIFT ) | portAPIC_MAX_SUB_PRIORITY ) 290 291 /* Asserts if interrupt safe FreeRTOS functions are called from a priority 292 * above the max system call interrupt priority. */ 293 #define portAPIC_PROCESSOR_PRIORITY ( *( ( volatile uint32_t * ) ( configAPIC_BASE + 0xA0UL ) ) ) 294 #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( ( portAPIC_PROCESSOR_PRIORITY ) <= ( portMAX_API_CALL_PRIORITY ) ) 295 296 /* *INDENT-OFF* */ 297 #ifdef __cplusplus 298 } 299 #endif 300 /* *INDENT-ON* */ 301 302 #endif /* PORTMACRO_H */ 303