freertos: Add RISC-V port

Changes come from internal branch commit a6723fc
This commit is contained in:
Angus Gratton 2020-11-06 15:03:21 +11:00
parent fccab8f4ef
commit 87e13baaf1
47 changed files with 1368 additions and 220 deletions

View File

@ -4,16 +4,49 @@ if(BOOTLOADER_BUILD)
return() return()
endif() endif()
set(srcs idf_build_get_property(target IDF_TARGET)
"xtensa/port.c"
"xtensa/portasm.S" if(NOT "${target}" STREQUAL "esp32c3") # should test arch here not target, TODO ESP32-C3 IDF-1754
"xtensa/xtensa_context.S" set(srcs
"xtensa/xtensa_init.c" "port/xtensa/port.c"
"xtensa/xtensa_overlay_os_hook.c" "port/xtensa/portasm.S"
"xtensa/xtensa_vector_defaults.S" "port/xtensa/xtensa_context.S"
"xtensa/xtensa_vectors.S") "port/xtensa/xtensa_init.c"
"port/xtensa/xtensa_overlay_os_hook.c"
"port/xtensa/xtensa_vector_defaults.S"
"port/xtensa/xtensa_vectors.S")
set(include_dirs
include
port/xtensa/include)
set(private_include_dirs
include/freertos
port/xtensa/include/freertos
port/xtensa
.)
set(required_components app_trace esp_timer)
else() # RISC-V
set(srcs
"port/riscv/port.c"
"port/riscv/portasm.S")
set(include_dirs
include
port/riscv/include)
set(private_include_dirs
include/freertos
port/riscv/include/freertos
port/riscv
.)
set(required_components esp_timer)
endif()
list(APPEND srcs list(APPEND srcs
"port/port_common.c"
"croutine.c" "croutine.c"
"event_groups.c" "event_groups.c"
"list.c" "list.c"
@ -23,19 +56,9 @@ list(APPEND srcs
"stream_buffer.c" "stream_buffer.c"
"FreeRTOS-openocd.c") "FreeRTOS-openocd.c")
set(include_dirs
include
xtensa/include)
set(private_include_dirs
include/freertos
xtensa/include/freertos
xtensa
.)
if(CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY) if(CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY)
list(APPEND srcs "xtensa/xtensa_loadstore_handler.S") list(APPEND srcs "port/xtensa/xtensa_loadstore_handler.S")
endif() endif()
# app_trace is required by FreeRTOS headers only when CONFIG_SYSVIEW_ENABLE=y, # app_trace is required by FreeRTOS headers only when CONFIG_SYSVIEW_ENABLE=y,
# but requirements can't depend on config options, so always require it. # but requirements can't depend on config options, so always require it.
@ -43,7 +66,7 @@ idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS ${include_dirs} INCLUDE_DIRS ${include_dirs}
PRIV_INCLUDE_DIRS ${private_include_dirs} PRIV_INCLUDE_DIRS ${private_include_dirs}
LDFRAGMENTS linker.lf LDFRAGMENTS linker.lf
REQUIRES app_trace esp_timer REQUIRES ${required_components}
PRIV_REQUIRES soc) PRIV_REQUIRES soc)
idf_component_get_property(COMPONENT_DIR freertos COMPONENT_DIR) idf_component_get_property(COMPONENT_DIR freertos COMPONENT_DIR)

View File

@ -6,9 +6,9 @@ ifdef CONFIG_FREERTOS_DEBUG_OCDAWARE
COMPONENT_ADD_LDFLAGS += -Wl,--undefined=uxTopUsedPriority COMPONENT_ADD_LDFLAGS += -Wl,--undefined=uxTopUsedPriority
endif endif
COMPONENT_ADD_INCLUDEDIRS := include xtensa/include COMPONENT_ADD_INCLUDEDIRS := include port/xtensa/include
COMPONENT_PRIV_INCLUDEDIRS := include/freertos xtensa/include/freertos xtensa . COMPONENT_PRIV_INCLUDEDIRS := include/freertos port/xtensa/include/freertos port/xtensa .
COMPONENT_SRCDIRS += xtensa COMPONENT_SRCDIRS += port port/xtensa
ifndef CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY ifndef CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY
COMPONENT_OBJEXCLUDE := xtensa/xtensa_loadstore_handler.o COMPONENT_OBJEXCLUDE := xtensa/xtensa_loadstore_handler.o

View File

@ -112,6 +112,6 @@ entries:
queue: xQueueAddToSet (default) queue: xQueueAddToSet (default)
queue: xQueueRemoveFromSet (default) queue: xQueueRemoveFromSet (default)
queue: xQueueSelectFromSet (default) queue: xQueueSelectFromSet (default)
port:main_task (default) port_common:main_task (default)
port:esp_startup_start_app (default) port:esp_startup_start_app (default)
port:esp_startup_start_app_other_cores (default) port:esp_startup_start_app_other_cores (default)

View File

@ -0,0 +1,135 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "portmacro.h"
#include "esp_system.h"
#include "esp_heap_caps_init.h"
#include "esp_int_wdt.h"
#include "esp_task_wdt.h"
#include "esp_task.h"
#include "esp_private/crosscore_int.h"
#include "esp_private/startup_internal.h"
#include "esp_log.h"
#include "soc/dport_access.h"
#include "sdkconfig.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp32/spiram.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/spiram.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/spiram.h"
#elif CONFIG_IDF_TARGET_ESP32C3
// SPIRAM is not supported on ESP32-C3
#endif
#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL
static const char* TAG = "cpu_start";
#endif
/* Architecture-agnostic parts of the FreeRTOS ESP-IDF port layer can go here.
*
* The actual call flow will be to call esp_startup_start_app() in <ARCH>/port.c,
* which will then call esp_startup_start_app_common()
*/
// Duplicate of inaccessible xSchedulerRunning; needed at startup to avoid counting nesting
volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS] = {0};
// For now, running FreeRTOS on one core and a bare metal on the other (or other OSes)
// is not supported. For now CONFIG_FREERTOS_UNICORE and CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
// should mirror each other's values.
//
// And since this should be true, we can just check for CONFIG_FREERTOS_UNICORE.
#if CONFIG_FREERTOS_UNICORE != CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
#error "FreeRTOS and system configuration mismatch regarding the use of multiple cores."
#endif
static void main_task(void* args);
extern void app_main(void);
void esp_startup_start_app_common(void)
{
#if CONFIG_ESP_INT_WDT
esp_int_wdt_init();
//Initialize the interrupt watch dog for CPU0.
esp_int_wdt_cpu_init();
#endif
esp_crosscore_int_init();
#ifndef CONFIG_FREERTOS_UNICORE
#if CONFIG_IDF_TARGET_ESP32
esp_dport_access_int_init();
#endif
#endif
portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main",
ESP_TASK_MAIN_STACK, NULL,
ESP_TASK_MAIN_PRIO, NULL, 0);
assert(res == pdTRUE);
}
static void main_task(void* args)
{
#if !CONFIG_FREERTOS_UNICORE
// Wait for FreeRTOS initialization to finish on APP CPU, before replacing its startup stack
while (port_xSchedulerRunning[1] == 0) {
;
}
#endif
// [refactor-todo] check if there is a way to move the following block to esp_system startup
heap_caps_enable_nonos_stack_heaps();
// Now we have startup stack RAM available for heap, enable any DMA pool memory
#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL
if (g_spiram_ok) {
esp_err_t r = esp_spiram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL);
if (r != ESP_OK) {
ESP_EARLY_LOGE(TAG, "Could not reserve internal/DMA pool (error 0x%x)", r);
abort();
}
}
#endif
//Initialize task wdt if configured to do so
#ifdef CONFIG_ESP_TASK_WDT_PANIC
ESP_ERROR_CHECK(esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, true));
#elif CONFIG_ESP_TASK_WDT
ESP_ERROR_CHECK(esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, false));
#endif
//Add IDLE 0 to task wdt
#ifdef CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0
TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0);
if(idle_0 != NULL){
ESP_ERROR_CHECK(esp_task_wdt_add(idle_0));
}
#endif
//Add IDLE 1 to task wdt
#ifdef CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1
TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCPU(1);
if(idle_1 != NULL){
ESP_ERROR_CHECK(esp_task_wdt_add(idle_1));
}
#endif
app_main();
vTaskDelete(NULL);
}

View File

