rtt.patch 22.2 KB
Newer Older
1 2 3 4
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
T
tangzz98 已提交
5 6 7

---
 Kconfig                                       |   4 +
8 9 10 11 12 13 14 15 16 17 18 19
 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(-)
T
tangzz98 已提交
20 21

diff --git a/Kconfig b/Kconfig
22
index c86ebeaaef..56d062b2db 100644
T
tangzz98 已提交
23 24
--- a/Kconfig
+++ b/Kconfig
25
@@ -101,6 +101,10 @@ mainmenu "Espressif IoT Development Framework Configuration"
T
tangzz98 已提交
26 27 28 29 30 31 32 33 34 35
         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
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
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
T
tangzz98 已提交
98
diff --git a/components/esp_system/ld/esp32c3/sections.ld.in b/components/esp_system/ld/esp32c3/sections.ld.in
99
index d6670bf759..1d51ffeea0 100644
T
tangzz98 已提交
100 101
--- a/components/esp_system/ld/esp32c3/sections.ld.in
+++ b/components/esp_system/ld/esp32c3/sections.ld.in
102
@@ -178,6 +178,26 @@ SECTIONS
T
tangzz98 已提交
103 104 105
     _noinit_end = ABSOLUTE(.);
   } > dram0_0_seg
 
106
+  .stack :
T
tangzz98 已提交
107 108
+  {
+      . = ALIGN(8);
109
+      __STACKSIZE__ = 40960; 
T
tangzz98 已提交
110 111 112 113 114 115 116
+      __stack_start__ = .;
+      *(.stack*)
+      . += __STACKSIZE__;
+      __stack_cpu0 = .;
+      __stack_end__ = .;
+  } > dram0_0_seg
+
117
+  .heap :
T
tangzz98 已提交
118 119
+  {
+      . = ALIGN(8);
120
+      __HEAPSIZE__ = 40960; 
T
tangzz98 已提交
121
+      __heap_start__ = .;
122
+      . += __HEAPSIZE__;
T
tangzz98 已提交
123 124
+      __heap_end__ = .;
+  } > dram0_0_seg
125
+
T
tangzz98 已提交
126 127 128
   /* Shared RAM */
   .dram0.bss (NOLOAD) :
   {
129 130 131
@@ -218,6 +238,17 @@ SECTIONS
     *(.fini)
     *(.gnu.version)
T
tangzz98 已提交
132
 
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
+    /* 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
T
tangzz98 已提交
169
+
170 171 172 173 174
 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);
T
tangzz98 已提交
175 176
 }
 
177 178 179 180
+#endif
+
 
 void esp_execute_shared_stack_function(SemaphoreHandle_t lock, void *stack, size_t stack_size, shared_stack_function function)
T
tangzz98 已提交
181
 {
182 183 184 185 186 187 188 189
+#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);
T
tangzz98 已提交
190
+#else
191 192 193 194 195 196 197 198 199 200
+    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"
T
tangzz98 已提交
201
 #endif
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
+
+#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;
 }
+
T
tangzz98 已提交
239
+#endif
240 241 242 243 244 245 246 247 248 249 250 251
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();
T
tangzz98 已提交
252
 }
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
+#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()
T
tangzz98 已提交
341
 
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
 # 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
T
tangzz98 已提交
369
diff --git a/components/riscv/vectors.S b/components/riscv/vectors.S
370
index 9b868280db..23236f3d8d 100644
T
tangzz98 已提交
371 372
--- a/components/riscv/vectors.S
+++ b/components/riscv/vectors.S
373
@@ -10,6 +10,9 @@
T
tangzz98 已提交
374 375 376 377 378 379 380
 #include "soc/soc_caps.h"
 #include "sdkconfig.h"
 
+#define STORE                   sw
+#define LOAD                    lw
+#define REGBYTES                4
 
381 382 383 384 385 386
     .equ SAVE_REGS, 32
     .equ CONTEXT_SIZE, (SAVE_REGS * 4)
@@ -210,6 +213,8 @@ _return_from_exception:
      */
     .global _interrupt_handler
     .type _interrupt_handler, @function
T
tangzz98 已提交
387 388 389
+#ifndef CONFIG_IDF_RTOS_RTTHREAD
+
 _interrupt_handler:
390 391 392 393 394 395
     /* 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
T
tangzz98 已提交
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501
+#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的值等于0,rt_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 */
502
+
T
tangzz98 已提交
503 504 505 506 507 508 509 510 511 512 513 514 515 516
+    /* 将 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*/
517
+
T
tangzz98 已提交
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569
+    /* 接下来,需要开始恢复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
570
\ No newline at end of file
T
tangzz98 已提交
571 572 573 574
-- 
2.32.0 (Apple Git-132)


575
From 394259fb2164e513abd4f0d23d88da92c2a2ac9e Mon Sep 17 00:00:00 2001
T
tangzz98 已提交
576
From: tangzz98 <tangz98@outlook.com>
577 578
Date: Fri, 23 Sep 2022 00:12:13 -0400
Subject: [PATCH 2/2] Specify freertos_root in project CMakeLists.txt
T
tangzz98 已提交
579 580

---
581 582
 components/freertos/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
T
tangzz98 已提交
583 584

diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt
585
index 5cd54494f6..33c901c187 100644
T
tangzz98 已提交
586 587
--- a/components/freertos/CMakeLists.txt
+++ b/components/freertos/CMakeLists.txt
588
@@ -7,7 +7,7 @@ endif()
T
tangzz98 已提交
589 590
 idf_build_get_property(target IDF_TARGET)
 
591 592 593
 if(CONFIG_IDF_RTOS_RTTHREAD)
-    set(freertos_root "../../../FreeRTOS_Wrapper-latest/FreeRTOS")
+    message(${freertos_root})
T
tangzz98 已提交
594
     set(srcs
595
         "${freertos_root}/portable/esp-idf/riscv/port.c")
T
tangzz98 已提交
596 597 598 599
 
-- 
2.32.0 (Apple Git-132)