1 /* 2 * FreeRTOS Kernel V11.1.0 3 * Copyright (C) 2024 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 /** 33 * @brief Functions, Defines, and Structs for use in the ARM_CRx_MPU FreeRTOS-Port 34 * @file portmacro.h 35 * @note The settings in this file configure FreeRTOS correctly for the given 36 * hardware and compiler. These settings should not be altered. 37 */ 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 /* Include stdint for integer types of specific bit widths. */ 44 #include <stdint.h> 45 46 /* ------------------------------ FreeRTOS Config Check ------------------------------ */ 47 48 #ifndef configSYSTEM_CALL_STACK_SIZE 49 #error "Define configSYSTEM_CALL_STACK_SIZE to a length, in bytes, " \ 50 "to use when an unprivileged task makes a FreeRTOS Kernel call. " 51 #endif /* configSYSTEM_CALL_STACK_SIZE */ 52 53 #if( configUSE_MPU_WRAPPERS_V1 == 1 ) 54 #error This port is usable with MPU wrappers V2 only. 55 #endif /* configUSE_MPU_WRAPPERS_V1 */ 56 57 #ifndef configSETUP_TICK_INTERRUPT 58 #error "configSETUP_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h " \ 59 "to call the function that sets up the tick interrupt." 60 #endif /* configSETUP_TICK_INTERRUPT */ 61 62 /* ----------------------------------------------------------------------------------- */ 63 64 #if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) 65 66 /* Check the configuration. */ 67 #if( configMAX_PRIORITIES > 32 ) 68 #error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when " \ 69 "configMAX_PRIORITIES is less than or equal to 32. " \ 70 "It is very rare that a system requires more than 10 to 15 difference " \ 71 "priorities as tasks that share a priority will time slice." 72 #endif /* ( configMAX_PRIORITIES > 32 ) */ 73 74 /** 75 * @brief Mark that a task of the given priority is ready. 76 * 77 * @ingroup Scheduler 78 * 79 * @param[in] uxPriority Priority of the task that is ready. 80 * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities. 81 */ 82 #define portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \ 83 ( uxTopReadyPriority ) |= ( 1UL << ( uxPriority ) ) 84 85 /** 86 * @brief Mark that a task of the given priority is no longer ready. 87 * 88 * @ingroup Scheduler 89 * 90 * @param[in] uxPriority Priority of the task that is no longer ready. 91 * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities. 92 */ 93 #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \ 94 ( uxTopReadyPriority ) &= ~( 1UL << ( uxPriority ) ) 95 96 /** 97 * @brief Determine the highest priority ready task's priority. 98 * 99 * @ingroup Scheduler 100 * 101 * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities. 102 * @param[in] uxTopPriority The highest priority ready task's priority. 103 */ 104 #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ) \ 105 ( uxTopPriority ) = ( 31UL - ulPortCountLeadingZeros( ( uxTopReadyPriority ) ) ) 106 107 #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ 108 109 /* ------------------------------ Port Type Definitions ------------------------------ */ 110 111 #include "portmacro_asm.h" 112 113 /** 114 * @brief Critical section nesting value. 115 * 116 * @ingroup Critical Sections 117 * 118 * @note A task exits critical section and enables IRQs when its nesting count 119 * reaches this value. 120 */ 121 #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0x0 ) 122 123 /** 124 * @brief Bit in Current Program Status Register (CPSR) to indicate that CPU is 125 * in Thumb State. 126 * 127 * @ingroup Task Context 128 */ 129 #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) 130 131 /** 132 * @brief Bitmask to check if an address is of Thumb Code. 133 * 134 * @ingroup Task Context 135 */ 136 #define portTHUMB_MODE_ADDRESS ( 0x01UL ) 137 138 /** 139 * @brief Data type used to represent a stack word. 140 * 141 * @ingroup Port Interface Specifications 142 */ 143 typedef uint32_t StackType_t; 144 145 /** 146 * @brief Signed data type equal to the data word operating size of the CPU. 147 * 148 * @ingroup Port Interface Specifications 149 */ 150 typedef int32_t BaseType_t; 151 152 /** 153 * @brief Unsigned data type equal to the data word operating size of the CPU. 154 * 155 * @ingroup Port Interface Specifications 156 */ 157 typedef uint32_t UBaseType_t; 158 159 /** 160 * @brief Data type used for the FreeRTOS Tick Counter. 161 * 162 * @note Using 32-bit tick type on a 32-bit architecture ensures that reads of 163 * the tick count do not need to be guarded with a critical section. 164 */ 165 typedef uint32_t TickType_t; 166 167 /** 168 * @brief Marks the direction the stack grows on the targeted CPU. 169 * 170 * @ingroup Port Interface Specifications 171 */ 172 #define portSTACK_GROWTH ( -1 ) 173 174 /** 175 * @brief Specifies stack pointer alignment requirements of the target CPU. 176 * 177 * @ingroup Port Interface Specifications 178 */ 179 #define portBYTE_ALIGNMENT 8U 180 181 /** 182 * @brief Task function prototype macro as described on FreeRTOS.org. 183 * 184 * @ingroup Port Interface Specifications 185 * 186 * @note This is not required for this port but included in case common demo 187 * code uses it. 188 */ 189 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \ 190 void vFunction( void * pvParameters ) 191 192 /** 193 * @brief Task function prototype macro as described on FreeRTOS.org. 194 * 195 * @ingroup Port Interface Specifications 196 * 197 * @note This is not required for this port but included in case common demo 198 * code uses it. 199 */ 200 #define portTASK_FUNCTION( vFunction, pvParameters ) \ 201 void vFunction( void * pvParameters ) 202 203 /** 204 * @brief The no-op ARM assembly instruction. 205 * 206 * @ingroup Port Interface Specifications 207 */ 208 #define portNOP() __asm volatile( "NOP" ) 209 210 /** 211 * @brief The inline GCC label. 212 * 213 * @ingroup Port Interface Specifications 214 */ 215 #define portINLINE __inline 216 217 /** 218 * @brief The memory access synchronization barrier. 219 * 220 * @ingroup Port Interface Specifications 221 */ 222 #define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) 223 224 /** 225 * @brief Ensure a symbol isn't removed from the compilation unit. 226 * 227 * @ingroup Port Interface Specifications 228 */ 229 #define portDONT_DISCARD __attribute__( ( used ) ) 230 231 /** 232 * @brief Defines if the tick count can be accessed atomically. 233 * 234 * @ingroup System Clock 235 */ 236 #define portTICK_TYPE_IS_ATOMIC 1 237 238 /** 239 * @brief The number of miliseconds between system ticks. 240 * 241 * @ingroup System Clock 242 */ 243 #define portTICK_PERIOD_MS ( ( TickType_t ) 1000UL / configTICK_RATE_HZ ) 244 245 /** 246 * @brief The largest possible delay value for any FreeRTOS API. 247 * 248 * @ingroup System Clock 249 */ 250 #define portMAX_DELAY ( TickType_t ) 0xFFFFFFFFUL 251 252 /* ----------------------------- Port Assembly Functions ----------------------------- */ 253 254 /** 255 * @brief FreeRTOS Supervisor Call (SVC) Handler. 256 * 257 * @ingroup Scheduler 258 */ 259 void FreeRTOS_SVC_Handler( void ); 260 261 /** 262 * @brief FreeRTOS Interrupt Handler. 263 * 264 * @ingroup Scheduler 265 */ 266 void FreeRTOS_IRQ_Handler( void ); 267 268 /** 269 * @brief Yield the CPU. 270 * 271 * @ingroup Scheduler 272 */ 273 void vPortYield( void ); 274 275 #define portYIELD() vPortYield() 276 277 /** 278 * @brief Enable interrupts. 279 * 280 * @ingroup Interrupt Management 281 */ 282 void vPortEnableInterrupts( void ); 283 284 #define portENABLE_INTERRUPTS() vPortEnableInterrupts() 285 286 /** 287 * @brief Disable interrupts. 288 * 289 * @ingroup Interrupt Management 290 */ 291 void vPortDisableInterrupts( void ); 292 293 #define portDISABLE_INTERRUPTS() vPortDisableInterrupts() 294 295 /** 296 * @brief Exit from a FreeRTO System Call. 297 * 298 * @ingroup Port Privilege 299 */ 300 void vPortSystemCallExit( void ); 301 302 /** 303 * @brief Start executing first task. 304 * 305 * @ingroup Scheduler 306 */ 307 void vPortStartFirstTask( void ); 308 309 /** 310 * @brief Enable the onboard MPU. 311 * 312 * @ingroup MPU Control 313 */ 314 void vMPUEnable( void ); 315 316 /** 317 * @brief Disable the onboard MPU. 318 * 319 * @ingroup MPU Control 320 */ 321 void vMPUDisable( void ); 322 323 /** 324 * @brief Enable the MPU Background Region. 325 * 326 * @ingroup MPU Control 327 */ 328 void vMPUEnableBackgroundRegion( void ); 329 330 /** 331 * @brief Disable the MPU Background Region. 332 * 333 * @ingroup MPU Control 334 */ 335 void vMPUDisableBackgroundRegion( void ); 336 337 /** 338 * @brief Set permissions for an MPU Region. 339 * 340 * @ingroup MPU Control 341 * 342 * @param[in] ulRegionNumber The MPU Region Number to set permissions for. 343 * @param[in] ulBaseAddress The base address of the MPU Region. 344 * @param[in] ulRegionSize The size of the MPU Region in bytes. 345 * @param[in] ulRegionPermissions The permissions associated with the MPU Region. 346 * 347 * @note This is an internal function and assumes that the inputs to this 348 * function are checked before calling this function. 349 */ 350 void vMPUSetRegion( uint32_t ulRegionNumber, 351 uint32_t ulBaseAddress, 352 uint32_t ulRegionSize, 353 uint32_t ulRegionPermissions ); 354 355 /* ------------------------------- Port.c Declarations ------------------------------- */ 356 357 /** 358 * @brief Enter critical section. 359 * 360 * @ingroup Critical Section 361 */ 362 void vPortEnterCritical( void ); 363 364 #define portENTER_CRITICAL() vPortEnterCritical() 365 366 /** 367 * @brief Exit critical section. 368 * 369 * @ingroup Critical Section 370 */ 371 void vPortExitCritical( void ); 372 373 #define portEXIT_CRITICAL() vPortExitCritical() 374 375 /** 376 * @brief Checks whether or not the processor is privileged. 377 * 378 * @ingroup Port Privilege 379 * 380 * @note The processor privilege level is determined by checking the 381 * mode bits [4:0] of the Current Program Status Register (CPSR). 382 * 383 * @return pdTRUE, if the processer is privileged, pdFALSE otherwise. 384 */ 385 BaseType_t xPortIsPrivileged( void ); 386 387 #define portIS_PRIVILEGED() xPortIsPrivileged() 388 389 /** 390 * @brief Checks whether or not a task is privileged. 391 * 392 * @ingroup Port Privilege 393 * 394 * @note A task's privilege level is associated with the task and is different from 395 * the processor's privilege level returned by xPortIsPrivileged. For example, 396 * the processor is privileged when an unprivileged task executes a system call. 397 * 398 * @return pdTRUE if the task is privileged, pdFALSE otherwise. 399 */ 400 BaseType_t xPortIsTaskPrivileged( void ); 401 402 #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() 403 404 /** 405 * @brief Default return address for tasks. 406 * 407 * @ingroup Task Context 408 * 409 * @note This function is used as the default return address for tasks if 410 * configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h. 411 */ 412 void prvTaskExitError( void ); 413 414 #ifdef configTASK_RETURN_ADDRESS 415 #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS 416 #else 417 #define portTASK_RETURN_ADDRESS prvTaskExitError 418 #endif /* configTASK_RETURN_ADDRESS */ 419 420 /** 421 * @brief Returns the number of leading zeros in a 32 bit variable. 422 * 423 * @param[in] ulBitmap 32-Bit number to count leading zeros in. 424 * 425 * @return The number of leading zeros in ulBitmap. 426 */ 427 UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); 428 429 /** 430 * @brief End the FreeRTOS scheduler. 431 * 432 * Not implemented on this port. 433 * 434 * @ingroup Scheduler 435 */ 436 void vPortEndScheduler( void ); 437 438 /* --------------------------------- MPU Definitions --------------------------------- */ 439 440 /** 441 * @brief Mark that this port utilizes the onboard ARM MPU. 442 * 443 * @ingroup MPU Control 444 */ 445 #define portUSING_MPU_WRAPPERS 1 446 447 /** 448 * @brief Used to mark if a task should be created as a privileged task. 449 * 450 * @ingroup Task Context 451 * @ingroup MPU Control 452 * 453 * @note A privileged task is created by performing a bitwise OR of this value and 454 * the task priority. For example, to create a privileged task at priority 2, the 455 * uxPriority parameter should be set to ( 2 | portPRIVILEGE_BIT ). 456 */ 457 #define portPRIVILEGE_BIT ( 0x80000000UL ) 458 459 /** 460 * @brief Size of an Access Control List (ACL) entry in bits. 461 */ 462 #define portACL_ENTRY_SIZE_BITS ( 32UL ) 463 464 /** 465 * @brief Structure to hold the MPU Register Values. 466 * 467 * @struct xMPU_REGION_REGISTERS 468 * 469 * @ingroup MPU Control 470 * 471 * @note The ordering of this struct MUST be in sync with the ordering in 472 * portRESTORE_CONTEXT. 473 */ 474 typedef struct MPU_REGION_REGISTERS 475 { 476 uint32_t ulRegionSize; /* Information for MPU Region Size and Enable Register. */ 477 uint32_t ulRegionAttribute; /* Information for MPU Region Access Control Register. */ 478 uint32_t ulRegionBaseAddress; /* Information for MPU Region Base Address Register. */ 479 } xMPU_REGION_REGISTERS; 480 481 /** 482 * @brief Structure to hold per-task System Call Stack information. 483 * 484 * @struct xSYSTEM_CALL_STACK_INFO 485 * 486 * @ingroup Port Privilege 487 * 488 * @note The ordering of this structure MUST be in sync with the assembly code 489 * of the port. 490 */ 491 typedef struct SYSTEM_CALL_STACK_INFO 492 { 493 uint32_t * pulTaskStackPointer; /**< Stack Pointer of the task when it made a FreeRTOS System Call. */ 494 uint32_t * pulLinkRegisterAtSystemCallEntry; /**< Link Register of the task when it made a FreeRTOS System Call. */ 495 uint32_t * pulSystemCallStackPointer; /**< Stack Pointer to use for executing a FreeRTOS System Call. */ 496 uint32_t * pulSystemCallExitAddress; /**< System call exit address. */ 497 uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; /**< Buffer to be used as stack when performing a FreeRTOS System Call. */ 498 } xSYSTEM_CALL_STACK_INFO; 499 500 /** 501 * @brief Per-Task MPU settings structure stored in the TCB. 502 * @struct xMPU_SETTINGS 503 * 504 * @ingroup MPU Control 505 * @ingroup Task Context 506 * @ingroup Port Privilege 507 * 508 * @note The ordering of this structure MUST be in sync with the assembly code 509 * of the port. 510 */ 511 typedef struct MPU_SETTINGS 512 { 513 xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; 514 uint32_t ulTaskFlags; 515 xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; 516 uint32_t ulContext[ CONTEXT_SIZE ]; /**< Buffer used to store task context. */ 517 518 #if( configENABLE_ACCESS_CONTROL_LIST == 1 ) 519 uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE 520 / portACL_ENTRY_SIZE_BITS ) 521 + 1UL ]; 522 #endif 523 } xMPU_SETTINGS; 524 525 #ifdef __cplusplus 526 } /* extern C */ 527 #endif 528 529 #endif /* PORTMACRO_H */ 530