@ -0,0 +1,277 @@
/*
FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
***************************************************************************
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
***************************************************************************
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "sdkconfig.h"
/* enable use of optimized task selection by the scheduler */
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define portNUM_PROCESSORS 1
#define configASSERT_2 0
#define portUSING_MPU_WRAPPERS 0
#define configUSE_MUTEX 1
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 0
#define configUSE_NEWLIB_REENTRANT 1
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS
#define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 1
/* configASSERT behaviour */
#ifndef __ASSEMBLER__
#include <stdlib.h> /* for abort() */
#include "esp32c3/rom/ets_sys.h"
#if defined(CONFIG_FREERTOS_ASSERT_DISABLE)
#define configASSERT(a) /* assertions disabled */
#elif defined(CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE)
#define configASSERT(a) if (unlikely(!(a))) { \
esp_rom_printf("%s:%d (%s)- assert failed!\n", __FILE__, __LINE__, \
__FUNCTION__); \
}
#else /* CONFIG_FREERTOS_ASSERT_FAIL_ABORT */
#define configASSERT(a) if (unlikely(!(a))) { \
esp_rom_printf("%s:%d (%s)- assert failed!\n", __FILE__, __LINE__, \
__FUNCTION__); \
abort(); \
}
#endif
#if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION
#define UNTESTED_FUNCTION() { esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0)
#else
#define UNTESTED_FUNCTION()
#endif
#endif /* def __ASSEMBLER__ */
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* Note that the default heap size is deliberately kept small so that
* the build is more likely to succeed for configurations with limited
* memory.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configRECORD_STACK_HIGH_ADDRESS 1
#define configTICK_RATE_HZ ( CONFIG_FREERTOS_HZ )
/* Default clock rate for simulator */
//#define configCPU_CLOCK_HZ 80000000
/* This has impact on speed of search for highest priority */
#ifdef SMALL_TEST
#define configMAX_PRIORITIES ( 7 )
#else
#define configMAX_PRIORITIES ( 25 )
#endif
#if defined(CONFIG_APPTRACE_ENABLE)
/* apptrace module requires at least 2KB of stack per task */
#define configMINIMAL_STACK_SIZE 2048
#elif defined(CONFIG_COMPILER_OPTIMIZATION_NONE)
/* with optimizations disabled, scheduler uses additional stack */
#define configMINIMAL_STACK_SIZE 1024
#else
#define configMINIMAL_STACK_SIZE 768
#endif
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS
#define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 1
#ifndef configIDLE_TASK_STACK_SIZE
#define configIDLE_TASK_STACK_SIZE CONFIG_FREERTOS_IDLE_TASK_STACKSIZE
#endif
/* The port layer uses a separate interrupt stack. Adjust the stack size */
/* to suit the needs of your specific application. */
#ifndef configISR_STACK_SIZE
#define configISR_STACK_SIZE CONFIG_FREERTOS_ISR_STACKSIZE
#endif
/* Minimal heap size to make sure examples can run on memory limited
configs. Adjust this to suit your system. */
//We define the heap to span all of the non-statically-allocated shared RAM. ToDo: Make sure there
//is some space left for the app and main cpu when running outside of a thread.
#define configAPPLICATION_ALLOCATED_HEAP 1
#define configTOTAL_HEAP_SIZE (&_heap_end - &_heap_start)//( ( size_t ) (64 * 1024) )
#define configMAX_TASK_NAME_LEN ( CONFIG_FREERTOS_MAX_TASK_NAME_LEN )
#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY
#define configUSE_TRACE_FACILITY 1 /* Used by uxTaskGetSystemState(), and other trace facility functions */
#endif
#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
#define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* Used by vTaskList() */
#endif
#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID
#define configTASKLIST_INCLUDE_COREID 1
#endif
#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
#define configGENERATE_RUN_TIME_STATS 1 /* Used by vTaskGetRunTimeStats() */
#endif
#define configUSE_TRACE_FACILITY_2 0
#define configBENCHMARK 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 0
#define configQUEUE_REGISTRY_SIZE CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#if CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE
#define configCHECK_FOR_STACK_OVERFLOW 0
#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL
#define configCHECK_FOR_STACK_OVERFLOW 1
#elif CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY
#define configCHECK_FOR_STACK_OVERFLOW 2
#endif
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_pcTaskGetTaskName 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_pxTaskGetStackStart 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
/* The priority at which the tick interrupt runs. This should probably be
kept at 1. */
#define configKERNEL_INTERRUPT_PRIORITY 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configSUPPORT_STATIC_ALLOCATION CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION
#ifndef __ASSEMBLER__
#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP
extern void vPortCleanUpTCB ( void *pxTCB );
#define portCLEAN_UP_TCB( pxTCB ) vPortCleanUpTCB( pxTCB )
#endif
#endif
/* Test FreeRTOS timers (with timer task) and more. */
/* Some files don't compile if this flag is disabled */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY CONFIG_FREERTOS_TIMER_TASK_PRIORITY
#define configTIMER_QUEUE_LENGTH CONFIG_FREERTOS_TIMER_QUEUE_LENGTH
#define configTIMER_TASK_STACK_DEPTH CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_eTaskGetState 1
#define configUSE_QUEUE_SETS 1
#define configUSE_TICKLESS_IDLE CONFIG_FREERTOS_USE_TICKLESS_IDLE
#if configUSE_TICKLESS_IDLE
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP
#endif //configUSE_TICKLESS_IDLE
#ifndef configENABLE_TASK_SNAPSHOT
#define configENABLE_TASK_SNAPSHOT 1
#endif
#if CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER
#define configCHECK_MUTEX_GIVEN_BY_OWNER 1
#else
#define configCHECK_MUTEX_GIVEN_BY_OWNER 0
#endif
#endif /* FREERTOS_CONFIG_H */

View File

