Skip to content

Commit

Permalink
Merge branch 'feature/freertos_sim' into 'master'
Browse files Browse the repository at this point in the history
FreeRTOS Single Core Simulator PoC

See merge request espressif/esp-idf!19256
  • Loading branch information
0xjakob committed Sep 29, 2022
2 parents 511f1d7 + bfbbd9d commit f33ac0a
Show file tree
Hide file tree
Showing 28 changed files with 1,380 additions and 168 deletions.
17 changes: 9 additions & 8 deletions .gitlab/ci/host-test.yml
Expand Up @@ -380,6 +380,15 @@ test_esp_event:
- idf.py build
- build/test_esp_event_host.elf

test_hello_world_linux_compatible_example:
extends: .host_test_template
script:
- cd ${IDF_PATH}/tools/test_apps/linux_compatible/hello_world_linux_compatible
- idf.py --preview set-target linux
- idf.py build
- timeout 15 build/hello_world.elf > test.log
- grep "Hello world!" test.log

test_esp_timer_cxx:
extends: .host_test_template
script:
Expand Down Expand Up @@ -429,14 +438,6 @@ test_system_cxx:
- idf.py build
- build/test_system_cxx_host.elf

test_linux_example:
extends: .host_test_template
script:
- cd ${IDF_PATH}/examples/build_system/cmake/linux_host_app
- idf.py build
- timeout 5 ./build/linux_host_app.elf >test.log || true
- grep "Restarting" test.log

test_partition_api_host:
extends: .host_test_template
script:
Expand Down
37 changes: 37 additions & 0 deletions components/freertos/CMakeLists.txt
Expand Up @@ -6,6 +6,43 @@ endif()

idf_build_get_property(target IDF_TARGET)

if(${target} STREQUAL "linux")
set(kernel_dir "FreeRTOS-Kernel")
set(srcs
"${kernel_dir}/portable/linux/port.c"
"${kernel_dir}/portable/linux/port_idf.c"
"${kernel_dir}/portable/linux/utils/wait_for_event.c"
"${kernel_dir}/list.c"
"${kernel_dir}/queue.c"
"${kernel_dir}/tasks.c"
"${kernel_dir}/timers.c"
)

set(include_dirs
${kernel_dir}/include
${kernel_dir}/portable/linux/include # For arch-specific FreeRTOSConfig_arch.h in portable/<arch>/include
${kernel_dir}/portable/linux/include/freertos
"esp_additions/include/freertos" # For config via #include "FreeRTOSConfig.h"
"esp_additions/include" # For #include "freertos/task_snapshot.h" and #include "freertos/FreeRTOSConfig.h"
)

set(private_include_dirs
${kernel_dir}/portable/linux
${kernel_dir}/portable/priv_include
${kernel_dir}/include/freertos
.
)

idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS ${include_dirs}
PRIV_INCLUDE_DIRS ${private_include_dirs})

target_compile_definitions(${COMPONENT_LIB} PUBLIC "projCOVERAGE_TEST=0")
target_link_libraries(${COMPONENT_LIB} PUBLIC pthread)

return()
endif()

if(CONFIG_FREERTOS_SMP)
set(ldfragments linker_smp.lf)
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
Expand Down
@@ -1,42 +1,141 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* FreeRTOS Kernel V10.4.6
* Copyright 2020 Cambridge Consultants Ltd.
*
* SPDX-License-Identifier: Apache-2.0
* SPDX-FileCopyrightText: 2020 Cambridge Consultants Ltd.
*
* 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
*/

#pragma once

#include "esp_attr.h"
#include <stdint.h>
#ifndef PORTMACRO_H
#define PORTMACRO_H

#include <limits.h>

