123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- /*
- * SPDX-FileCopyrightText: 2020 Amazon.com, Inc. or its affiliates
- *
- * SPDX-License-Identifier: MIT
- *
- * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
- */
- /*
- * FreeRTOS Kernel V10.4.3
- * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * 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.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
- #ifndef PORTMACRO_H
- #define PORTMACRO_H
- #ifndef __ASSEMBLER__
- #include "sdkconfig.h"
- #include <stdint.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include <stdio.h>
- #include "spinlock.h"
- #include "soc/interrupt_core0_reg.h"
- #include "esp_macros.h"
- #include "esp_attr.h"
- #include "esp_cpu.h"
- #include "esp_rom_sys.h"
- #include "esp_heap_caps.h"
- #include "esp_system.h" /* required by esp_get_...() functions in portable.h. [refactor-todo] Update portable.h */
- #include "esp_newlib.h"
- #include "rtthread.h"
- /* [refactor-todo] These includes are not directly used in this file. They are kept into to prevent a breaking change. Remove these. */
- #include <limits.h>
- /* [refactor-todo] introduce a port wrapper function to avoid including esp_timer.h into the public header */
- #if CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER
- #include "esp_timer.h"
- #endif
- #ifdef __cplusplus
- extern "C" {
- #endif
- /* --------------------------------------------------- Port Types ------------------------------------------------------
- * - Port specific types.
- * - The settings in this file configure FreeRTOS correctly for the given hardware and compiler.
- * - These settings should not be altered.
- * - The port types must come first as they are used further down in this file
- * ------------------------------------------------------------------------------------------------------------------ */
- #define portCHAR char
- #define portFLOAT float
- #define portDOUBLE double
- #define portLONG long
- #define portSHORT short
- #define portSTACK_TYPE rt_ubase_t
- #define portBASE_TYPE rt_base_t
- typedef portSTACK_TYPE StackType_t;
- typedef rt_base_t BaseType_t;
- typedef rt_ubase_t UBaseType_t;
- typedef rt_tick_t TickType_t;
- #define portMAX_DELAY (TickType_t) RT_TICK_MAX
- struct rt_semaphore_wrapper
- {
- struct rt_semaphore sem;
- rt_uint16_t max_value;
- };
- /* ----------------------------------------------- Port Configurations -------------------------------------------------
- * - Configurations values supplied by each port
- * - Required by FreeRTOS
- * ------------------------------------------------------------------------------------------------------------------ */
- #define portTICK_PERIOD_MS ((TickType_t) (1000 / configTICK_RATE_HZ))
- #define portBYTE_ALIGNMENT RT_ALIGN_SIZE
- #define portNOP() __asm volatile (" nop ")
- /* ---------------------------------------------- Forward Declarations -------------------------------------------------
- * - Forward declarations of all the port functions and macros need to implement the FreeRTOS porting interface
- * - These must come before definition/declaration of the FreeRTOS porting interface
- * ------------------------------------------------------------------------------------------------------------------ */
- // --------------------- Interrupts ------------------------
- /**
- * @brief Checks if the current core is in an ISR context
- *
- * - ISR context consist of Low/Mid priority ISR, or time tick ISR
- * - High priority ISRs aren't detected here, but they normally cannot call C code, so that should not be an issue anyway.
- *
- * @note [refactor-todo] Check if this should be inlined
- * @return
- * - pdTRUE if in ISR
- * - pdFALSE otherwise
- */
- BaseType_t xPortInIsrContext(void);
- /**
- * @brief Check if in ISR context from High priority ISRs
- *
- * - Called from High priority ISR
- * - Checks if the previous context (before high priority interrupt) was in ISR context (meaning low/med priority)
- *
- * @note [refactor-todo] Check if this should be inlined
- * @return
- * - pdTRUE if in previous in ISR context
- * - pdFALSE otherwise
- */
- BaseType_t xPortInterruptedFromISRContext(void);
- /* ---------------------- Spinlocks ------------------------
- - Spinlocks added to match API with SMP FreeRTOS. Single core RISC-V does not need spin locks
- - Because single core does not have a primitive spinlock data type, we have to implement one here
- * @note [refactor-todo] Refactor critical section API so that this is no longer required
- * ------------------------------------------------------ */
- /**
- * @brief Spinlock object
- * Owner:
- * - Set to 0 if uninitialized
- * - Set to portMUX_FREE_VAL when free
- * - Set to CORE_ID_REGVAL_PRO or CORE_ID_REGVAL_AP when locked
- * - Any other value indicates corruption
- * Count:
- * - 0 if unlocked
- * - Recursive count if locked
- *
- * @note Not a true spinlock as single core RISC-V does not have atomic compare and set instruction
- * @note Keep portMUX_INITIALIZER_UNLOCKED in sync with this struct
- */
- typedef struct {
- uint32_t owner;
- uint32_t count;
- } portMUX_TYPE;
- /**< Spinlock initializer */
- #define portMUX_INITIALIZER_UNLOCKED { \
- .owner = portMUX_FREE_VAL, \
- .count = 0, \
- }
- #define portMUX_FREE_VAL SPINLOCK_FREE /**< Spinlock is free. [refactor-todo] check if this is still required */
- #define portMUX_NO_TIMEOUT SPINLOCK_WAIT_FOREVER /**< When passed for 'timeout_cycles', spin forever if necessary. [refactor-todo] check if this is still required */
- #define portMUX_TRY_LOCK SPINLOCK_NO_WAIT /**< Try to acquire the spinlock a single time only. [refactor-todo] check if this is still required */
- #define portMUX_INITIALIZE(mux) ({ \
- (mux)->owner = portMUX_FREE_VAL; \
- (mux)->count = 0; \
- })
- // ------------------ Critical Sections --------------------
- /**
- * @brief Enter a critical section
- *
- * - Simply disable interrupts
- * - Can be nested
- */
- void vPortEnterCritical(void);
- /**
- * @brief Exit a critical section
- *
- * - Reenables interrupts
- * - Can be nested
- */
- void vPortExitCritical(void);
- // ---------------------- Yielding -------------------------
- /**
- * @brief Perform a context switch from a task
- *
- * @note [refactor-todo] The rest of ESP-IDF should call taskYield() instead
- */
- #define vPortYield(void) rt_thread_yield()
- /**
- * @brief Checks if the current core can yield
- *
- * - A core cannot yield if its in an ISR or in a critical section
- *
- * @note [refactor-todo] See if this can be separated from port macro
- * @note [refactor-todo] Check if this function should be renamed (due to bool return type)
- * @return true Core can yield
- * @return false Core cannot yield
- */
- FORCE_INLINE_ATTR bool xPortCanYield(void);
- // ----------------------- System --------------------------
- /**
- * @brief Get the tick rate per second
- *
- * @note [refactor-todo] make this inline
- * @note [refactor-todo] Check if this function should be renamed (due to uint return type)
- * @return uint32_t Tick rate in Hz
- */
- uint32_t xPortGetTickRateHz(void);
- /**
- * @brief Set a watchpoint to watch the last 32 bytes of the stack
- *
- * Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack watchpoint
- * around.
- *
- * @param pxStackStart Pointer to the start of the stack
- */
- void vPortSetStackWatchpoint(void *pxStackStart);
- /**
- * @brief Get the current core's ID
- *
- * @note Added to be compatible with SMP API
- * @note [refactor-todo] IDF should call a FreeRTOS like macro instead of port function directly
- * @return BaseType_t Core ID
- */
- FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void)
- {
- return (BaseType_t) esp_cpu_get_core_id();
- }
- /* ------------------------------------------- FreeRTOS Porting Interface ----------------------------------------------
- * - Contains all the mappings of the macros required by FreeRTOS
- * - Most come after forward declare as porting macros map to declared functions
- * - Maps to forward declared functions
- * ------------------------------------------------------------------------------------------------------------------ */
- // --------------------- Interrupts ------------------------
- #define portDISABLE_INTERRUPTS() vPortEnterCritical()
- #define portENABLE_INTERRUPTS() vPortExitCritical()
- #define portSET_INTERRUPT_MASK_FROM_ISR() rt_hw_interrupt_disable()
- #define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue) rt_hw_interrupt_enable(uxSavedStatusValue)
- // ------------------ Critical Sections --------------------
- #define portENTER_CRITICAL(mux) {(void)mux; vPortEnterCritical();}
- #define portEXIT_CRITICAL(mux) {(void)mux; vPortExitCritical();}
- #define portTRY_ENTER_CRITICAL(mux, timeout) ({ \
- (void)mux; (void)timeout; \
- vPortEnterCritical(); \
- BaseType_t ret = pdPASS; \
- ret; \
- })
- //In single-core RISC-V, we can use the same critical section API
- #define portENTER_CRITICAL_ISR(mux) portENTER_CRITICAL(mux)
- #define portEXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL(mux)
- #define portTRY_ENTER_CRITICAL_ISR(mux, timeout) portTRY_ENTER_CRITICAL(mux, timeout)
- /* [refactor-todo] on RISC-V, both ISR and non-ISR cases result in the same call. We can redefine this macro */
- #define portENTER_CRITICAL_SAFE(mux) ({ \
- if (xPortInIsrContext()) { \
- portENTER_CRITICAL_ISR(mux); \
- } else { \
- portENTER_CRITICAL(mux); \
- } \
- })
- #define portEXIT_CRITICAL_SAFE(mux) ({ \
- if (xPortInIsrContext()) { \
- portEXIT_CRITICAL_ISR(mux); \
- } else { \
- portEXIT_CRITICAL(mux); \
- } \
- })
- #define portTRY_ENTER_CRITICAL_SAFE(mux, timeout) portENTER_CRITICAL_SAFE(mux, timeout)
- // ---------------------- Yielding -------------------------
- #define portYIELD() rt_thread_yield()
- #define portYIELD_FROM_ISR_NO_ARG() rt_thread_yield()
- #define portYIELD_FROM_ISR_ARG(xHigherPriorityTaskWoken) ({ \
- if (xHigherPriorityTaskWoken == pdTRUE) { \
- rt_thread_yield(); \
- } \
- })
- /**
- * @note The macro below could be used when passing a single argument, or without any argument,
- * it was developed to support both usages of portYIELD inside of an ISR. Any other usage form
- * might result in undesired behavior
- */
- #if defined(__cplusplus) && (__cplusplus > 201703L)
- #define portYIELD_FROM_ISR(...) CHOOSE_MACRO_VA_ARG(portYIELD_FROM_ISR_ARG, portYIELD_FROM_ISR_NO_ARG __VA_OPT__(,) __VA_ARGS__)(__VA_ARGS__)
- #else
- #define portYIELD_FROM_ISR(...) CHOOSE_MACRO_VA_ARG(portYIELD_FROM_ISR_ARG, portYIELD_FROM_ISR_NO_ARG, ##__VA_ARGS__)(__VA_ARGS__)
- #endif
- /* --------------------------------------------- Inline Implementations ------------------------------------------------
- * - Implementation of inline functions of the forward declares
- * - Should come after forward declare and FreeRTOS Porting interface, as implementation may use both.
- * - For implementation of non-inlined functions, see port.c, port_common.c, or other assembly files
- * ------------------------------------------------------------------------------------------------------------------ */
- // --------------------- Interrupts ------------------------
- // ---------------------- Yielding -------------------------
- FORCE_INLINE_ATTR bool xPortCanYield(void)
- {
- rt_base_t level = rt_interrupt_get_nest();
- return (level == 0);
- }
- #define FREERTOS_PRIORITY_TO_RTTHREAD(priority) ( configMAX_PRIORITIES - 1 - ( priority ) )
- #define RTTHREAD_PRIORITY_TO_FREERTOS(priority) ( RT_THREAD_PRIORITY_MAX - 1 - ( priority ) )
- /* Use this macro to calculate the buffer size when allocating a queue statically
- * To ensure the buffer can fit the desired number of messages
- */
- #define QUEUE_BUFFER_SIZE( uxQueueLength, uxItemSize ) ( ( RT_ALIGN( uxItemSize, RT_ALIGN_SIZE ) + sizeof( void * ) ) * uxQueueLength )
- BaseType_t rt_err_to_freertos(rt_err_t rt_err);
- #if CONFIG_APPTRACE_SV_ENABLE
- extern int xPortSwitchFlag;
- #define os_task_switch_is_pended(_cpu_) (xPortSwitchFlag)
- #else
- #define os_task_switch_is_pended(_cpu_) (false)
- #endif
- #ifdef __cplusplus
- }
- #endif
- #endif //__ASSEMBLER__
- #endif /* PORTMACRO_H */
|