@ -0,0 +1,310 @@
/*
* FreeRTOS Kernel V10.2.1
* 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
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __ASSEMBLER__
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <limits.h>
#include "sdkconfig.h"
#include "esp_attr.h"
#include "esp_heap_caps.h"
#ifdef CONFIG_LEGACY_INCLUDE_COMMON_HEADERS
#include "soc/soc_memory_layout.h"
#endif
#include "soc/spinlock.h"
#include "soc/interrupt_core0_reg.h"
#include "esp_rom_sys.h"
#include "soc/cpu.h"
#include "esp_system.h"
#include "esp_newlib.h"
/*-----------------------------------------------------------
* 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;
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
/*------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) (1000 / configTICK_RATE_HZ) )
#define portBYTE_ALIGNMENT 16
/*-----------------------------------------------------------*/
#include "portbenchmark.h"
static inline uint32_t IRAM_ATTR xPortGetCoreID(void) {
return cpu_hal_get_core_id();
}
static inline bool IRAM_ATTR xPortCanYield(void)
{
uint32_t threshold = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG);
/* when enter critical code, freertos will mask threshold to RVHAL_EXCM_LEVEL
* and exit critical code, will recover threshold value (1). so threshold <= 1
* means not in critical code
*/
return (threshold <= 1);
}
static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
{
#if defined(CONFIG_SPIRAM)
compare_and_set_extram(addr, compare, set);
#endif
}
static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set) {
compare_and_set_native(addr, compare, set);
}
#define portCRITICAL_NESTING_IN_TCB 0
/*
* Send an interrupt to another core in order to make the task running
* on it yield for a higher-priority task.
*/
void vPortYieldOtherCore( BaseType_t coreid);
/*
Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack
watchpoint around.
*/
void vPortSetStackWatchpoint( void* pxStackStart );
/*
* Returns true if the current core is in ISR context; low prio ISR, med prio ISR or timer tick ISR. High prio ISRs
* aren't detected here, but they normally cannot call C code, so that should not be an issue anyway.
*/
BaseType_t xPortInIsrContext(void);
/*
* This function will be called in High prio ISRs. Returns true if the current core was in ISR context
* before calling into high prio ISR context.
*/
BaseType_t xPortInterruptedFromISRContext(void);
/* "mux" data structure (spinlock) */
typedef struct {
/* owner field values:
* 0 - Uninitialized (invalid)
* portMUX_FREE_VAL - Mux is free, can be locked by either CPU
* CORE_ID_REGVAL_PRO / CORE_ID_REGVAL_APP - Mux is locked to the particular core
*
*
* Any value other than portMUX_FREE_VAL, CORE_ID_REGVAL_PRO, CORE_ID_REGVAL_APP indicates corruption
*/
uint32_t owner;
/* count field:
* If mux is unlocked, count should be zero.
* If mux is locked, count is non-zero & represents the number of recursive locks on the mux.
*/
uint32_t count;
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
const char *lastLockedFn;
int lastLockedLine;
#endif
} portMUX_TYPE;
#define portMUX_FREE_VAL SPINLOCK_FREE
/* Special constants for vPortCPUAcquireMutexTimeout() */
#define portMUX_NO_TIMEOUT SPINLOCK_WAIT_FOREVER /* When passed for 'timeout_cycles', spin forever if necessary */
#define portMUX_TRY_LOCK SPINLOCK_NO_WAIT /* Try to acquire the spinlock a single time only */
// Keep this in sync with the portMUX_TYPE struct definition please.
#ifndef CONFIG_FREERTOS_PORTMUX_DEBUG
#define portMUX_INITIALIZER_UNLOCKED { \
.owner = portMUX_FREE_VAL, \
.count = 0, \
}
#else
#define portMUX_INITIALIZER_UNLOCKED { \
.owner = portMUX_FREE_VAL, \
.count = 0, \
.lastLockedFn = "(never locked)", \
.lastLockedLine = -1 \
}
#endif
/* Scheduler utilities. */
extern void vPortYield( void );
extern void vPortYieldFromISR( void );
#define portYIELD() vPortYield()
#define portYIELD_FROM_ISR() vPortYieldFromISR()
/* Yielding within an API call (when interrupts are off), means the yield should be delayed
until interrupts are re-enabled.
To do this, we use the "cross-core" interrupt as a trigger to yield on this core when interrupts are re-enabled.This
is the same interrupt & code path which is used to trigger a yield between CPUs, although in this case the yield is
happening on the same CPU.
*/
#define portYIELD_WITHIN_API() portYIELD()
/*-----------------------------------------------------------*/
/* Critical section management. */
extern int vPortSetInterruptMask(void);
extern void vPortClearInterruptMask( int );
void vPortCPUInitializeMutex(portMUX_TYPE *mux);
void vPortCPUAcquireMutex(portMUX_TYPE *mux);
bool vPortCPUAcquireMutexTimeout(portMUX_TYPE *mux, int timeout_cycles);
void vPortCPUReleaseMutex(portMUX_TYPE *mux);
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK_FROM_ISR()
#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK_FROM_ISR(1)
#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)
#define portENTER_CRITICAL_SAFE(mux) do { \
if (xPortInIsrContext()) { \
portENTER_CRITICAL_ISR(mux); \
} else { \
portENTER_CRITICAL(mux); \
} \
} while(0)
#define portEXIT_CRITICAL_SAFE(mux) do { \
if (xPortInIsrContext()) { \
portEXIT_CRITICAL_ISR(mux); \
} else { \
portEXIT_CRITICAL(mux); \
} \
} while(0)
/*------------------------------------------------------------*/
#define portSET_INTERRUPT_MASK_FROM_ISR() vPortSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) vPortClearInterruptMask( uxSavedStatusValue )
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYield()
// Cleaner solution allows nested interrupts disabling and restoring via local registers or stack.
// They can be called from interrupts too.
static inline unsigned portENTER_CRITICAL_NESTED(void) {
unsigned state = portSET_INTERRUPT_MASK_FROM_ISR();
return state;
}
#define portEXIT_CRITICAL_NESTED(state) do { portCLEAR_INTERRUPT_MASK_FROM_ISR( state );} while(0);
/*-----------------------------------------------------------*/
//Because the ROM routines don't necessarily handle a stack in external RAM correctly, we force
//the stack memory to always be internal.
#define portTcbMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)
#define portStackMemoryCaps (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)
#define pvPortMallocTcbMem(size) pvPortMalloc(size)
#define pvPortMallocStackMem(size) pvPortMalloc(size)
/* Fine resolution time */
#define portGET_RUN_TIME_COUNTER_VALUE() 0
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
#ifdef CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER
/* Coarse resolution time (us) */
#define portALT_GET_RUN_TIME_COUNTER_VALUE(x) do{(void)x; }while(0)
#endif
extern void esp_vApplicationIdleHook( void );
extern void esp_vApplicationTickHook( void );
#ifndef CONFIG_FREERTOS_LEGACY_HOOKS
#define vApplicationIdleHook esp_vApplicationIdleHook
#define vApplicationTickHook esp_vApplicationTickHook
#endif /* !CONFIG_FREERTOS_LEGACY_HOOKS */
/* Task function macros as described on the FreeRTOS.org WEB site. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
void vApplicationSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( idleTime ) vApplicationSleep( idleTime )
#define portNOP() __asm volatile ( " nop " )
#define portVALID_TCB_MEM(ptr) esp_ptr_byte_accessible(ptr)
#define portVALID_STACK_MEM(ptr) esp_ptr_byte_accessible(ptr)
// configASSERT_2 if requested
#if configASSERT_2
#include <stdio.h>
void exit(int);
#define configASSERT( x ) if (!(x)) { porttracePrint(-1); printf("\nAssertion failed in %s:%d\n", __FILE__, __LINE__); exit(-1); }
#endif
#endif //__ASSEMBLER__
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View File

@ -0,0 +1,369 @@
/*
FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
This file is part of the FreeRTOS distribution and was contributed
to the project by Technolution B.V. (www.technolution.nl,
freertos-riscv@technolution.eu) under the terms of the FreeRTOS
contributors license.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
***************************************************************************
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
***************************************************************************
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
/*-----------------------------------------------------------------------
* Implementation of functions defined in portable.h for the RISC-V port.
*----------------------------------------------------------------------*/
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "sdkconfig.h"
#include "portmacro.h"
#include "riscv/interrupt.h"
#include "soc/periph_defs.h"
#include "soc/system_reg.h"
#include "soc/interrupt_reg.h"
#include "hal/systimer_hal.h"
#include "hal/systimer_ll.h"
#include "riscv/riscv_interrupts.h"
#include "riscv/interrupt.h"
#include "esp_system.h"
#include "esp_intr_alloc.h"
#include "esp_log.h"
/**
* @brief A variable is used to keep track of the critical section nesting.
* @note This variable has to be stored as part of the task context and must be initialized to a non zero value
* to ensure interrupts don't inadvertently become unmasked before the scheduler starts.
* As it is stored as part of the task context it will automatically be set to 0 when the first task is started.
*/
static UBaseType_t uxCriticalNesting = 0;
static UBaseType_t uxSavedInterruptState = 0;
BaseType_t uxSchedulerRunning = 0;
UBaseType_t uxInterruptNesting = 0;
__attribute__((aligned(16))) static StackType_t xIsrStack[configISR_STACK_SIZE];
StackType_t *xIsrStackTop = &xIsrStack[0] + (configISR_STACK_SIZE & (~((portPOINTER_SIZE_TYPE)portBYTE_ALIGNMENT_MASK)));
static const char *TAG = "cpu_start"; // [refactor-todo]: might be appropriate to change in the future, but
static void vPortSysTickHandler(void);
static void vPortSetupTimer(void);
static void vPortSetupSoftwareInterrupt(void);
static void vPortSoftwareInterrupt(void);
static void prvTaskExitError(void);
extern void esprv_intc_int_set_threshold(int); // FIXME, this function is in ROM only
void vPortEnterCritical(void)
{
BaseType_t state = portENTER_CRITICAL_NESTED();
uxCriticalNesting++;
if (uxCriticalNesting == 1) {
//portDISABLE_INTERRUPTS();
uxSavedInterruptState = state;
}
}
void vPortExitCritical(void)
{
if (uxCriticalNesting > 0) {
uxCriticalNesting--;
if (uxCriticalNesting == 0) {
portEXIT_CRITICAL_NESTED(uxSavedInterruptState);
//portENABLE_INTERRUPTS();
}
}
}
/**
* @brief Set up the systimer peripheral to generate the tick interrupt
*
*/
void vPortSetupTimer(void)
{
/* register the interrupt handler */
intr_handler_set(ETS_SYSTICK_INUM, (intr_handler_t)&vPortSysTickHandler, NULL);
/* pass the timer interrupt through the interrupt matrix */
intr_matrix_route(ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE, ETS_SYSTICK_INUM);
/* enable the interrupt in the INTC */
esprv_intc_int_enable(BIT(ETS_SYSTICK_INUM));
esprv_intc_int_set_type(BIT(ETS_SYSTICK_INUM), INTR_TYPE_LEVEL);
esprv_intc_int_set_priority(ETS_SYSTICK_INUM, 1);
/* configure the timer */
systimer_hal_init();
systimer_hal_enable_counter(SYSTIMER_COUNTER_1);
systimer_hal_set_alarm_period(SYSTIMER_ALARM_0, 1000000UL / CONFIG_FREERTOS_HZ);
systimer_hal_select_alarm_mode(SYSTIMER_ALARM_0, SYSTIMER_ALARM_MODE_PERIOD);
systimer_hal_enable_alarm_int(SYSTIMER_ALARM_0);
systimer_hal_connect_alarm_counter(SYSTIMER_ALARM_0, SYSTIMER_COUNTER_1);
}
/* setup software interrupt */
void vPortSetupSoftwareInterrupt(void)
{
/* register the interrupt handler, see interrupt.h */
intr_handler_set(ETS_CPU_INTR0_INUM, (intr_handler_t)&vPortSoftwareInterrupt, NULL);
/* pass the "FROM_CPU_0", a.k.a. cross-core interrupt, through the interrupt matrix */
intr_matrix_route(ETS_FROM_CPU_INTR0_SOURCE, ETS_CPU_INTR0_INUM);
/* enable the interrupt in the INTC */
esprv_intc_int_enable(BIT(ETS_CPU_INTR0_INUM));
esprv_intc_int_set_type(BIT(ETS_CPU_INTR0_INUM), INTR_TYPE_LEVEL);
esprv_intc_int_set_priority(ETS_CPU_INTR0_INUM, 1);
// TODO ESP32-C3 IDF-2126, maybe can use interrupt allocation API for all of the above? unsure...
esp_intr_reserve(ETS_CPU_INTR0_INUM, xPortGetCoreID());
}
void prvTaskExitError(void)
{
/* A function that implements a task must not exit or attempt to return to
its caller as there is nothing to return to. If a task wants to exit it
should instead call vTaskDelete( NULL ).
Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */
configASSERT(uxCriticalNesting == ~0UL);
portDISABLE_INTERRUPTS();
for (;;)
;
}
/* Clear current interrupt mask and set given mask */
void vPortClearInterruptMask(int mask)
{
REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, mask);
}
/* Set interrupt mask and return current interrupt enable register */
int vPortSetInterruptMask(void)
{
int ret;
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
ret = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG);
REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, RVHAL_EXCM_LEVEL);
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
return ret;
}
/*
* See header file for description.
*/
StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters)
{
extern uint32_t __global_pointer$;
/* Simulate the stack frame as it would be created by a context switch
interrupt. */
RvExcFrame *frame = (RvExcFrame *)pxTopOfStack;
frame--;
frame->ra = (UBaseType_t)prvTaskExitError;
frame->mepc = (UBaseType_t)pxCode;
frame->a0 = (UBaseType_t)pvParameters;
frame->gp = (UBaseType_t)&__global_pointer$;
frame->a1 = 0x11111111;
frame->a2 = 0x22222222;
frame->a3 = 0x33333333;
return (StackType_t *)frame;
}
void vPortSysTickHandler(void)
{
systimer_ll_clear_alarm_int(SYSTIMER_ALARM_0);
if (!uxSchedulerRunning) {
return;
}
if (xTaskIncrementTick() != pdFALSE) {
vTaskSwitchContext();
}
}
BaseType_t xPortStartScheduler(void)
{
vPortSetupTimer();
vPortSetupSoftwareInterrupt();
uxCriticalNesting = 0;
uxSchedulerRunning = 0; /* this means first yield */
esprv_intc_int_set_threshold(1); /* set global INTC masking level */
riscv_global_interrupts_enable();
vPortYield();
/*Should not get here*/
return pdFALSE;
}
void vPortEndScheduler(void)
{
/* very unlikely this function will be called, so just trap here */
while (1)
;
}
void vPortSoftwareInterrupt(void)
{
uxSchedulerRunning = 1;
vTaskSwitchContext();
REG_WRITE(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 0);
}
void vPortYieldOtherCore(BaseType_t coreid)
{
(void)coreid;
vPortYield();
}
void vPortYield(void)
{
if (uxInterruptNesting) {
vPortYieldFromISR();
} else {
REG_WRITE(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 1);
/* There are 3-4 instructions of latency between triggering the software
interrupt and the CPU interrupt happening. Make sure it happened before
we return, otherwise vTaskDelay() may return and execute 1-2
instructions before the delay actually happens.
(We could use the WFI instruction here, but there is a chance that
the interrupt will happen while evaluating the other two conditions
for an instant yield, and if that happens then the WFI would be
waiting for the next interrupt to occur...)
*/
while(uxSchedulerRunning && uxCriticalNesting == 0 && REG_READ(SYSTEM_CPU_INTR_FROM_CPU_0_REG) != 0) { }
}
}
void vPortYieldFromISR(void)
{
vTaskSwitchContext();
}
void vPortSetStackWatchpoint(void *pxStackStart)
{
(void)pxStackStart; // TODO ESP32-C3 IDF-2207
}
BaseType_t xPortInIsrContext(void)
{
return uxInterruptNesting;
}
BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void)
{
/* For single core, this can be the same as xPortInIsrContext() because reading it is atomic */
return uxInterruptNesting;
}
void vPortCPUInitializeMutex(portMUX_TYPE *mux)
{
(void)mux;
}
void vPortCPUAcquireMutex(portMUX_TYPE *mux)
{
(void)mux;
}
bool vPortCPUAcquireMutexTimeout(portMUX_TYPE *mux, int timeout_cycles)
{
(void)mux;
(void)timeout_cycles;
return true;
}
void vPortCPUReleaseMutex(portMUX_TYPE *mux)
{
(void)mux;
}
void __attribute__((weak)) vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
{
#define ERR_STR1 "***ERROR*** A stack overflow in task "
#define ERR_STR2 " has been detected."
const char *str[] = {ERR_STR1, pcTaskName, ERR_STR2};
char buf[sizeof(ERR_STR1) + CONFIG_FREERTOS_MAX_TASK_NAME_LEN + sizeof(ERR_STR2) + 1 /* null char */] = {0};
char *dest = buf;
for (int i = 0; i < sizeof(str) / sizeof(str[0]); i++) {
dest = strcat(dest, str[i]);
}
esp_system_abort(buf);
}
extern void esp_startup_start_app_common(void);
void esp_startup_start_app(void)
{
esp_startup_start_app_common();
ESP_LOGI(TAG, "Starting scheduler.");
vTaskStartScheduler();
}

