1 /* 2 * FreeRTOS Kernel V10.6.2 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 30 #ifndef PORTMACRO_H 31 #define PORTMACRO_H 32 33 /* *INDENT-OFF* */ 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 /* *INDENT-ON* */ 38 39 /*----------------------------------------------------------- 40 * Port specific definitions. 41 * 42 * The settings in this file configure FreeRTOS correctly for the 43 * given hardware and compiler. 44 * 45 * These settings should not be altered. 46 *----------------------------------------------------------- 47 */ 48 49 /* Type definitions. */ 50 #define portCHAR char 51 #define portFLOAT float 52 #define portDOUBLE double 53 #define portLONG long 54 #define portSHORT short 55 #define portSTACK_TYPE uint32_t 56 #define portBASE_TYPE long 57 58 typedef portSTACK_TYPE StackType_t; 59 typedef long BaseType_t; 60 typedef unsigned long UBaseType_t; 61 62 #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) 63 typedef uint16_t TickType_t; 64 #define portMAX_DELAY ( TickType_t ) 0xffff 65 #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) 66 typedef uint32_t TickType_t; 67 #define portMAX_DELAY ( TickType_t ) 0xffffffffUL 68 69 /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do 70 * not need to be guarded with a critical section. */ 71 #define portTICK_TYPE_IS_ATOMIC 1 72 #else 73 #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. 74 #endif 75 /*-----------------------------------------------------------*/ 76 77 /* MPU specific constants. */ 78 #define portUSING_MPU_WRAPPERS 1 79 #define portPRIVILEGE_BIT ( 0x80000000UL ) 80 81 #define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL ) 82 #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL ) 83 #define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL ) 84 #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL ) 85 #define portMPU_REGION_PRIVILEGED_READ_WRITE_UNPRIV_READ_ONLY ( 0x02UL << 24UL ) 86 #define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL ) 87 #define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL ) 88 89 #define portGENERAL_PERIPHERALS_REGION ( 3UL ) 90 #define portSTACK_REGION ( 4UL ) 91 #define portUNPRIVILEGED_FLASH_REGION ( 5UL ) 92 #define portPRIVILEGED_FLASH_REGION ( 6UL ) 93 #define portPRIVILEGED_RAM_REGION ( 7UL ) 94 #define portFIRST_CONFIGURABLE_REGION ( 0UL ) 95 #define portLAST_CONFIGURABLE_REGION ( 2UL ) 96 #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) 97 #define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ 98 99 #define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " ::: "r0", "memory" ) 100 101 typedef struct MPU_REGION_REGISTERS 102 { 103 uint32_t ulRegionBaseAddress; 104 uint32_t ulRegionAttribute; 105 } xMPU_REGION_REGISTERS; 106 107 typedef struct MPU_REGION_SETTINGS 108 { 109 uint32_t ulRegionStartAddress; 110 uint32_t ulRegionEndAddress; 111 uint32_t ulRegionPermissions; 112 } xMPU_REGION_SETTINGS; 113 114 #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) 115 116 #ifndef configSYSTEM_CALL_STACK_SIZE 117 #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. 118 #endif 119 120 typedef struct SYSTEM_CALL_STACK_INFO 121 { 122 uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 123 uint32_t * pulSystemCallStack; 124 uint32_t * pulTaskStack; 125 uint32_t ulLinkRegisterAtSystemCallEntry; 126 } xSYSTEM_CALL_STACK_INFO; 127 128 #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ 129 130 #define MAX_CONTEXT_SIZE ( 20 ) 131 132 /* Size of an Access Control List (ACL) entry in bits. */ 133 #define portACL_ENTRY_SIZE_BITS ( 32U ) 134 135 /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ 136 #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) 137 #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) 138 139 typedef struct MPU_SETTINGS 140 { 141 xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; 142 xMPU_REGION_SETTINGS xRegionSettings[ portTOTAL_NUM_REGIONS_IN_TCB ]; 143 uint32_t ulContext[ MAX_CONTEXT_SIZE ]; 144 uint32_t ulTaskFlags; 145 146 #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) 147 xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; 148 #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) 149 uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; 150 #endif 151 #endif 152 } xMPU_SETTINGS; 153 154 /* Architecture specifics. */ 155 #define portSTACK_GROWTH ( -1 ) 156 #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) 157 #define portBYTE_ALIGNMENT 8 158 #define portDONT_DISCARD __attribute__( ( used ) ) 159 /*-----------------------------------------------------------*/ 160 161 /* SVC numbers for various services. */ 162 #define portSVC_START_SCHEDULER 100 163 #define portSVC_YIELD 101 164 #define portSVC_RAISE_PRIVILEGE 102 165 #define portSVC_SYSTEM_CALL_EXIT 103 166 167 /* Scheduler utilities. */ 168 169 #define portYIELD() __asm volatile ( " SVC %0 \n"::"i" ( portSVC_YIELD ) : "memory" ) 170 #define portYIELD_WITHIN_API() \ 171 { \ 172 /* Set a PendSV to request a context switch. */ \ 173 portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ 174 \ 175 /* Barriers are normally not required but do ensure the code is completely \ 176 * within the specified behaviour for the architecture. */ \ 177 __asm volatile ( "dsb" ::: "memory" ); \ 178 __asm volatile ( "isb" ); \ 179 } 180 181 #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) 182 #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) 183 #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 ) 184 #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) 185 /*-----------------------------------------------------------*/ 186 187 /* Critical section management. */ 188 extern void vPortEnterCritical( void ); 189 extern void vPortExitCritical( void ); 190 #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() 191 #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x ) 192 #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() 193 #define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) 194 #define portENTER_CRITICAL() vPortEnterCritical() 195 #define portEXIT_CRITICAL() vPortExitCritical() 196 197 /*-----------------------------------------------------------*/ 198 199 /* Task function macros as described on the FreeRTOS.org WEB site. These are 200 * not necessary for to use this port. They are defined so the common demo files 201 * (which build with all the ports) will build. */ 202 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) 203 #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) 204 /*-----------------------------------------------------------*/ 205 206 /* Architecture specific optimisations. */ 207 #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION 208 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 209 #endif 210 211 #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 212 213 /* Generic helper function. */ ucPortCountLeadingZeros(uint32_t ulBitmap)214 __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) 215 { 216 uint8_t ucReturn; 217 218 __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); 219 220 return ucReturn; 221 } 222 223 /* Check the configuration. */ 224 #if ( configMAX_PRIORITIES > 32 ) 225 #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. 226 #endif 227 228 /* Store/clear the ready priorities in a bit map. */ 229 #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) 230 #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) 231 232 /*-----------------------------------------------------------*/ 233 234 #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) 235 236 #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ 237 238 /*-----------------------------------------------------------*/ 239 240 #ifdef configASSERT 241 void vPortValidateInterruptPriority( void ); 242 #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() 243 #endif 244 245 /* portNOP() is not required by this port. */ 246 #define portNOP() 247 248 #define portINLINE __inline 249 250 #ifndef portFORCE_INLINE 251 #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) 252 #endif 253 /*-----------------------------------------------------------*/ 254 255 extern BaseType_t xIsPrivileged( void ); 256 extern void vResetPrivilege( void ); 257 258 /** 259 * @brief Checks whether or not the processor is privileged. 260 * 261 * @return 1 if the processor is already privileged, 0 otherwise. 262 */ 263 #define portIS_PRIVILEGED() xIsPrivileged() 264 265 /** 266 * @brief Raise an SVC request to raise privilege. 267 */ 268 #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); 269 270 /** 271 * @brief Lowers the privilege level by setting the bit 0 of the CONTROL 272 * register. 273 */ 274 #define portRESET_PRIVILEGE() vResetPrivilege() 275 /*-----------------------------------------------------------*/ 276 277 extern BaseType_t xPortIsTaskPrivileged( void ); 278 279 /** 280 * @brief Checks whether or not the calling task is privileged. 281 * 282 * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. 283 */ 284 #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() 285 /*-----------------------------------------------------------*/ 286 xPortIsInsideInterrupt(void)287 portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) 288 { 289 uint32_t ulCurrentInterrupt; 290 BaseType_t xReturn; 291 292 /* Obtain the number of the currently executing interrupt. */ 293 __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); 294 295 if( ulCurrentInterrupt == 0 ) 296 { 297 xReturn = pdFALSE; 298 } 299 else 300 { 301 xReturn = pdTRUE; 302 } 303 304 return xReturn; 305 } 306 307 /*-----------------------------------------------------------*/ 308 vPortRaiseBASEPRI(void)309 portFORCE_INLINE static void vPortRaiseBASEPRI( void ) 310 { 311 uint32_t ulNewBASEPRI; 312 313 __asm volatile 314 ( 315 " mov %0, %1 \n"\ 316 " msr basepri, %0 \n"\ 317 " isb \n"\ 318 " dsb \n"\ 319 : "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" 320 ); 321 } 322 323 /*-----------------------------------------------------------*/ 324 ulPortRaiseBASEPRI(void)325 portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) 326 { 327 uint32_t ulOriginalBASEPRI, ulNewBASEPRI; 328 329 __asm volatile 330 ( 331 " mrs %0, basepri \n"\ 332 " mov %1, %2 \n"\ 333 " msr basepri, %1 \n"\ 334 " isb \n"\ 335 " dsb \n"\ 336 : "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" 337 ); 338 339 /* This return will not be reached but is necessary to prevent compiler 340 * warnings. */ 341 return ulOriginalBASEPRI; 342 } 343 /*-----------------------------------------------------------*/ 344 vPortSetBASEPRI(uint32_t ulNewMaskValue)345 portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) 346 { 347 __asm volatile 348 ( 349 " msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory" 350 ); 351 } 352 /*-----------------------------------------------------------*/ 353 354 #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) 355 356 #ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 357 #warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. *www.FreeRTOS.org/FreeRTOS-V10.3.x.html" 358 #define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0 359 #endif 360 /*-----------------------------------------------------------*/ 361 362 /* *INDENT-OFF* */ 363 #ifdef __cplusplus 364 } 365 #endif 366 /* *INDENT-ON* */ 367 368 #endif /* PORTMACRO_H */ 369