#ifdef __cplusplus
extern "C" {
#endif

#define portBYTE_ALIGNMENT 16
#define portTICK_TYPE_IS_ATOMIC 1
/*-----------------------------------------------------------
* Port specific definitions.
*
* The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler.
*
* These settings should not be altered.
*-----------------------------------------------------------
*/

/* Type definitions. */
#define portCHAR uint8_t
#define portFLOAT float
#define portDOUBLE double
#define portLONG int32_t
#define portSHORT int16_t
#define portSTACK_TYPE uint8_t
#define portBASE_TYPE int
// interrupt module will mask interrupt with priority less than threshold
#define RVHAL_EXCM_LEVEL 4

typedef portSTACK_TYPE StackType_t;
typedef portBASE_TYPE BaseType_t;
typedef unsigned portBASE_TYPE UBaseType_t;
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL

typedef int portMUX_TYPE;

#define portTICK_PERIOD_MS ( ( TickType_t ) 1 )
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE unsigned long
#define portBASE_TYPE long
#define portPOINTER_SIZE_TYPE intptr_t

typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;

typedef unsigned long TickType_t;
#define portMAX_DELAY ( TickType_t ) ULONG_MAX

#define portTICK_TYPE_IS_ATOMIC 1

/*-----------------------------------------------------------*/

/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portHAS_STACK_OVERFLOW_CHECKING ( 1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portTICK_RATE_MICROSECONDS ( ( TickType_t ) 1000000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
/*-----------------------------------------------------------*/

/* Scheduler utilities. */
extern void vPortYield( void );

#define portYIELD() vPortYield()

#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) vPortYield()
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/

/* Critical section management. */
extern void vPortDisableInterrupts( void );
extern void vPortEnableInterrupts( void );
#define portSET_INTERRUPT_MASK() ( vPortDisableInterrupts() )
#define portCLEAR_INTERRUPT_MASK() ( vPortEnableInterrupts() )

extern portBASE_TYPE xPortSetInterruptMask( void );
extern void vPortClearInterruptMask( portBASE_TYPE xMask );

extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()
#define portENTER_CRITICAL(mux) {(void)mux; vPortEnterCritical();}
#define portEXIT_CRITICAL(mux) {(void)mux; vPortExitCritical();}
#define portENTER_CRITICAL_ISR(mux) portENTER_CRITICAL(mux)
#define portEXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL(mux)

/*-----------------------------------------------------------*/

extern void vPortThreadDying( void *pxTaskToDelete, volatile BaseType_t *pxPendYield );
extern void vPortCancelThread( void *pxTaskToDelete );
#define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxPendYield ) vPortThreadDying( ( pvTaskToDelete ), ( pxPendYield ) )
#define portCLEAN_UP_TCB( pxTCB ) vPortCancelThread( pxTCB )
/*-----------------------------------------------------------*/

#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/*-----------------------------------------------------------*/

/*
* Tasks run in their own pthreads and context switches between them
* are always a full memory barrier. ISRs are emulated as signals
* which also imply a full memory barrier.
*
* Thus, only a compilier barrier is needed to prevent the compiler
* reordering.
*/
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )

extern unsigned long ulPortGetRunTime( void );
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() /* no-op */
#define portGET_RUN_TIME_COUNTER_VALUE() ulPortGetRunTime()

#ifdef __cplusplus
}
#endif

// We need additional definitions for ESP-IDF code
#include "portmacro_idf.h"

#endif /* PORTMACRO_H */
@@ -0,0 +1,98 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

/*
* This is the "IDF-part" of the POSIX portmacro.
* We need additional definitions for code in ESP-IDF which is kept here to separate the original
* FreeRTOS POSIX port code from the additional IDF POSIX port code.
*/

#pragma once

#include <stdint.h>
#include "sdkconfig.h"
#include "esp_attr.h"
#include "spinlock.h"

#ifdef __cplusplus
extern "C" {
#endif

// TODO: IDF-5983 From esp_task.h, should later be used from there
// or be refactored in IDF (e.g. move esp_task.h to freertos)
// See also configMINIMAL_STACK_SIZE for more information.
#define CONFIG_ESP_MAIN_TASK_STACK_SIZE ( ( unsigned short ) (0x4000 + 40) / sizeof(portSTACK_TYPE) ) // should be in Kconfig again
#define CONFIG_ESP_MAIN_TASK_AFFINITY 0

#define ESP_TASK_PRIO_MAX (configMAX_PRIORITIES)
#define ESP_TASK_PRIO_MIN (0)
#define ESP_TASK_MAIN_PRIO (ESP_TASK_PRIO_MIN + 1)
#define ESP_TASK_MAIN_STACK (CONFIG_ESP_MAIN_TASK_STACK_SIZE)
#define ESP_TASK_MAIN_CORE CONFIG_ESP_MAIN_TASK_AFFINITY

// interrupt module will mask interrupt with priority less than threshold
#define RVHAL_EXCM_LEVEL 4

typedef spinlock_t 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 */

void vPortYieldFromISR(void);
void vPortYieldOtherCore(BaseType_t coreid);

#define portMUX_INITIALIZE(mux) spinlock_initialize(mux) /*< Initialize a spinlock to its unlocked state */

/**
* @brief Get the current core's ID
*
* @note dummy function for freertos simulator, always returns 0.
@ return BaseType_t 0
*/
static inline BaseType_t IRAM_ATTR xPortGetCoreID(void)
{
return (BaseType_t) 0;
}

static inline bool portVALID_TCB_MEM(const void *ptr)
{
return true;
}

static inline bool portVALID_STACK_MEM(const void *ptr)
{
return true;
}

#define pvPortMallocTcbMem(size) pvPortMalloc(size)
#define pvPortMallocStackMem(size) pvPortMalloc(size)

BaseType_t xPortCheckIfInISR(void);

/**
* @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
*/
static inline BaseType_t xPortInIsrContext(void)
{
//Just call the FreeRTOS port interface version
return xPortCheckIfInISR();
}

#ifdef __cplusplus
}
#endif

0 comments on commit f33ac0a

Please sign in to comment.