View File

@ -0,0 +1,87 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
.global uxInterruptNesting
.global uxSchedulerRunning
.global xIsrStackTop
.global pxCurrentTCB
.global vTaskSwitchContext
.global xPortSwitchFlag
.section .text
/**
* This function makes the RTOS aware about a ISR entering, it takes the
* current task stack saved, places into the TCB, loads the ISR stack
* the interrupted stack must be passed in a0. It needs to receive the
* ISR nesting code improvements
*/
.global rtos_int_enter
.type rtos_int_enter, @function
rtos_int_enter:
/* preserve the return address */
mv t1, ra
mv t2, a0
/* scheduler not enabled, jump directly to ISR handler */
lw t0, uxSchedulerRunning
beq t0,zero, not_rtos_enter
/* Sabe current TCB and load the ISR stack */
lw t0, pxCurrentTCB
sw t2, 0x0(t0)
lw sp, xIsrStackTop
not_rtos_enter:
mv ra, t1
ret
/**
* Recovers the next task to run stack pointer and place it into
* a0, then the interrupt handler can restore the context of
* the next task
*/
.global rtos_int_exit
.type rtos_int_exit, @function
rtos_int_exit:
/* may skip RTOS aware interrupt since scheduler was not started */
lw t0, uxSchedulerRunning
beq t0,zero, not_rtos_exit
/* Schedule the next task if a yield is pending */
la t0, xPortSwitchFlag
lw t2, 0x0(t0)
beq t2, zero, no_switch
/* preserve return address and schedule next task */
addi sp,sp,-4
sw ra, 0x04(sp)
call vTaskSwitchContext
lw ra, 0x04(sp)
addi sp, sp, 4
/* Clears the switch pending flag */
la t0, xPortSwitchFlag
mv t2, zero
sw t2, 0x0(t0)
no_switch:
/* Recover the stack of next task and prepare to exit : */
lw a0, pxCurrentTCB
lw a0, 0x0(a0)
not_rtos_exit:
ret

View File

@ -0,0 +1,46 @@
/*******************************************************************************
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
//
// 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.
--------------------------------------------------------------------------------
*/
/*
* This utility helps benchmarking interrupt latency and context switches.
* In order to enable it, set configBENCHMARK to 1 in FreeRTOSConfig.h.
* You will also need to download the FreeRTOS_trace patch that contains
* portbenchmark.c and the complete version of portbenchmark.h
*/
#ifndef PORTBENCHMARK_H
#define PORTBENCHMARK_H
#if configBENCHMARK
#error "You need to download the FreeRTOS_trace patch that overwrites this file"
#endif
#define portbenchmarkINTERRUPT_DISABLE()
#define portbenchmarkINTERRUPT_RESTORE(newstate)
#define portbenchmarkIntLatency()
#define portbenchmarkIntWait()
#define portbenchmarkReset()
#define portbenchmarkPrint()
#endif /* PORTBENCHMARK */

View File

