rt-thread/bsp/ESP32_C3/rtt.patch

600 lines
22 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 92402217b821c8da7e2a188352f095caaf0818d1 Mon Sep 17 00:00:00 2001
From: tangzz98 <tangz98@outlook.com>
Date: Tue, 13 Sep 2022 18:05:44 -0400
Subject: [PATCH 1/2] Add config for RT-Thread
---
Kconfig | 4 +
components/driver/deprecated/i2s_legacy.c | 4 +
components/driver/uart.c | 4 +
components/esp_system/crosscore_int.c | 5 +-
.../esp_system/ld/esp32c3/sections.ld.in | 37 ++++
.../port/arch/riscv/expression_with_stack.c | 8 +
components/esp_system/startup.c | 9 +
components/esp_system/task_wdt.c | 4 +
components/esp_timer/src/esp_timer.c | 2 +
components/freertos/CMakeLists.txt | 50 ++++-
.../freertos_tasks_c_additions.h | 6 +-
components/riscv/vectors.S | 179 ++++++++++++++++++
12 files changed, 309 insertions(+), 3 deletions(-)
diff --git a/Kconfig b/Kconfig
index c86ebeaaef..56d062b2db 100644
--- a/Kconfig
+++ b/Kconfig
@@ -101,6 +101,10 @@ mainmenu "Espressif IoT Development Framework Configuration"
bool
default "y" if IDF_TARGET="linux"
+ config IDF_RTOS_RTTHREAD
+ bool "RT-THREAD SELECT"
+ default "n"
+
config IDF_FIRMWARE_CHIP_ID
hex
default 0x0000 if IDF_TARGET_ESP32
diff --git a/components/driver/deprecated/i2s_legacy.c b/components/driver/deprecated/i2s_legacy.c
index 2e36ab2608..92edf9d2bb 100644
--- a/components/driver/deprecated/i2s_legacy.c
+++ b/components/driver/deprecated/i2s_legacy.c
@@ -1600,7 +1600,11 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config,
i2s_obj->i2s_queue = xQueueCreate(queue_size, sizeof(i2s_event_t));
ESP_GOTO_ON_FALSE(i2s_obj->i2s_queue, ESP_ERR_NO_MEM, err, TAG, "I2S queue create failed");
*((QueueHandle_t *) i2s_queue) = i2s_obj->i2s_queue;
+#if !defined CONFIG_IDF_RTOS_RTTHREAD
ESP_LOGD(TAG, "queue free spaces: %d", uxQueueSpacesAvailable(i2s_obj->i2s_queue));
+#else
+ ESP_LOGD(TAG, "queue free spaces: %lu", uxQueueSpacesAvailable(i2s_obj->i2s_queue));
+#endif
} else {
i2s_obj->i2s_queue = NULL;
}
diff --git a/components/driver/uart.c b/components/driver/uart.c
index b68b2900e1..63c9841380 100644
--- a/components/driver/uart.c
+++ b/components/driver/uart.c
@@ -1603,7 +1603,11 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
uart_pattern_queue_reset(uart_num, UART_PATTERN_DET_QLEN_DEFAULT);
if (uart_queue) {
*uart_queue = p_uart_obj[uart_num]->event_queue;
+#if !defined CONFIG_IDF_RTOS_RTTHREAD
ESP_LOGI(UART_TAG, "queue free spaces: %d", uxQueueSpacesAvailable(p_uart_obj[uart_num]->event_queue));
+#else
+ ESP_LOGI(UART_TAG, "queue free spaces: %lu", uxQueueSpacesAvailable(p_uart_obj[uart_num]->event_queue));
+#endif
}
} else {
ESP_LOGE(UART_TAG, "UART driver already installed");
diff --git a/components/esp_system/crosscore_int.c b/components/esp_system/crosscore_int.c
index 4aae2a2540..8a9079de64 100644
--- a/components/esp_system/crosscore_int.c
+++ b/components/esp_system/crosscore_int.c
@@ -95,13 +95,14 @@ static void IRAM_ATTR esp_crosscore_isr(void *arg) {
if (my_reason_val & REASON_PRINT_BACKTRACE) {
esp_backtrace_print(100);
}
-
+#ifdef CONFIG_ESP_TASK_WDT
if (my_reason_val & REASON_TWDT_ABORT) {
extern void task_wdt_timeout_abort_xtensa(bool);
/* Called from a crosscore interrupt, thus, we are not the core that received
* the TWDT interrupt, call the function with `false` as a parameter. */
task_wdt_timeout_abort_xtensa(false);
}
+#endif
#endif // CONFIG_IDF_TARGET_ARCH_XTENSA
}
@@ -171,7 +172,9 @@ void IRAM_ATTR esp_crosscore_int_send_print_backtrace(int core_id)
esp_crosscore_int_send(core_id, REASON_PRINT_BACKTRACE);
}
+#ifdef CONFIG_ESP_TASK_WDT
void IRAM_ATTR esp_crosscore_int_send_twdt_abort(int core_id) {
esp_crosscore_int_send(core_id, REASON_TWDT_ABORT);
}
#endif
+#endif
diff --git a/components/esp_system/ld/esp32c3/sections.ld.in b/components/esp_system/ld/esp32c3/sections.ld.in
index d6670bf759..1d51ffeea0 100644
--- a/components/esp_system/ld/esp32c3/sections.ld.in
+++ b/components/esp_system/ld/esp32c3/sections.ld.in
@@ -178,6 +178,26 @@ SECTIONS
_noinit_end = ABSOLUTE(.);
} > dram0_0_seg
+ .stack :
+ {
+ . = ALIGN(8);
+ __STACKSIZE__ = 40960;
+ __stack_start__ = .;
+ *(.stack*)
+ . += __STACKSIZE__;
+ __stack_cpu0 = .;
+ __stack_end__ = .;
+ } > dram0_0_seg
+
+ .heap :
+ {
+ . = ALIGN(8);
+ __HEAPSIZE__ = 40960;
+ __heap_start__ = .;
+ . += __HEAPSIZE__;
+ __heap_end__ = .;
+ } > dram0_0_seg
+
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
@@ -218,6 +238,17 @@ SECTIONS
*(.fini)
*(.gnu.version)
+ /* section information for finsh shell */
+ . = ALIGN(8);
+ __fsymtab_start = .;
+ KEEP(*(FSymTab))
+ __fsymtab_end = .;
+ . = ALIGN(8);
+ __vsymtab_start = .;
+ KEEP(*(VSymTab))
+ __vsymtab_end = .;
+ . = ALIGN(8);
+
/** CPU will try to prefetch up to 16 bytes of
* of instructions. This means that any configuration (e.g. MMU, PMS) must allow
* safe access to up to 16 bytes after the last real instruction, add
@@ -318,6 +349,12 @@ SECTIONS
_esp_system_init_fn_array_start = ABSOLUTE(.);
KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
+ /* section information for initial. */
+ . = ALIGN(4);
+ __rt_init_start = .;
+ KEEP(*(SORT(.rti_fn*)))
+ __rt_init_end = .;
+ . = ALIGN(4);
_rodata_end = ABSOLUTE(.);
/* Literals are also RO data. */
_lit4_start = ABSOLUTE(.);
diff --git a/components/esp_system/port/arch/riscv/expression_with_stack.c b/components/esp_system/port/arch/riscv/expression_with_stack.c
index 07d22bf3aa..5eac5a88f8 100644
--- a/components/esp_system/port/arch/riscv/expression_with_stack.c
+++ b/components/esp_system/port/arch/riscv/expression_with_stack.c
@@ -18,6 +18,8 @@
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
+#if !defined CONFIG_IDF_RTOS_RTTHREAD
+
static portMUX_TYPE shared_stack_spinlock = portMUX_INITIALIZER_UNLOCKED;
static void *current_task_stack = NULL;
@@ -46,9 +48,12 @@ static StackType_t *esp_switch_stack_setup(StackType_t *stack, size_t stack_size
return ((StackType_t *)adjusted_top_of_stack);
}
+#endif
+
void esp_execute_shared_stack_function(SemaphoreHandle_t lock, void *stack, size_t stack_size, shared_stack_function function)
{
+#if !defined CONFIG_IDF_RTOS_RTTHREAD
assert(lock);
assert(stack);
assert(stack_size > 0 && stack_size >= CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE);
@@ -70,4 +75,7 @@ void esp_execute_shared_stack_function(SemaphoreHandle_t lock, void *stack, size
portEXIT_CRITICAL(&shared_stack_spinlock);
xSemaphoreGive(lock);
+#else
+ function();
+#endif
}
diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c
index 0feda4e9f5..b1752d91a0 100644
--- a/components/esp_system/startup.c
+++ b/components/esp_system/startup.c
@@ -72,6 +72,10 @@
#include "esp_psram.h"
#include "esp_private/esp_psram_extram.h"
#endif
+
+#if CONFIG_IDF_RTOS_RTTHREAD
+#include "rtthread.h"
+#endif
/***********************************************/
#include "esp_private/startup_internal.h"
@@ -266,6 +270,11 @@ static void do_core_init(void)
app CPU, and when that is not up yet, the memory will be inaccessible and heap_caps_init may
fail initializing it properly. */
heap_caps_init();
+#if CONFIG_IDF_RTOS_RTTHREAD && defined RT_USING_HEAP
+ extern int __heap_start__;
+ extern int __heap_end__;
+ rt_system_heap_init((void *)&__heap_start__, (void *)&__heap_end__);
+#endif
// When apptrace module is enabled, there will be SEGGER_SYSVIEW calls in the newlib init.
// SEGGER_SYSVIEW relies on apptrace module
diff --git a/components/esp_system/task_wdt.c b/components/esp_system/task_wdt.c
index 58d1247bf0..60330edf8a 100644
--- a/components/esp_system/task_wdt.c
+++ b/components/esp_system/task_wdt.c
@@ -29,6 +29,8 @@
#include "esp_private/eh_frame_parser.h"
#endif // CONFIG_ESP_SYSTEM_USE_EH_FRAME
+#if CONFIG_ESP_TASK_WDT
+
#if CONFIG_IDF_TARGET_ARCH_RISCV && !CONFIG_ESP_SYSTEM_USE_EH_FRAME
/* Function used to print all the registers pointed by the given frame .*/
extern void panic_print_registers(const void *frame, int core);
@@ -784,3 +786,5 @@ esp_err_t esp_task_wdt_status(TaskHandle_t task_handle)
return ret;
}
+
+#endif
diff --git a/components/esp_timer/src/esp_timer.c b/components/esp_timer/src/esp_timer.c
index 3ca19f642f..78779a08b3 100644
--- a/components/esp_timer/src/esp_timer.c
+++ b/components/esp_timer/src/esp_timer.c
@@ -460,10 +460,12 @@ out:
return ESP_ERR_NO_MEM;
}
+#if !defined CONFIG_IDF_RTOS_RTTHREAD
ESP_SYSTEM_INIT_FN(esp_timer_startup_init, BIT(0), 100)
{
return esp_timer_init();
}
+#endif
esp_err_t esp_timer_deinit(void)
{
diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt
index 78a8e4ae4e..5cd54494f6 100644
--- a/components/freertos/CMakeLists.txt
+++ b/components/freertos/CMakeLists.txt
@@ -6,7 +6,36 @@ endif()
idf_build_get_property(target IDF_TARGET)
-if(CONFIG_FREERTOS_SMP)
+if(CONFIG_IDF_RTOS_RTTHREAD)
+ set(freertos_root "../../../FreeRTOS_Wrapper-latest/FreeRTOS")
+ set(srcs
+ "${freertos_root}/portable/esp-idf/riscv/port.c")
+
+ set(include_dirs
+ "${freertos_root}/include"
+ esp_additions/include
+ esp_additions/include/freertos
+ "${freertos_root}/portable/esp-idf/riscv/include")
+
+ set(private_include_dirs
+ "${freertos_root}/portable/esp-idf/riscv/include/freertos")
+
+ list(APPEND srcs
+ "${freertos_root}/portable/esp-idf/port_common.c"
+ "${freertos_root}/portable/esp-idf/port_rt.c"
+ "${freertos_root}/event_groups.c"
+ "${freertos_root}/queue.c"
+ "${freertos_root}/tasks.c"
+ "${freertos_root}/timers.c"
+ "${freertos_root}/list.c"
+ "FreeRTOS-openocd.c"
+ "esp_additions/freertos_v8_compat.c")
+
+ list(APPEND private_include_dirs
+ "${freertos_root}/include/freertos"
+ "esp_additions/private_include")
+
+elseif(CONFIG_FREERTOS_SMP)
set(ldfragments linker_smp.lf)
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
set(srcs
@@ -133,11 +162,19 @@ else()
endif()
endif()
+if(CONFIG_IDF_RTOS_RTTHREAD)
+idf_component_register(SRCS "${srcs}"
+ INCLUDE_DIRS ${include_dirs}
+ PRIV_INCLUDE_DIRS ${private_include_dirs}
+ PRIV_REQUIRES soc esp_pm)
+else()
idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS ${include_dirs}
PRIV_INCLUDE_DIRS ${private_include_dirs}
LDFRAGMENTS "${ldfragments}"
+ REQUIRES main
PRIV_REQUIRES soc esp_pm)
+endif()
idf_component_get_property(COMPONENT_DIR freertos COMPONENT_DIR)
@@ -153,6 +190,16 @@ if(CONFIG_FREERTOS_DEBUG_OCDAWARE)
idf_build_set_property(COMPILE_OPTIONS "-DconfigENABLE_FREERTOS_DEBUG_OCDAWARE=1" APPEND)
endif()
+if(CONFIG_IDF_RTOS_RTTHREAD)
+set_source_files_properties(
+ tasks.c
+ event_groups.c
+ timers.c
+ queue.c
+ PROPERTIES COMPILE_DEFINITIONS
+ _ESP_FREERTOS_INTERNAL
+ )
+else()
set_source_files_properties(
tasks.c
event_groups.c
@@ -162,6 +209,7 @@ set_source_files_properties(
PROPERTIES COMPILE_DEFINITIONS
_ESP_FREERTOS_INTERNAL
)
+endif()
# The freertos component provides the `start_app` and `start_app_other_cores`
# if it is included in the build. It then calls `app_main`
diff --git a/components/freertos/esp_additions/private_include/freertos_tasks_c_additions.h b/components/freertos/esp_additions/private_include/freertos_tasks_c_additions.h
index f5ecdbb5a9..96fc4f73ce 100644
--- a/components/freertos/esp_additions/private_include/freertos_tasks_c_additions.h
+++ b/components/freertos/esp_additions/private_include/freertos_tasks_c_additions.h
@@ -34,8 +34,9 @@
struct _reent *__getreent(void)
{
// No lock needed because if this changes, we won't be running anymore.
- TCB_t *pxCurTask = xTaskGetCurrentTaskHandle();
struct _reent *ret;
+#if !defined CONFIG_IDF_RTOS_RTTHREAD
+ TCB_t *pxCurTask = xTaskGetCurrentTaskHandle();
if (pxCurTask == NULL) {
// No task running. Return global struct.
ret = _GLOBAL_REENT;
@@ -43,6 +44,9 @@ struct _reent *__getreent(void)
// We have a task; return its reentrant struct.
ret = &pxCurTask->xNewLib_reent;
}
+#else
+ ret = _GLOBAL_REENT;
+#endif
return ret;
}
#endif // configUSE_NEWLIB_REENTRANT == 1
diff --git a/components/riscv/vectors.S b/components/riscv/vectors.S
index 9b868280db..23236f3d8d 100644
--- a/components/riscv/vectors.S
+++ b/components/riscv/vectors.S
@@ -10,6 +10,9 @@
#include "soc/soc_caps.h"
#include "sdkconfig.h"
+#define STORE sw
+#define LOAD lw
+#define REGBYTES 4
.equ SAVE_REGS, 32
.equ CONTEXT_SIZE, (SAVE_REGS * 4)
@@ -210,6 +213,8 @@ _return_from_exception:
*/
.global _interrupt_handler
.type _interrupt_handler, @function
+#ifndef CONFIG_IDF_RTOS_RTTHREAD
+
_interrupt_handler:
/* Start by saving the general purpose registers and the PC value before
* the interrupt happened. */
@@ -308,3 +313,177 @@ _interrupt_handler:
/* exit, this will also re-enable the interrupts */
mret
.size _interrupt_handler, .-_interrupt_handler
+#else
+_interrupt_handler:
+ /* 此时CPU的sp = from_thread->sp */
+ /* 注意: 在这里并没有将mepc的值赋值为from_thread栈中的epc但后面会赋值 */
+ addi sp, sp, -32 * REGBYTES /* sp = sp - 32 * 4 栈指针向下偏移32个寄存器长度用来将CPU的寄存器保存到from_thread的栈中*/
+ STORE x1, 1 * REGBYTES(sp) /* 将CPU的x1寄存器即ra寄存器保存到from_thread->栈中 */
+
+ li t0, 0x80 /* t0 = 0x80 */
+ STORE t0, 2 * REGBYTES(sp) /* mstatus = t0, 即关闭全局中断 */
+
+ /* 将 CPU 的其他寄存器的值保存到from_thread的任务栈中 */
+ STORE x4, 4 * REGBYTES(sp)
+ STORE x5, 5 * REGBYTES(sp)
+ STORE x6, 6 * REGBYTES(sp)
+ STORE x7, 7 * REGBYTES(sp)
+ STORE x8, 8 * REGBYTES(sp)
+ STORE x9, 9 * REGBYTES(sp)
+ STORE x10, 10 * REGBYTES(sp)
+ STORE x11, 11 * REGBYTES(sp)
+ STORE x12, 12 * REGBYTES(sp)
+ STORE x13, 13 * REGBYTES(sp)
+ STORE x14, 14 * REGBYTES(sp)
+ STORE x15, 15 * REGBYTES(sp)
+ STORE x16, 16 * REGBYTES(sp)
+ STORE x17, 17 * REGBYTES(sp)
+ STORE x18, 18 * REGBYTES(sp)
+ STORE x19, 19 * REGBYTES(sp)
+ STORE x20, 20 * REGBYTES(sp)
+ STORE x21, 21 * REGBYTES(sp)
+ STORE x22, 22 * REGBYTES(sp)
+ STORE x23, 23 * REGBYTES(sp)
+ STORE x24, 24 * REGBYTES(sp)
+ STORE x25, 25 * REGBYTES(sp)
+ STORE x26, 26 * REGBYTES(sp)
+ STORE x27, 27 * REGBYTES(sp)
+ STORE x28, 28 * REGBYTES(sp)
+ STORE x29, 29 * REGBYTES(sp)
+ STORE x30, 30 * REGBYTES(sp)
+ STORE x31, 31 * REGBYTES(sp)
+
+ /* 备份 CPU 的 sp (这时CPU的sp其实就是from thread的sp指针) 寄存器的值到 s0 寄存器中下面会使用s0恢复 CPU 的寄存器 */
+ move s0, sp /* s0 = sp */
+
+ /* 在中断函数中中断函数中调用的C函数需要使用 sp 这里,在中断函数中,使用的 sp 为,系统的栈资源 */
+ /* switch to interrupt stack */
+ la sp, __stack_end__ /* sp = _sp */
+
+ /* interrupt handle */
+ /* 注意: 在调用C函数之前,比如sp的值为0x30001000, 在执行完C函数后sp的值还是会变成 0x30001000 */
+ call rt_interrupt_enter /* 执行所有的中断函数前,调用该函数 */
+
+ csrr s1, mcause
+ csrr s2, mstatus
+
+ /* Save the interrupt threshold level */
+ la t0, INTERRUPT_CORE0_CPU_INT_THRESH_REG
+ lw s3, 0(t0)
+
+ li t2, 0x7fffffff
+ and t1, s1, t2 /* t1 = mcause & mask */
+ slli t1, t1, 2 /* t1 = mcause * 4 */
+ la t2, INTC_INT_PRIO_REG(0)
+ add t1, t2, t1 /* t1 = INTC_INT_PRIO_REG + 4 * mcause */
+ lw t2, 0(t1) /* t2 = INTC_INT_PRIO_REG[mcause] */
+ addi t2, t2, 1 /* t2 = t2 +1 */
+ sw t2, 0(t0) /* INTERRUPT_CORE0_CPU_INT_THRESH_REG = t2 */
+ fence
+
+ li t0, 0x8
+ csrrs t0, mstatus, t0
+
+ /* call the C dispatcher */
+ mv a0, sp /* argument 1, stack pointer */
+ mv a1, s1 /* argument 2, interrupt number (mcause) */
+ /* mask off the interrupt flag of mcause */
+ li t0, 0x7fffffff
+ and a1, a1, t0
+ jal _global_interrupt_handler
+
+ li t0, 0x8
+ csrrc t0, mstatus, t0
+
+ /* restore the interrupt threshold level */
+ la t0, INTERRUPT_CORE0_CPU_INT_THRESH_REG
+ sw s3, 0(t0)
+ fence
+
+ call rt_interrupt_leave /* 执行所有的中断函数后,调用该函数 */
+
+ /* 上面将保存执行中断服务函数之前的CPU的sp寄存器到了s0所指向的位置处当执行完中断服务函数需要将之前的CPU寄存器恢复一下,此时sp又变成了from thread的sp了 */
+ move sp, s0 /* sp = s0 */
+
+ /* 下面两句话,相当于将 rt_thread_switch_interrupt_flag 值赋值给了s2 */
+ /* 将 rt_thread_switch_interrupt_flag 的地址值,赋值给 s0 寄存器*/
+ la s0, rt_thread_switch_interrupt_flag /* s0 = &rt_thread_switch_interrupt_flag */
+ /* 将 s0 所指向的地址处的内容,取出来,赋值给 s2 寄存器,其实就是将 rt_thread_switch_interrupt_flag 的值,赋值给了 s2 寄存器*/
+ lw s2, 0(s0) /* s2 = *s0 = rt_thread_switch_interrupt_flag */
+
+ /* 如果 s2的值即 rt_thread_switch_interrupt_flag 值如果不为0则需要继续执行下一条指令如果为0则需要跳转到 spurious_interrupt 标号处 执行 */
+ /* 如果 s2的值等于0rt_thread_switch_interrupt_flag等于0 则不需要在中断处理函数中,进行上下文切换,反之则需要 */
+ /* 如果不需要上下文切换, */
+
+ /* 在这里,跳转到 spurious_interrupt的话是不会进行上下文切换的因为此时CPU的sp指针还是from线程的*/
+ beqz s2, spurious_interrupt /* if (s2 == 0) goto spurious_interrupt; else 执行下一条语句*/
+
+ /* 需要上下文切换: 主要目的是将CPU的sp指针赋值为to_thread的sp */
+
+ /* 将 s0 所执向的地址的内容设置为0 也就是,将变量 rt_thread_switch_interrupt_flag 赋值为了 0 */
+ /* s0存放的值是 rt_thread_switch_interrupt_flag 变量的地址*/
+ sw zero, 0(s0) /* *s0 = 0; 也就是 rt_thread_switch_interrupt_flag = 0 */
+ /* 将 mepc 的值,赋值给 a0 寄存器mepc 的值是,跳转到中断函数执行之前的 PC 指针 */
+ /* 这时的mpec其实还是from线程在跳转到中断执行前的一个PC地址 */
+ csrr a0, mepc /* a0 = mepc */
+
+ /* 将 mpec 的值写回到freom thread任务栈中的 epc 中,待后续恢复from线程时使用 */
+ STORE a0, 0 * REGBYTES(sp) /* from_thread->sp->epc = a0 ,中断入口处*/
+
+ /* 将from_thread的sp指针赋值为CPU的sp指针 */
+ la s0, rt_interrupt_from_thread /* s0 = &rt_interrupt_from_thread 注意: rt_interrupt_from_thread = &(from_thread->sp) */
+ LOAD s1, 0(s0) /* s1 = rt_interrupt_from_thread也就是s1 = &(from_thread->sp) */
+ STORE sp, 0(s1) /* from_thread->sp = sp*/
+
+ /* 接下来需要开始恢复CPU的sp为to_thread的sp了 */
+ la s0, rt_interrupt_to_thread /* s0 = &rt_interrupt_to_thread 注意: rt_interrupt_to_thread = &(to_thred->sp)*/
+ LOAD s1, 0(s0) /* s1 = rt_interrupt_to_thread, 也就是s1 = &(to_thred->sp) */
+ LOAD sp, 0(s1) /* sp = (to_thred->sp)*/
+
+ /* 将CPU的 mepc设置为to_thred的mepc待中断退出执行mret指令后将从该地址开始执行 */
+ LOAD a0, 0 * REGBYTES(sp) /* a0 = to_thread的mepc的值*/
+ csrw mepc, a0 /* mepc = a0 */
+
+
+spurious_interrupt:
+ LOAD x1, 1 * REGBYTES(sp)
+
+ /* Remain in M-mode after mret */
+ li t0, 0x00001800
+ csrs mstatus, t0
+ LOAD t0, 2 * REGBYTES(sp)
+ csrs mstatus, t0
+
+ LOAD x4, 4 * REGBYTES(sp)
+ LOAD x5, 5 * REGBYTES(sp)
+ LOAD x6, 6 * REGBYTES(sp)
+ LOAD x7, 7 * REGBYTES(sp)
+ LOAD x8, 8 * REGBYTES(sp)
+ LOAD x9, 9 * REGBYTES(sp)
+ LOAD x10, 10 * REGBYTES(sp)
+ LOAD x11, 11 * REGBYTES(sp)
+ LOAD x12, 12 * REGBYTES(sp)
+ LOAD x13, 13 * REGBYTES(sp)
+ LOAD x14, 14 * REGBYTES(sp)
+ LOAD x15, 15 * REGBYTES(sp)
+ LOAD x16, 16 * REGBYTES(sp)
+ LOAD x17, 17 * REGBYTES(sp)
+ LOAD x18, 18 * REGBYTES(sp)
+ LOAD x19, 19 * REGBYTES(sp)
+ LOAD x20, 20 * REGBYTES(sp)
+ LOAD x21, 21 * REGBYTES(sp)
+ LOAD x22, 22 * REGBYTES(sp)
+ LOAD x23, 23 * REGBYTES(sp)
+ LOAD x24, 24 * REGBYTES(sp)
+ LOAD x25, 25 * REGBYTES(sp)
+ LOAD x26, 26 * REGBYTES(sp)
+ LOAD x27, 27 * REGBYTES(sp)
+ LOAD x28, 28 * REGBYTES(sp)
+ LOAD x29, 29 * REGBYTES(sp)
+ LOAD x30, 30 * REGBYTES(sp)
+ LOAD x31, 31 * REGBYTES(sp)
+
+ addi sp, sp, 32 * REGBYTES
+ mret
+ .size _interrupt_handler, .-_interrupt_handler
+#endif
\ No newline at end of file
--
2.32.0 (Apple Git-132)
From 394259fb2164e513abd4f0d23d88da92c2a2ac9e Mon Sep 17 00:00:00 2001
From: tangzz98 <tangz98@outlook.com>
Date: Fri, 23 Sep 2022 00:12:13 -0400
Subject: [PATCH 2/2] Specify freertos_root in project CMakeLists.txt
---
components/freertos/CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt
index 5cd54494f6..33c901c187 100644
--- a/components/freertos/CMakeLists.txt
+++ b/components/freertos/CMakeLists.txt
@@ -7,7 +7,7 @@ endif()
idf_build_get_property(target IDF_TARGET)
if(CONFIG_IDF_RTOS_RTTHREAD)
- set(freertos_root "../../../FreeRTOS_Wrapper-latest/FreeRTOS")
+ message(${freertos_root})
set(srcs
"${freertos_root}/portable/esp-idf/riscv/port.c")
--
2.32.0 (Apple Git-132)