| /* |
| * FreeRTOS Kernel <DEVELOPMENT BRANCH> |
| * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| * |
| * SPDX-License-Identifier: MIT |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy of |
| * this software and associated documentation files (the "Software"), to deal in |
| * the Software without restriction, including without limitation the rights to |
| * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
| * the Software, and to permit persons to whom the Software is furnished to do so, |
| * subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in all |
| * copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
| * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
| * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
| * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| * |
| * https://www.FreeRTOS.org |
| * https://github.com/FreeRTOS |
| * |
| */ |
| |
| #ifndef PORTMACRO_H |
| #define PORTMACRO_H |
| |
| /** |
| * @brief Functions, Defines, and Structs for use in the ARM_CRx_MPU FreeRTOS-Port |
| * @file portmacro.h |
| * @note The settings in this file configure FreeRTOS correctly for the given |
| * hardware and compiler. These settings should not be altered. |
| */ |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /* Include stdint for integer types of specific bit widths. */ |
| #include <stdint.h> |
| |
| /* ------------------------------ FreeRTOS Config Check ------------------------------ */ |
| |
| #ifndef configSYSTEM_CALL_STACK_SIZE |
| #error "Define configSYSTEM_CALL_STACK_SIZE to a length, in bytes, " \ |
| "to use when an unprivileged task makes a FreeRTOS Kernel call. " |
| #endif /* configSYSTEM_CALL_STACK_SIZE */ |
| |
| #if( configUSE_MPU_WRAPPERS_V1 == 1 ) |
| #error This port is usable with MPU wrappers V2 only. |
| #endif /* configUSE_MPU_WRAPPERS_V1 */ |
| |
| #ifndef configSETUP_TICK_INTERRUPT |
| #error "configSETUP_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h " \ |
| "to call the function that sets up the tick interrupt." |
| #endif /* configSETUP_TICK_INTERRUPT */ |
| |
| /* ----------------------------------------------------------------------------------- */ |
| |
| #if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) |
| |
| /* Check the configuration. */ |
| #if( configMAX_PRIORITIES > 32 ) |
| #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." |
| #endif /* ( configMAX_PRIORITIES > 32 ) */ |
| |
| /** |
| * @brief Mark that a task of the given priority is ready. |
| * |
| * @ingroup Scheduler |
| * |
| * @param[in] uxPriority Priority of the task that is ready. |
| * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities. |
| */ |
| #define portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \ |
| ( uxTopReadyPriority ) |= ( 1UL << ( uxPriority ) ) |
| |
| /** |
| * @brief Mark that a task of the given priority is no longer ready. |
| * |
| * @ingroup Scheduler |
| * |
| * @param[in] uxPriority Priority of the task that is no longer ready. |
| * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities. |
| */ |
| #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \ |
| ( uxTopReadyPriority ) &= ~( 1UL << ( uxPriority ) ) |
| |
| /** |
| * @brief Determine the highest priority ready task's priority. |
| * |
| * @ingroup Scheduler |
| * |
| * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities. |
| * @param[in] uxTopPriority The highest priority ready task's priority. |
| */ |
| #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ) \ |
| ( uxTopPriority ) = ( 31UL - ulPortCountLeadingZeros( ( uxTopReadyPriority ) ) ) |
| |
| #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ |
| |
| /* ------------------------------ Port Type Definitions ------------------------------ */ |
| |
| #include "portmacro_asm.h" |
| |
| /** |
| * @brief Critical section nesting value. |
| * |
| * @ingroup Critical Sections |
| * |
| * @note A task exits critical section and enables IRQs when its nesting count |
| * reaches this value. |
| */ |
| #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0x0 ) |
| |
| /** |
| * @brief Bit in Current Program Status Register (CPSR) to indicate that CPU is |
| * in Thumb State. |
| * |
| * @ingroup Task Context |
| */ |
| #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) |
| |
| /** |
| * @brief Bitmask to check if an address is of Thumb Code. |
| * |
| * @ingroup Task Context |
| */ |
| #define portTHUMB_MODE_ADDRESS ( 0x01UL ) |
| |
| /** |
| * @brief Data type used to represent a stack word. |
| * |
| * @ingroup Port Interface Specifications |
| */ |
| typedef uint32_t StackType_t; |
| |
| /** |
| * @brief Signed data type equal to the data word operating size of the CPU. |
| * |
| * @ingroup Port Interface Specifications |
| */ |
| typedef int32_t BaseType_t; |
| |
| /** |
| * @brief Unsigned data type equal to the data word operating size of the CPU. |
| * |
| * @ingroup Port Interface Specifications |
| */ |
| typedef uint32_t UBaseType_t; |
| |
| /** |
| * @brief Data type used for the FreeRTOS Tick Counter. |
| * |
| * @note Using 32-bit tick type on a 32-bit architecture ensures that reads of |
| * the tick count do not need to be guarded with a critical section. |
| */ |
| typedef uint32_t TickType_t; |
| |
| /** |
| * @brief Marks the direction the stack grows on the targeted CPU. |
| * |
| * @ingroup Port Interface Specifications |
| */ |
| #define portSTACK_GROWTH ( -1 ) |
| |
| /** |
| * @brief Specifies stack pointer alignment requirements of the target CPU. |
| * |
| * @ingroup Port Interface Specifications |
| */ |
| #define portBYTE_ALIGNMENT 8U |
| |
| /** |
| * @brief Task function prototype macro as described on FreeRTOS.org. |
| * |
| * @ingroup Port Interface Specifications |
| * |
| * @note This is not required for this port but included in case common demo |
| * code uses it. |
| */ |
| #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \ |
| void vFunction( void * pvParameters ) |
| |
| /** |
| * @brief Task function prototype macro as described on FreeRTOS.org. |
| * |
| * @ingroup Port Interface Specifications |
| * |
| * @note This is not required for this port but included in case common demo |
| * code uses it. |
| */ |
| #define portTASK_FUNCTION( vFunction, pvParameters ) \ |
| void vFunction( void * pvParameters ) |
| |
| /** |
| * @brief The no-op ARM assembly instruction. |
| * |
| * @ingroup Port Interface Specifications |
| */ |
| #define portNOP() __asm volatile( "NOP" ) |
| |
| /** |
| * @brief The inline GCC label. |
| * |
| * @ingroup Port Interface Specifications |
| */ |
| #define portINLINE __inline |
| |
| /** |
| * @brief The memory access synchronization barrier. |
| * |
| * @ingroup Port Interface Specifications |
| */ |
| #define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) |
| |
| /** |
| * @brief Ensure a symbol isn't removed from the compilation unit. |
| * |
| * @ingroup Port Interface Specifications |
| */ |
| #define portDONT_DISCARD __attribute__( ( used ) ) |
| |
| /** |
| * @brief Defines if the tick count can be accessed atomically. |
| * |
| * @ingroup System Clock |
| */ |
| #define portTICK_TYPE_IS_ATOMIC 1 |
| |
| /** |
| * @brief The number of miliseconds between system ticks. |
| * |
| * @ingroup System Clock |
| */ |
| #define portTICK_PERIOD_MS ( ( TickType_t ) 1000UL / configTICK_RATE_HZ ) |
| |
| /** |
| * @brief The largest possible delay value for any FreeRTOS API. |
| * |
| * @ingroup System Clock |
| */ |
| #define portMAX_DELAY ( TickType_t ) 0xFFFFFFFFUL |
| |
| /* ----------------------------- Port Assembly Functions ----------------------------- */ |
| |
| /** |
| * @brief FreeRTOS Supervisor Call (SVC) Handler. |
| * |
| * @ingroup Scheduler |
| */ |
| void FreeRTOS_SVC_Handler( void ); |
| |
| /** |
| * @brief FreeRTOS Interrupt Handler. |
| * |
| * @ingroup Scheduler |
| */ |
| void FreeRTOS_IRQ_Handler( void ); |
| |
| /** |
| * @brief Yield the CPU. |
| * |
| * @ingroup Scheduler |
| */ |
| void vPortYield( void ); |
| |
| #define portYIELD() vPortYield() |
| |
| /** |
| * @brief Enable interrupts. |
| * |
| * @ingroup Interrupt Management |
| */ |
| void vPortEnableInterrupts( void ); |
| |
| #define portENABLE_INTERRUPTS() vPortEnableInterrupts() |
| |
| /** |
| * @brief Disable interrupts. |
| * |
| * @ingroup Interrupt Management |
| */ |
| void vPortDisableInterrupts( void ); |
| |
| #define portDISABLE_INTERRUPTS() vPortDisableInterrupts() |
| |
| /** |
| * @brief Exit from a FreeRTO System Call. |
| * |
| * @ingroup Port Privilege |
| */ |
| void vPortSystemCallExit( void ); |
| |
| /** |
| * @brief Start executing first task. |
| * |
| * @ingroup Scheduler |
| */ |
| void vPortStartFirstTask( void ); |
| |
| /** |
| * @brief Enable the onboard MPU. |
| * |
| * @ingroup MPU Control |
| */ |
| void vMPUEnable( void ); |
| |
| /** |
| * @brief Disable the onboard MPU. |
| * |
| * @ingroup MPU Control |
| */ |
| void vMPUDisable( void ); |
| |
| /** |
| * @brief Enable the MPU Background Region. |
| * |
| * @ingroup MPU Control |
| */ |
| void vMPUEnableBackgroundRegion( void ); |
| |
| /** |
| * @brief Disable the MPU Background Region. |
| * |
| * @ingroup MPU Control |
| */ |
| void vMPUDisableBackgroundRegion( void ); |
| |
| /** |
| * @brief Set permissions for an MPU Region. |
| * |
| * @ingroup MPU Control |
| * |
| * @param[in] ulRegionNumber The MPU Region Number to set permissions for. |
| * @param[in] ulBaseAddress The base address of the MPU Region. |
| * @param[in] ulRegionSize The size of the MPU Region in bytes. |
| * @param[in] ulRegionPermissions The permissions associated with the MPU Region. |
| * |
| * @note This is an internal function and assumes that the inputs to this |
| * function are checked before calling this function. |
| */ |
| void vMPUSetRegion( uint32_t ulRegionNumber, |
| uint32_t ulBaseAddress, |
| uint32_t ulRegionSize, |
| uint32_t ulRegionPermissions ); |
| |
| /* ------------------------------- Port.c Declarations ------------------------------- */ |
| |
| /** |
| * @brief Enter critical section. |
| * |
| * @ingroup Critical Section |
| */ |
| void vPortEnterCritical( void ); |
| |
| #define portENTER_CRITICAL() vPortEnterCritical() |
| |
| /** |
| * @brief Exit critical section. |
| * |
| * @ingroup Critical Section |
| */ |
| void vPortExitCritical( void ); |
| |
| #define portEXIT_CRITICAL() vPortExitCritical() |
| |
| /** |
| * @brief Checks whether or not the processor is privileged. |
| * |
| * @ingroup Port Privilege |
| * |
| * @note The processor privilege level is determined by checking the |
| * mode bits [4:0] of the Current Program Status Register (CPSR). |
| * |
| * @return pdTRUE, if the processer is privileged, pdFALSE otherwise. |
| */ |
| BaseType_t xPortIsPrivileged( void ); |
| |
| #define portIS_PRIVILEGED() xPortIsPrivileged() |
| |
| /** |
| * @brief Checks whether or not a task is privileged. |
| * |
| * @ingroup Port Privilege |
| * |
| * @note A task's privilege level is associated with the task and is different from |
| * the processor's privilege level returned by xPortIsPrivileged. For example, |
| * the processor is privileged when an unprivileged task executes a system call. |
| * |
| * @return pdTRUE if the task is privileged, pdFALSE otherwise. |
| */ |
| BaseType_t xPortIsTaskPrivileged( void ); |
| |
| #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() |
| |
| /** |
| * @brief Default return address for tasks. |
| * |
| * @ingroup Task Context |
| * |
| * @note This function is used as the default return address for tasks if |
| * configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h. |
| */ |
| void prvTaskExitError( void ); |
| |
| #ifdef configTASK_RETURN_ADDRESS |
| #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS |
| #else |
| #define portTASK_RETURN_ADDRESS prvTaskExitError |
| #endif /* configTASK_RETURN_ADDRESS */ |
| |
| /** |
| * @brief Returns the number of leading zeros in a 32 bit variable. |
| * |
| * @param[in] ulBitmap 32-Bit number to count leading zeros in. |
| * |
| * @return The number of leading zeros in ulBitmap. |
| */ |
| UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); |
| |
| /** |
| * @brief End the FreeRTOS scheduler. |
| * |
| * Not implemented on this port. |
| * |
| * @ingroup Scheduler |
| */ |
| void vPortEndScheduler( void ); |
| |
| /* --------------------------------- MPU Definitions --------------------------------- */ |
| |
| /** |
| * @brief Mark that this port utilizes the onboard ARM MPU. |
| * |
| * @ingroup MPU Control |
| */ |
| #define portUSING_MPU_WRAPPERS 1 |
| |
| /** |
| * @brief Used to mark if a task should be created as a privileged task. |
| * |
| * @ingroup Task Context |
| * @ingroup MPU Control |
| * |
| * @note A privileged task is created by performing a bitwise OR of this value and |
| * the task priority. For example, to create a privileged task at priority 2, the |
| * uxPriority parameter should be set to ( 2 | portPRIVILEGE_BIT ). |
| */ |
| #define portPRIVILEGE_BIT ( 0x80000000UL ) |
| |
| /** |
| * @brief Size of an Access Control List (ACL) entry in bits. |
| */ |
| #define portACL_ENTRY_SIZE_BITS ( 32UL ) |
| |
| /** |
| * @brief Structure to hold the MPU Register Values. |
| * |
| * @struct xMPU_REGION_REGISTERS |
| * |
| * @ingroup MPU Control |
| * |
| * @note The ordering of this struct MUST be in sync with the ordering in |
| * portRESTORE_CONTEXT. |
| */ |
| typedef struct MPU_REGION_REGISTERS |
| { |
| uint32_t ulRegionSize; /* Information for MPU Region Size and Enable Register. */ |
| uint32_t ulRegionAttribute; /* Information for MPU Region Access Control Register. */ |
| uint32_t ulRegionBaseAddress; /* Information for MPU Region Base Address Register. */ |
| } xMPU_REGION_REGISTERS; |
| |
| /** |
| * @brief Structure to hold per-task System Call Stack information. |
| * |
| * @struct xSYSTEM_CALL_STACK_INFO |
| * |
| * @ingroup Port Privilege |
| * |
| * @note The ordering of this structure MUST be in sync with the assembly code |
| * of the port. |
| */ |
| typedef struct SYSTEM_CALL_STACK_INFO |
| { |
| uint32_t * pulTaskStackPointer; /**< Stack Pointer of the task when it made a FreeRTOS System Call. */ |
| uint32_t * pulLinkRegisterAtSystemCallEntry; /**< Link Register of the task when it made a FreeRTOS System Call. */ |
| uint32_t * pulSystemCallStackPointer; /**< Stack Pointer to use for executing a FreeRTOS System Call. */ |
| uint32_t * pulSystemCallExitAddress; /**< System call exit address. */ |
| uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; /**< Buffer to be used as stack when performing a FreeRTOS System Call. */ |
| } xSYSTEM_CALL_STACK_INFO; |
| |
| /** |
| * @brief Per-Task MPU settings structure stored in the TCB. |
| * @struct xMPU_SETTINGS |
| * |
| * @ingroup MPU Control |
| * @ingroup Task Context |
| * @ingroup Port Privilege |
| * |
| * @note The ordering of this structure MUST be in sync with the assembly code |
| * of the port. |
| */ |
| typedef struct MPU_SETTINGS |
| { |
| xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; |
| uint32_t ulTaskFlags; |
| xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; |
| uint32_t ulContext[ CONTEXT_SIZE ]; /**< Buffer used to store task context. */ |
| |
| #if( configENABLE_ACCESS_CONTROL_LIST == 1 ) |
| uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE |
| / portACL_ENTRY_SIZE_BITS ) |
| + 1UL ]; |
| #endif |
| } xMPU_SETTINGS; |
| |
| #ifdef __cplusplus |
| } /* extern C */ |
| #endif |
| |
| #endif /* PORTMACRO_H */ |