@ -1,68 +1,29 @@
/* /*
FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd. * FreeRTOS Kernel V10.2.1
All rights reserved * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. * 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
* FreeRTOS provides completely free yet professionally developed, * * the Software, and to permit persons to whom the Software is furnished to do so,
* robust, strictly quality controlled, supported, and cross * * subject to the following conditions:
* platform software that has become a de facto standard. * *
* * * The above copyright notice and this permission notice shall be included in all
* Help yourself get started quickly and support the FreeRTOS * * copies or substantial portions of the Software.
* project by purchasing a FreeRTOS tutorial book, reference * *
* manual, or both from: http://www.FreeRTOS.org/Documentation * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* Thank you! * * 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.
This file is part of the FreeRTOS distribution. *
* http://www.FreeRTOS.org
FreeRTOS is free software; you can redistribute it and/or modify it under * http://aws.amazon.com/freertos
the terms of the GNU General Public License (version 2) as published by the *
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. * 1 tab == 4 spaces!
*/
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. Full license text is available from the following
link: http://www.freertos.org/a00114.html
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong?" *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
#ifndef PORTMACRO_H #ifndef PORTMACRO_H
#define PORTMACRO_H #define PORTMACRO_H
@ -108,8 +69,11 @@ extern "C" {
*----------------------------------------------------------- *-----------------------------------------------------------
*/ */
/* Type definitions. */ #include "esp_system.h"
#include "hal/cpu_hal.h"
#include "xt_instr_macros.h"
/* Type definitions. */
#define portCHAR int8_t #define portCHAR int8_t
#define portFLOAT float #define portFLOAT float
#define portDOUBLE double #define portDOUBLE double
@ -136,6 +100,7 @@ typedef unsigned portBASE_TYPE UBaseType_t;
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "portmacro_priv.h"
// Cleaner solution allows nested interrupts disabling and restoring via local registers or stack. // Cleaner solution allows nested interrupts disabling and restoring via local registers or stack.
// They can be called from interrupts too. // They can be called from interrupts too.

View File

@ -139,8 +139,6 @@ extern void _frxt_tick_timer_init(void);
/* Defined in xtensa_context.S */ /* Defined in xtensa_context.S */
extern void _xt_coproc_init(void); extern void _xt_coproc_init(void);
extern void app_main(void);
static const char* TAG = "cpu_start"; // [refactor-todo]: might be appropriate to change in the future, but static const char* TAG = "cpu_start"; // [refactor-todo]: might be appropriate to change in the future, but
// for now maintain the same log output // for now maintain the same log output
@ -154,7 +152,7 @@ static const char* TAG = "cpu_start"; // [refactor-todo]: might be appropriate t
_Static_assert(tskNO_AFFINITY == CONFIG_FREERTOS_NO_AFFINITY, "incorrect tskNO_AFFINITY value"); _Static_assert(tskNO_AFFINITY == CONFIG_FREERTOS_NO_AFFINITY, "incorrect tskNO_AFFINITY value");
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS] = {0}; // Duplicate of inaccessible xSchedulerRunning; needed at startup to avoid counting nesting extern volatile int port_xSchedulerRunning[portNUM_PROCESSORS];
unsigned port_interruptNesting[portNUM_PROCESSORS] = {0}; // Interrupt nesting level. Increased/decreased in portasm.c, _frxt_int_enter/_frxt_int_exit unsigned port_interruptNesting[portNUM_PROCESSORS] = {0}; // Interrupt nesting level. Increased/decreased in portasm.c, _frxt_int_enter/_frxt_int_exit
BaseType_t port_uxCriticalNesting[portNUM_PROCESSORS] = {0}; BaseType_t port_uxCriticalNesting[portNUM_PROCESSORS] = {0};
BaseType_t port_uxOldInterruptState[portNUM_PROCESSORS] = {0}; BaseType_t port_uxOldInterruptState[portNUM_PROCESSORS] = {0};
@ -488,66 +486,6 @@ void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, c
esp_system_abort(buf); esp_system_abort(buf);
} }
static void main_task(void* args)
{
#if !CONFIG_FREERTOS_UNICORE
// Wait for FreeRTOS initialization to finish on APP CPU, before replacing its startup stack
while (port_xSchedulerRunning[1] == 0) {
;
}
#endif
// [refactor-todo] check if there is a way to move the following block to esp_system startup
heap_caps_enable_nonos_stack_heaps();
// Now we have startup stack RAM available for heap, enable any DMA pool memory
#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL
if (g_spiram_ok) {
esp_err_t r = esp_spiram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL);
if (r != ESP_OK) {
ESP_EARLY_LOGE(TAG, "Could not reserve internal/DMA pool (error 0x%x)", r);
abort();
}
}
#endif
//Initialize task wdt if configured to do so
#ifdef CONFIG_ESP_TASK_WDT_PANIC
ESP_ERROR_CHECK(esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, true));
#elif CONFIG_ESP_TASK_WDT
ESP_ERROR_CHECK(esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, false));
#endif
//Add IDLE 0 to task wdt
#ifdef CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0
TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0);
if(idle_0 != NULL){
ESP_ERROR_CHECK(esp_task_wdt_add(idle_0));
}
#endif
//Add IDLE 1 to task wdt
#ifdef CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1
TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCPU(1);
if(idle_1 != NULL){
ESP_ERROR_CHECK(esp_task_wdt_add(idle_1));
}
#endif
app_main();
vTaskDelete(NULL);
}
// For now, running FreeRTOS on one core and a bare metal on the other (or other OSes)
// is not supported. For now CONFIG_FREERTOS_UNICORE and CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
// should mirror each other's values.
//
// And since this should be true, we can just check for CONFIG_FREERTOS_UNICORE.
#if CONFIG_FREERTOS_UNICORE != CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
#error "FreeRTOS and system configuration mismatch regarding the use of multiple cores."
#endif
#if !CONFIG_FREERTOS_UNICORE #if !CONFIG_FREERTOS_UNICORE
void esp_startup_start_app_other_cores(void) void esp_startup_start_app_other_cores(void)
{ {
@ -581,33 +519,18 @@ void esp_startup_start_app_other_cores(void)
xPortStartScheduler(); xPortStartScheduler();
abort(); /* Only get to here if FreeRTOS somehow very broken */ abort(); /* Only get to here if FreeRTOS somehow very broken */
} }
#endif #endif // !CONFIG_FREERTOS_UNICORE
extern void esp_startup_start_app_common(void);
void esp_startup_start_app(void) void esp_startup_start_app(void)
{ {
#if CONFIG_ESP_INT_WDT #if !CONFIG_ESP_INT_WDT
esp_int_wdt_init();
//Initialize the interrupt watch dog for CPU0.
esp_int_wdt_cpu_init();
#else
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX #if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
assert(!soc_has_cache_lock_bug() && "ESP32 Rev 3 + Dual Core + PSRAM requires INT WDT enabled in project config!"); assert(!soc_has_cache_lock_bug() && "ESP32 Rev 3 + Dual Core + PSRAM requires INT WDT enabled in project config!");
#endif #endif
#endif #endif
esp_crosscore_int_init();
#ifndef CONFIG_FREERTOS_UNICORE
#if CONFIG_IDF_TARGET_ESP32
esp_dport_access_int_init();
#endif
#endif
portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main",
ESP_TASK_MAIN_STACK, NULL,
ESP_TASK_MAIN_PRIO, NULL, 0);
assert(res == pdTRUE);
// ESP32 has single core variants. Check that FreeRTOS has been configured properly. // ESP32 has single core variants. Check that FreeRTOS has been configured properly.
#if CONFIG_IDF_TARGET_ESP32 && !CONFIG_FREERTOS_UNICORE #if CONFIG_IDF_TARGET_ESP32 && !CONFIG_FREERTOS_UNICORE
if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_DIS_APP_CPU)) { if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_DIS_APP_CPU)) {
@ -617,6 +540,8 @@ void esp_startup_start_app(void)
} }
#endif // CONFIG_IDF_TARGET_ESP32 && !CONFIG_FREERTOS_UNICORE #endif // CONFIG_IDF_TARGET_ESP32 && !CONFIG_FREERTOS_UNICORE
esp_startup_start_app_common();
ESP_LOGI(TAG, "Starting scheduler on PRO CPU."); ESP_LOGI(TAG, "Starting scheduler on PRO CPU.");
vTaskStartScheduler(); vTaskStartScheduler();
} }

View File

@ -5,9 +5,7 @@
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "xtensa/hal.h"
#include "unity.h" #include "unity.h"
#include "soc/cpu.h" #include "soc/cpu.h"
#include "test_utils.h" #include "test_utils.h"

View File

@ -29,6 +29,7 @@
#include "unity.h" #include "unity.h"
#include "test_utils.h" #include "test_utils.h"
#ifdef CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION
/* ---------------------Test 1: Backported Timer functions----------------------- /* ---------------------Test 1: Backported Timer functions-----------------------
* Test xTimerCreateStatic(), vTimerSetTimerId(), xTimerGetPeriod(), xTimerGetExpiryTime() * Test xTimerCreateStatic(), vTimerSetTimerId(), xTimerGetPeriod(), xTimerGetExpiryTime()
* *
@ -200,6 +201,7 @@ TEST_CASE("Test FreeRTOS backported eventgroup functions", "[freertos]")
//Cleanup static event //Cleanup static event
vEventGroupDelete(eg_handle); vEventGroupDelete(eg_handle);
} }
#endif
/* --------Test backported thread local storage pointer and deletion cb feature---------- /* --------Test backported thread local storage pointer and deletion cb feature----------
* vTaskSetThreadLocalStoragePointerAndDelCallback() * vTaskSetThreadLocalStoragePointerAndDelCallback()

View File

@ -4,52 +4,52 @@
#include <esp_types.h> #include <esp_types.h>
#include <stdio.h> #include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "unity.h" #include "unity.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "xtensa/hal.h"
#include "esp_rom_sys.h" #include "esp_rom_sys.h"
#include "esp_freertos_hooks.h"
#if CONFIG_FREERTOS_CORETIMER_0 #if CONFIG_FREERTOS_CORETIMER_0
static volatile int in_int_context, int_handled; static volatile int in_int_context, int_handled;
static void testint(void *arg) { static void testint(void)
xthal_set_ccompare(1, xthal_get_ccount()+8000000000); {
esp_rom_printf("INT!\n"); esp_rom_printf("INT!\n");
if (xPortInIsrContext()) in_int_context++; if (xPortInIsrContext()) {
in_int_context++;
}
int_handled++; int_handled++;
} }
static void testthread(void *arg) { static void testthread(void *arg)
intr_handle_t handle; {
in_int_context=0; in_int_context = 0;
int_handled=0; int_handled = 0;
TEST_ASSERT(!xPortInIsrContext()); TEST_ASSERT(!xPortInIsrContext());
xthal_set_ccompare(1, xthal_get_ccount()+8000000); esp_err_t err = esp_register_freertos_tick_hook_for_cpu(testint, xPortGetCoreID());
esp_err_t err = esp_intr_alloc(ETS_INTERNAL_TIMER1_INTR_SOURCE, 0, &testint, NULL, &handle);
TEST_ASSERT_EQUAL_HEX32(ESP_OK, err); TEST_ASSERT_EQUAL_HEX32(ESP_OK, err);
vTaskDelay(100 / portTICK_PERIOD_MS); vTaskDelay(100 / portTICK_PERIOD_MS);
TEST_ASSERT(int_handled); TEST_ASSERT(int_handled);
TEST_ASSERT(in_int_context); TEST_ASSERT(in_int_context);
TEST_ASSERT_EQUAL_HEX32( ESP_OK, esp_intr_free(handle) ); esp_deregister_freertos_tick_hook_for_cpu(testint, xPortGetCoreID());
vTaskDelete(NULL); vTaskDelete(NULL);
} }
TEST_CASE("xPortInIsrContext test", "[freertos]") TEST_CASE("xPortInIsrContext test", "[freertos]")
{ {
xTaskCreatePinnedToCore(testthread, "tst" , 4096, NULL, 3, NULL, 0); xTaskCreatePinnedToCore(testthread, "tst", 4096, NULL, 3, NULL, 0);
vTaskDelay(150 / portTICK_PERIOD_MS); vTaskDelay(150 / portTICK_PERIOD_MS);
#if portNUM_PROCESSORS == 2 #if portNUM_PROCESSORS == 2
xTaskCreatePinnedToCore(testthread, "tst" , 4096, NULL, 3, NULL, 1); xTaskCreatePinnedToCore(testthread, "tst", 4096, NULL, 3, NULL, 1);
vTaskDelay(150 / portTICK_PERIOD_MS); vTaskDelay(150 / portTICK_PERIOD_MS);
#endif #endif
} }

View File

@ -4,9 +4,7 @@
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "xtensa/hal.h"
#include "unity.h" #include "unity.h"
#include "soc/cpu.h" #include "soc/cpu.h"
#include "test_utils.h" #include "test_utils.h"

View File

@ -189,7 +189,7 @@ TEST_CASE("Test Task_Notify", "[freertos]")
xSemaphoreGive(trigger_send_semphr); //Trigger sender task xSemaphoreGive(trigger_send_semphr); //Trigger sender task
for(int k = 0; k < NO_OF_TASKS; k++){ //Wait for sender and receiver task deletion for(int k = 0; k < NO_OF_TASKS; k++){ //Wait for sender and receiver task deletion
xSemaphoreTake(task_delete_semphr, portMAX_DELAY); TEST_ASSERT( xSemaphoreTake(task_delete_semphr, 1000 / portTICK_PERIOD_MS) );
} }
vTaskDelay(5); //Give time tasks to delete vTaskDelay(5); //Give time tasks to delete

View File

@ -1,16 +1,26 @@
#include <esp_types.h> #include <esp_types.h>
#include <stdio.h> #include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "xtensa/hal.h"
#include "unity.h" #include "unity.h"
#include "soc/cpu.h" #include "soc/cpu.h"
#include "test_utils.h" #include "test_utils.h"
#if CONFIG_IDF_TARGET_ARCH_XTENSA
#include "xtensa/hal.h"
#include "freertos/xtensa_api.h"
#define TEST_SET_INT_MASK(mask) xt_set_intset(mask)
#define TEST_CLR_INT_MASK(mask) xt_set_intclear(mask)
#elif CONFIG_IDF_TARGET_ARCH_RISCV
#include "riscv/interrupt.h"
#define TEST_SET_INT_MASK(mask) esprv_intc_int_enable(mask)
#define TEST_CLR_INT_MASK(mask) esprv_intc_int_disable(mask)
#endif
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
#define SW_ISR_LEVEL_1 7 #define SW_ISR_LEVEL_1 7
@ -25,8 +35,7 @@ static void software_isr_using_parameter_vportyield(void *arg) {
(void)arg; (void)arg;
BaseType_t yield; BaseType_t yield;
delta_enter_cycles += portGET_RUN_TIME_COUNTER_VALUE() - cycle_before_trigger; delta_enter_cycles += portGET_RUN_TIME_COUNTER_VALUE() - cycle_before_trigger;
TEST_CLR_INT_MASK(1 << SW_ISR_LEVEL_1);
xt_set_intclear(1 << SW_ISR_LEVEL_1);
xSemaphoreGiveFromISR(sync, &yield); xSemaphoreGiveFromISR(sync, &yield);
portYIELD_FROM_ISR(yield); portYIELD_FROM_ISR(yield);
@ -39,7 +48,7 @@ static void software_isr_using_no_argument_vportyield(void *arg) {
BaseType_t yield; BaseType_t yield;
delta_enter_cycles += portGET_RUN_TIME_COUNTER_VALUE() - cycle_before_trigger; delta_enter_cycles += portGET_RUN_TIME_COUNTER_VALUE() - cycle_before_trigger;
xt_set_intclear(1 << SW_ISR_LEVEL_1); TEST_CLR_INT_MASK(1 << SW_ISR_LEVEL_1);
xSemaphoreGiveFromISR(sync, &yield); xSemaphoreGiveFromISR(sync, &yield);
if(yield) { if(yield) {
@ -53,7 +62,7 @@ static void test_task(void *arg) {
for(int i = 0;i < 10000; i++) { for(int i = 0;i < 10000; i++) {
cycle_before_trigger = portGET_RUN_TIME_COUNTER_VALUE(); cycle_before_trigger = portGET_RUN_TIME_COUNTER_VALUE();
xt_set_intset(1 << SW_ISR_LEVEL_1); TEST_SET_INT_MASK(1 << SW_ISR_LEVEL_1);
xSemaphoreTake(sync, portMAX_DELAY); xSemaphoreTake(sync, portMAX_DELAY);
delta_exit_cycles += portGET_RUN_TIME_COUNTER_VALUE() - cycle_before_exit; delta_exit_cycles += portGET_RUN_TIME_COUNTER_VALUE() - cycle_before_exit;
} }
@ -103,3 +112,5 @@ TEST_CASE("isr latency test vport-yield-from-isr with parameter", "[freertos][ig
esp_intr_free(handle); esp_intr_free(handle);
} }
#endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)

View File

@ -10,7 +10,6 @@
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "unity.h" #include "unity.h"
volatile static int done; volatile static int done;

View File

@ -9,7 +9,6 @@
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "unity.h" #include "unity.h"
TEST_CASE("Panic handler", "[freertos][ignore]") TEST_CASE("Panic handler", "[freertos][ignore]")

View File

@ -9,9 +9,9 @@
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "unity.h" #include "unity.h"
#include "soc/cpu.h" #include "soc/cpu.h"
#include "hal/cpu_hal.h"
#include "test_utils.h" #include "test_utils.h"
#include "sdkconfig.h" #include "sdkconfig.h"
@ -31,7 +31,7 @@ static void task_send_to_queue(void *param)
while(!trigger) {} while(!trigger) {}
RSR(CCOUNT, ccount); ccount = cpu_hal_get_cycle_count();
flag = true; flag = true;
xQueueSendToBack(queue, &ccount, 0); xQueueSendToBack(queue, &ccount, 0);
/* This is to ensure that higher priority task /* This is to ensure that higher priority task
@ -60,7 +60,7 @@ TEST_CASE("Yield from lower priority task, same CPU", "[freertos]")
uint32_t yield_ccount, now_ccount, delta; uint32_t yield_ccount, now_ccount, delta;
TEST_ASSERT( xQueueReceive(queue, &yield_ccount, 100 / portTICK_PERIOD_MS) ); TEST_ASSERT( xQueueReceive(queue, &yield_ccount, 100 / portTICK_PERIOD_MS) );
RSR(CCOUNT, now_ccount); now_ccount = cpu_hal_get_cycle_count();
TEST_ASSERT( flag ); TEST_ASSERT( flag );
delta = now_ccount - yield_ccount; delta = now_ccount - yield_ccount;
@ -92,12 +92,12 @@ TEST_CASE("Yield from lower priority task, other CPU", "[freertos]")
vTaskDelay(2); /* make sure everything is set up */ vTaskDelay(2); /* make sure everything is set up */
trigger = true; trigger = true;
RSR(CCOUNT, trigger_ccount); trigger_ccount = cpu_hal_get_cycle_count();
// yield_ccount is not useful in this test as it's the other core's CCOUNT // yield_ccount is not useful in this test as it's the other core's CCOUNT
// so we use trigger_ccount instead // so we use trigger_ccount instead
TEST_ASSERT( xQueueReceive(queue, &yield_ccount, 100 / portTICK_PERIOD_MS) ); TEST_ASSERT( xQueueReceive(queue, &yield_ccount, 100 / portTICK_PERIOD_MS) );
RSR(CCOUNT, now_ccount); now_ccount = cpu_hal_get_cycle_count();
TEST_ASSERT( flag ); TEST_ASSERT( flag );
delta = now_ccount - trigger_ccount; delta = now_ccount - trigger_ccount;

View File

@ -9,9 +9,9 @@
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "unity.h" #include "unity.h"
#include "soc/cpu.h" #include "soc/cpu.h"
#include "hal/cpu_hal.h"
#include "test_utils.h" #include "test_utils.h"
@ -20,11 +20,11 @@
static uint32_t start, end; static uint32_t start, end;
#define BENCHMARK_START() do { \ #define BENCHMARK_START() do { \
RSR(CCOUNT, start); \ start = cpu_hal_get_cycle_count(); \
} while(0) } while(0)
#define BENCHMARK_END(OPERATION) do { \ #define BENCHMARK_END(OPERATION) do { \
RSR(CCOUNT, end); \ end = cpu_hal_get_cycle_count(); \
printf("%s took %d cycles/op (%d cycles for %d ops)\n", \ printf("%s took %d cycles/op (%d cycles for %d ops)\n", \
OPERATION, (end - start)/REPEAT_OPS, \ OPERATION, (end - start)/REPEAT_OPS, \
(end - start), REPEAT_OPS); \ (end - start), REPEAT_OPS); \

View File

@ -5,7 +5,6 @@
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "unity.h" #include "unity.h"
#include "soc/cpu.h" #include "soc/cpu.h"
#include "test_utils.h" #include "test_utils.h"

View File

@ -7,7 +7,6 @@
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "freertos/timers.h" #include "freertos/timers.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "unity.h" #include "unity.h"
#include "soc/cpu.h" #include "soc/cpu.h"
#include "test_utils.h" #include "test_utils.h"

View File

@ -11,6 +11,7 @@
#include "test_utils.h" #include "test_utils.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
static __thread int tl_test_var1; static __thread int tl_test_var1;
static __thread uint8_t tl_test_var2 = 55; static __thread uint8_t tl_test_var2 = 55;
@ -108,3 +109,4 @@ TEST_CASE("TLS test", "[freertos]")
} }
vTaskDelay(10); /* Make sure idle task can clean up s_task, before it goes out of scope */ vTaskDelay(10); /* Make sure idle task can clean up s_task, before it goes out of scope */
} }
#endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)

View File

@ -5,10 +5,13 @@
#include <esp_types.h> #include <esp_types.h>
#include <stdio.h> #include <stdio.h>
#include <esp_heap_caps.h> #include <esp_heap_caps.h>
#include "sdkconfig.h"
#include "esp_system.h" #include "esp_system.h"
#include "freertos/xtensa_api.h"
#include "unity.h" #include "unity.h"
#if CONFIG_IDF_TARGET_ARCH_XTENSA
#include "freertos/xtensa_api.h"
#ifdef CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY #ifdef CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY
TEST_CASE("LoadStore Exception handler", "[freertos]") TEST_CASE("LoadStore Exception handler", "[freertos]")
{ {
@ -119,4 +122,5 @@ TEST_CASE("LoadStore Exception handler", "[freertos]")
TEST_ASSERT_TRUE(heap_caps_check_integrity_all(true)); TEST_ASSERT_TRUE(heap_caps_check_integrity_all(true));
heap_caps_free(arr); heap_caps_free(arr);
} }
#endif #endif // CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY
#endif // CONFIG_IDF_TARGET_ARCH_XTENSA

View File

@ -2,7 +2,7 @@ COMPONENTS_DIR=../..
COMPILER_ICLUDE_DIR=$(shell echo `which xtensa-esp32-elf-gcc | xargs dirname | xargs dirname`/xtensa-esp32-elf) COMPILER_ICLUDE_DIR=$(shell echo `which xtensa-esp32-elf-gcc | xargs dirname | xargs dirname`/xtensa-esp32-elf)
CFLAGS=-std=gnu99 -Og -ggdb -ffunction-sections -fdata-sections -nostdlib -Wall -Werror=all -Wno-int-to-pointer-cast -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-macro-redefined -Wno-constant-conversion -Wno-incompatible-pointer-types-discards-qualifiers -Wno-typedef-redefinition -Wno-incompatible-pointer-types -Wextra \ CFLAGS=-std=gnu99 -Og -ggdb -ffunction-sections -fdata-sections -nostdlib -Wall -Werror=all -Wno-int-to-pointer-cast -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-macro-redefined -Wno-constant-conversion -Wno-incompatible-pointer-types-discards-qualifiers -Wno-typedef-redefinition -Wno-incompatible-pointer-types -Wextra \
-Wno-unused-parameter -Wno-sign-compare -Wno-address -Wno-unused-variable -DESP_PLATFORM -D IDF_VER=\"v3.1\" -MMD -MP -DWITH_POSIX -DLWIP_NO_CTYPE_H=1 -Wno-unused-parameter -Wno-sign-compare -Wno-address -Wno-unused-variable -DESP_PLATFORM -D IDF_VER=\"v3.1\" -MMD -MP -DWITH_POSIX -DLWIP_NO_CTYPE_H=1
INC_DIRS=-I . -I ./build/config -I $(COMPONENTS_DIR)/newlib/platform_include -I $(COMPONENTS_DIR)/newlib/include -I $(COMPONENTS_DIR)/driver/include -I $(COMPONENTS_DIR)/esp32/include -I $(COMPONENTS_DIR)/ethernet/include -I $(COMPONENTS_DIR)/freertos/include -I $(COMPONENTS_DIR)/heap/include -I $(COMPONENTS_DIR)/lwip/lwip/src/include -I $(COMPONENTS_DIR)/lwip/include/apps -I $(COMPONENTS_DIR)/lwip/lwip/src/include/netif -I $(COMPONENTS_DIR)/lwip/lwip/src/include/posix -I $(COMPONENTS_DIR)/lwip/port/esp32/include -I $(COMPONENTS_DIR)/lwip/lwip/src/include/posix -I $(COMPONENTS_DIR)/lwip/include/apps/ping -I $(COMPONENTS_DIR)/lwip/include/apps/sntp -I $(COMPONENTS_DIR)/soc/esp32/include -I $(COMPONENTS_DIR)/soc/include -I $(COMPONENTS_DIR)/tcpip_adapter/include -I $(COMPONENTS_DIR)/esp_rom/include -I $(COMPONENTS_DIR)/esp_common/include -I $(COMPONENTS_DIR)/esp_hw_support/include -I $(COMPONENTS_DIR)/xtensa/include -I $(COMPONENTS_DIR)/xtensa/esp32/include -I $(COMPONENTS_DIR)/esp_wifi/include -I $(COMPONENTS_DIR)/esp_event/include -I $(COMPONENTS_DIR)/freertos/xtensa/include -I $(COMPONENTS_DIR)/esp_system/include -I $(COMPONENTS_DIR)/esp_timer/include -I $(COMPONENTS_DIR)/soc/include -I $(COMPONENTS_DIR)/soc/include -I $(COMPONENTS_DIR)/soc/src/esp32/include -I $(COMPONENTS_DIR)/soc/esp32/include -I $(COMPONENTS_DIR)/esp_netif/include -I $(COMPONENTS_DIR)/esp_eth/include -I $(COMPONENTS_DIR)/esp_netif/lwip -I $(COMPONENTS_DIR)/hal/include -I $(COMPONENTS_DIR)/hal/esp32/include -I $(COMPILER_ICLUDE_DIR)/include INC_DIRS=-I . -I ./build/config -I $(COMPONENTS_DIR)/newlib/platform_include -I $(COMPONENTS_DIR)/newlib/include -I $(COMPONENTS_DIR)/driver/include -I $(COMPONENTS_DIR)/esp32/include -I $(COMPONENTS_DIR)/ethernet/include -I $(COMPONENTS_DIR)/freertos/include -I $(COMPONENTS_DIR)/heap/include -I $(COMPONENTS_DIR)/lwip/lwip/src/include -I $(COMPONENTS_DIR)/lwip/include/apps -I $(COMPONENTS_DIR)/lwip/lwip/src/include/netif -I $(COMPONENTS_DIR)/lwip/lwip/src/include/posix -I $(COMPONENTS_DIR)/lwip/port/esp32/include -I $(COMPONENTS_DIR)/lwip/lwip/src/include/posix -I $(COMPONENTS_DIR)/lwip/include/apps/ping -I $(COMPONENTS_DIR)/lwip/include/apps/sntp -I $(COMPONENTS_DIR)/soc/esp32/include -I $(COMPONENTS_DIR)/soc/include -I $(COMPONENTS_DIR)/tcpip_adapter/include -I $(COMPONENTS_DIR)/esp_rom/include -I $(COMPONENTS_DIR)/esp_common/include -I $(COMPONENTS_DIR)/esp_hw_support/include -I $(COMPONENTS_DIR)/xtensa/include -I $(COMPONENTS_DIR)/xtensa/esp32/include -I $(COMPONENTS_DIR)/esp_wifi/include -I $(COMPONENTS_DIR)/esp_event/include -I $(COMPONENTS_DIR)/freertos/port/xtensa/include -I $(COMPONENTS_DIR)/esp_system/include -I $(COMPONENTS_DIR)/esp_timer/include -I $(COMPONENTS_DIR)/soc/include -I $(COMPONENTS_DIR)/soc/include -I $(COMPONENTS_DIR)/soc/src/esp32/include -I $(COMPONENTS_DIR)/soc/esp32/include -I $(COMPONENTS_DIR)/esp_netif/include -I $(COMPONENTS_DIR)/esp_eth/include -I $(COMPONENTS_DIR)/esp_netif/lwip -I $(COMPONENTS_DIR)/hal/include -I $(COMPONENTS_DIR)/hal/esp32/include -I $(COMPILER_ICLUDE_DIR)/include
TEST_NAME=test TEST_NAME=test
FUZZ=afl-fuzz FUZZ=afl-fuzz
GEN_CFG=generate_config GEN_CFG=generate_config

View File

@ -18,7 +18,7 @@ CFLAGS=-g -Wno-unused-value -Wno-missing-declarations -Wno-pointer-bool-conversi
-I$(COMPONENTS_DIR)/esp_system/include \ -I$(COMPONENTS_DIR)/esp_system/include \
-I$(COMPONENTS_DIR)/esp_timer/include \ -I$(COMPONENTS_DIR)/esp_timer/include \
-I$(COMPONENTS_DIR)/esp_wifi/include \ -I$(COMPONENTS_DIR)/esp_wifi/include \
-I$(COMPONENTS_DIR)/freertos/xtensa/include \ -I$(COMPONENTS_DIR)/freertos/port/xtensa/include \
-I$(COMPONENTS_DIR)/freertos \ -I$(COMPONENTS_DIR)/freertos \
-I$(COMPONENTS_DIR)/freertos/include \ -I$(COMPONENTS_DIR)/freertos/include \
-I$(COMPONENTS_DIR)/hal/include \ -I$(COMPONENTS_DIR)/hal/include \

View File

@ -7,7 +7,7 @@ components/xtensa/esp32/include/xtensa/config/
components/newlib/platform_include/ components/newlib/platform_include/
components/freertos/include/freertos/ components/freertos/include/freertos/
components/freertos/xtensa/include/freertos/ components/freertos/port/xtensa/include/freertos/
components/log/include/esp_log_internal.h components/log/include/esp_log_internal.h

View File

@ -183,7 +183,7 @@ function run_tests()
# and therefore should rebuild # and therefore should rebuild
assert_rebuilt newlib/syscall_table.o assert_rebuilt newlib/syscall_table.o
assert_rebuilt nvs_flash/src/nvs_api.o assert_rebuilt nvs_flash/src/nvs_api.o
assert_rebuilt freertos/xtensa/xtensa_vectors.o assert_rebuilt freertos/port/xtensa/xtensa_vectors.o
print_status "Updating project Makefile triggers full recompile" print_status "Updating project Makefile triggers full recompile"
make make
@ -193,7 +193,7 @@ function run_tests()
# similar to previous test # similar to previous test
assert_rebuilt newlib/syscall_table.o assert_rebuilt newlib/syscall_table.o
assert_rebuilt nvs_flash/src/nvs_api.o assert_rebuilt nvs_flash/src/nvs_api.o
assert_rebuilt freertos/xtensa/xtensa_vectors.o assert_rebuilt freertos/port/xtensa/xtensa_vectors.o
print_status "print_flash_cmd target should produce one line of output" print_status "print_flash_cmd target should produce one line of output"
make make

View File

@ -220,7 +220,7 @@ function run_tests()
# and therefore should rebuild # and therefore should rebuild
assert_rebuilt esp-idf/newlib/CMakeFiles/${IDF_COMPONENT_PREFIX}_newlib.dir/syscall_table.c.obj assert_rebuilt esp-idf/newlib/CMakeFiles/${IDF_COMPONENT_PREFIX}_newlib.dir/syscall_table.c.obj
assert_rebuilt esp-idf/nvs_flash/CMakeFiles/${IDF_COMPONENT_PREFIX}_nvs_flash.dir/src/nvs_api.cpp.obj assert_rebuilt esp-idf/nvs_flash/CMakeFiles/${IDF_COMPONENT_PREFIX}_nvs_flash.dir/src/nvs_api.cpp.obj
assert_rebuilt esp-idf/freertos/CMakeFiles/${IDF_COMPONENT_PREFIX}_freertos.dir/xtensa/xtensa_vectors.S.obj assert_rebuilt esp-idf/freertos/CMakeFiles/${IDF_COMPONENT_PREFIX}_freertos.dir/port/xtensa/xtensa_vectors.S.obj
mv sdkconfig.bak sdkconfig mv sdkconfig.bak sdkconfig
print_status "Updating project CMakeLists.txt triggers full recompile" print_status "Updating project CMakeLists.txt triggers full recompile"
@ -235,7 +235,7 @@ function run_tests()
# similar to previous test # similar to previous test
assert_rebuilt esp-idf/newlib/CMakeFiles/${IDF_COMPONENT_PREFIX}_newlib.dir/syscall_table.c.obj assert_rebuilt esp-idf/newlib/CMakeFiles/${IDF_COMPONENT_PREFIX}_newlib.dir/syscall_table.c.obj
assert_rebuilt esp-idf/nvs_flash/CMakeFiles/${IDF_COMPONENT_PREFIX}_nvs_flash.dir/src/nvs_api.cpp.obj assert_rebuilt esp-idf/nvs_flash/CMakeFiles/${IDF_COMPONENT_PREFIX}_nvs_flash.dir/src/nvs_api.cpp.obj
assert_rebuilt esp-idf/freertos/CMakeFiles/${IDF_COMPONENT_PREFIX}_freertos.dir/xtensa/xtensa_vectors.S.obj assert_rebuilt esp-idf/freertos/CMakeFiles/${IDF_COMPONENT_PREFIX}_freertos.dir/port/xtensa/xtensa_vectors.S.obj
mv sdkconfig.bak sdkconfig mv sdkconfig.bak sdkconfig
print_status "Can build with Ninja (no idf.py)" print_status "Can build with Ninja (no idf.py)"