rtt.patch 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. From 92402217b821c8da7e2a188352f095caaf0818d1 Mon Sep 17 00:00:00 2001
  2. From: tangzz98 <tangz98@outlook.com>
  3. Date: Tue, 13 Sep 2022 18:05:44 -0400
  4. Subject: [PATCH 1/2] Add config for RT-Thread
  5. ---
  6. Kconfig | 4 +
  7. components/driver/deprecated/i2s_legacy.c | 4 +
  8. components/driver/uart.c | 4 +
  9. components/esp_system/crosscore_int.c | 5 +-
  10. .../esp_system/ld/esp32c3/sections.ld.in | 37 ++++
  11. .../port/arch/riscv/expression_with_stack.c | 8 +
  12. components/esp_system/startup.c | 9 +
  13. components/esp_system/task_wdt.c | 4 +
  14. components/esp_timer/src/esp_timer.c | 2 +
  15. components/freertos/CMakeLists.txt | 50 ++++-
  16. .../freertos_tasks_c_additions.h | 6 +-
  17. components/riscv/vectors.S | 179 ++++++++++++++++++
  18. 12 files changed, 309 insertions(+), 3 deletions(-)
  19. diff --git a/Kconfig b/Kconfig
  20. index c86ebeaaef..56d062b2db 100644
  21. --- a/Kconfig
  22. +++ b/Kconfig
  23. @@ -101,6 +101,10 @@ mainmenu "Espressif IoT Development Framework Configuration"
  24. bool
  25. default "y" if IDF_TARGET="linux"
  26. + config IDF_RTOS_RTTHREAD
  27. + bool "RT-THREAD SELECT"
  28. + default "n"
  29. +
  30. config IDF_FIRMWARE_CHIP_ID
  31. hex
  32. default 0x0000 if IDF_TARGET_ESP32
  33. diff --git a/components/driver/deprecated/i2s_legacy.c b/components/driver/deprecated/i2s_legacy.c
  34. index 2e36ab2608..92edf9d2bb 100644
  35. --- a/components/driver/deprecated/i2s_legacy.c
  36. +++ b/components/driver/deprecated/i2s_legacy.c
  37. @@ -1600,7 +1600,11 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config,
  38. i2s_obj->i2s_queue = xQueueCreate(queue_size, sizeof(i2s_event_t));
  39. ESP_GOTO_ON_FALSE(i2s_obj->i2s_queue, ESP_ERR_NO_MEM, err, TAG, "I2S queue create failed");
  40. *((QueueHandle_t *) i2s_queue) = i2s_obj->i2s_queue;
  41. +#if !defined CONFIG_IDF_RTOS_RTTHREAD
  42. ESP_LOGD(TAG, "queue free spaces: %d", uxQueueSpacesAvailable(i2s_obj->i2s_queue));
  43. +#else
  44. + ESP_LOGD(TAG, "queue free spaces: %lu", uxQueueSpacesAvailable(i2s_obj->i2s_queue));
  45. +#endif
  46. } else {
  47. i2s_obj->i2s_queue = NULL;
  48. }
  49. diff --git a/components/driver/uart.c b/components/driver/uart.c
  50. index b68b2900e1..63c9841380 100644
  51. --- a/components/driver/uart.c
  52. +++ b/components/driver/uart.c
  53. @@ -1603,7 +1603,11 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
  54. uart_pattern_queue_reset(uart_num, UART_PATTERN_DET_QLEN_DEFAULT);
  55. if (uart_queue) {
  56. *uart_queue = p_uart_obj[uart_num]->event_queue;
  57. +#if !defined CONFIG_IDF_RTOS_RTTHREAD
  58. ESP_LOGI(UART_TAG, "queue free spaces: %d", uxQueueSpacesAvailable(p_uart_obj[uart_num]->event_queue));
  59. +#else
  60. + ESP_LOGI(UART_TAG, "queue free spaces: %lu", uxQueueSpacesAvailable(p_uart_obj[uart_num]->event_queue));
  61. +#endif
  62. }
  63. } else {
  64. ESP_LOGE(UART_TAG, "UART driver already installed");
  65. diff --git a/components/esp_system/crosscore_int.c b/components/esp_system/crosscore_int.c
  66. index 4aae2a2540..8a9079de64 100644
  67. --- a/components/esp_system/crosscore_int.c
  68. +++ b/components/esp_system/crosscore_int.c
  69. @@ -95,13 +95,14 @@ static void IRAM_ATTR esp_crosscore_isr(void *arg) {
  70. if (my_reason_val & REASON_PRINT_BACKTRACE) {
  71. esp_backtrace_print(100);
  72. }
  73. -
  74. +#ifdef CONFIG_ESP_TASK_WDT
  75. if (my_reason_val & REASON_TWDT_ABORT) {
  76. extern void task_wdt_timeout_abort_xtensa(bool);
  77. /* Called from a crosscore interrupt, thus, we are not the core that received
  78. * the TWDT interrupt, call the function with `false` as a parameter. */
  79. task_wdt_timeout_abort_xtensa(false);
  80. }
  81. +#endif
  82. #endif // CONFIG_IDF_TARGET_ARCH_XTENSA
  83. }
  84. @@ -171,7 +172,9 @@ void IRAM_ATTR esp_crosscore_int_send_print_backtrace(int core_id)
  85. esp_crosscore_int_send(core_id, REASON_PRINT_BACKTRACE);
  86. }
  87. +#ifdef CONFIG_ESP_TASK_WDT
  88. void IRAM_ATTR esp_crosscore_int_send_twdt_abort(int core_id) {
  89. esp_crosscore_int_send(core_id, REASON_TWDT_ABORT);
  90. }
  91. #endif
  92. +#endif
  93. diff --git a/components/esp_system/ld/esp32c3/sections.ld.in b/components/esp_system/ld/esp32c3/sections.ld.in
  94. index d6670bf759..1d51ffeea0 100644
  95. --- a/components/esp_system/ld/esp32c3/sections.ld.in
  96. +++ b/components/esp_system/ld/esp32c3/sections.ld.in
  97. @@ -178,6 +178,26 @@ SECTIONS
  98. _noinit_end = ABSOLUTE(.);
  99. } > dram0_0_seg
  100. + .stack :
  101. + {
  102. + . = ALIGN(8);
  103. + __STACKSIZE__ = 40960;
  104. + __stack_start__ = .;
  105. + *(.stack*)
  106. + . += __STACKSIZE__;
  107. + __stack_cpu0 = .;
  108. + __stack_end__ = .;
  109. + } > dram0_0_seg
  110. + PROVIDE( __rt_rvstack = __stack_end__);
  111. +
  112. + .heap :
  113. + {
  114. + . = ALIGN(8);
  115. + __HEAPSIZE__ = 40960;
  116. + __heap_start__ = .;
  117. + . += __HEAPSIZE__;
  118. + __heap_end__ = .;
  119. + } > dram0_0_seg
  120. +
  121. /* Shared RAM */
  122. .dram0.bss (NOLOAD) :
  123. {
  124. @@ -218,6 +238,17 @@ SECTIONS
  125. *(.fini)
  126. *(.gnu.version)
  127. + /* section information for finsh shell */
  128. + . = ALIGN(8);
  129. + __fsymtab_start = .;
  130. + KEEP(*(FSymTab))
  131. + __fsymtab_end = .;
  132. + . = ALIGN(8);
  133. + __vsymtab_start = .;
  134. + KEEP(*(VSymTab))
  135. + __vsymtab_end = .;
  136. + . = ALIGN(8);
  137. +
  138. /** CPU will try to prefetch up to 16 bytes of
  139. * of instructions. This means that any configuration (e.g. MMU, PMS) must allow
  140. * safe access to up to 16 bytes after the last real instruction, add
  141. @@ -318,6 +349,12 @@ SECTIONS
  142. _esp_system_init_fn_array_start = ABSOLUTE(.);
  143. KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
  144. _esp_system_init_fn_array_end = ABSOLUTE(.);
  145. + /* section information for initial. */
  146. + . = ALIGN(4);
  147. + __rt_init_start = .;
  148. + KEEP(*(SORT(.rti_fn*)))
  149. + __rt_init_end = .;
  150. + . = ALIGN(4);
  151. _rodata_end = ABSOLUTE(.);
  152. /* Literals are also RO data. */
  153. _lit4_start = ABSOLUTE(.);
  154. diff --git a/components/esp_system/port/arch/riscv/expression_with_stack.c b/components/esp_system/port/arch/riscv/expression_with_stack.c
  155. index 07d22bf3aa..5eac5a88f8 100644
  156. --- a/components/esp_system/port/arch/riscv/expression_with_stack.c
  157. +++ b/components/esp_system/port/arch/riscv/expression_with_stack.c
  158. @@ -18,6 +18,8 @@
  159. #include "freertos/FreeRTOS.h"
  160. #include "freertos/portmacro.h"
  161. +#if !defined CONFIG_IDF_RTOS_RTTHREAD
  162. +
  163. static portMUX_TYPE shared_stack_spinlock = portMUX_INITIALIZER_UNLOCKED;
  164. static void *current_task_stack = NULL;
  165. @@ -46,9 +48,12 @@ static StackType_t *esp_switch_stack_setup(StackType_t *stack, size_t stack_size
  166. return ((StackType_t *)adjusted_top_of_stack);
  167. }
  168. +#endif
  169. +
  170. void esp_execute_shared_stack_function(SemaphoreHandle_t lock, void *stack, size_t stack_size, shared_stack_function function)
  171. {
  172. +#if !defined CONFIG_IDF_RTOS_RTTHREAD
  173. assert(lock);
  174. assert(stack);
  175. assert(stack_size > 0 && stack_size >= CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE);
  176. @@ -70,4 +75,7 @@ void esp_execute_shared_stack_function(SemaphoreHandle_t lock, void *stack, size
  177. portEXIT_CRITICAL(&shared_stack_spinlock);
  178. xSemaphoreGive(lock);
  179. +#else
  180. + function();
  181. +#endif
  182. }
  183. diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c
  184. index 0feda4e9f5..b1752d91a0 100644
  185. --- a/components/esp_system/startup.c
  186. +++ b/components/esp_system/startup.c
  187. @@ -72,6 +72,10 @@
  188. #include "esp_psram.h"
  189. #include "esp_private/esp_psram_extram.h"
  190. #endif
  191. +
  192. +#if CONFIG_IDF_RTOS_RTTHREAD
  193. +#include "rtthread.h"
  194. +#endif
  195. /***********************************************/
  196. #include "esp_private/startup_internal.h"
  197. @@ -266,6 +270,11 @@ static void do_core_init(void)
  198. app CPU, and when that is not up yet, the memory will be inaccessible and heap_caps_init may
  199. fail initializing it properly. */
  200. heap_caps_init();
  201. +#if CONFIG_IDF_RTOS_RTTHREAD && defined RT_USING_HEAP
  202. + extern int __heap_start__;
  203. + extern int __heap_end__;
  204. + rt_system_heap_init((void *)&__heap_start__, (void *)&__heap_end__);
  205. +#endif
  206. // When apptrace module is enabled, there will be SEGGER_SYSVIEW calls in the newlib init.
  207. // SEGGER_SYSVIEW relies on apptrace module
  208. diff --git a/components/esp_system/task_wdt.c b/components/esp_system/task_wdt.c
  209. index 58d1247bf0..60330edf8a 100644
  210. --- a/components/esp_system/task_wdt.c
  211. +++ b/components/esp_system/task_wdt.c
  212. @@ -29,6 +29,8 @@
  213. #include "esp_private/eh_frame_parser.h"
  214. #endif // CONFIG_ESP_SYSTEM_USE_EH_FRAME
  215. +#if CONFIG_ESP_TASK_WDT
  216. +
  217. #if CONFIG_IDF_TARGET_ARCH_RISCV && !CONFIG_ESP_SYSTEM_USE_EH_FRAME
  218. /* Function used to print all the registers pointed by the given frame .*/
  219. extern void panic_print_registers(const void *frame, int core);
  220. @@ -784,3 +786,5 @@ esp_err_t esp_task_wdt_status(TaskHandle_t task_handle)
  221. return ret;
  222. }
  223. +
  224. +#endif
  225. diff --git a/components/esp_timer/src/esp_timer.c b/components/esp_timer/src/esp_timer.c
  226. index 3ca19f642f..78779a08b3 100644
  227. --- a/components/esp_timer/src/esp_timer.c
  228. +++ b/components/esp_timer/src/esp_timer.c
  229. @@ -460,10 +460,12 @@ out:
  230. return ESP_ERR_NO_MEM;
  231. }
  232. +#if !defined CONFIG_IDF_RTOS_RTTHREAD
  233. ESP_SYSTEM_INIT_FN(esp_timer_startup_init, BIT(0), 100)
  234. {
  235. return esp_timer_init();
  236. }
  237. +#endif
  238. esp_err_t esp_timer_deinit(void)
  239. {
  240. diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt
  241. index 78a8e4ae4e..5cd54494f6 100644
  242. --- a/components/freertos/CMakeLists.txt
  243. +++ b/components/freertos/CMakeLists.txt
  244. @@ -6,7 +6,36 @@ endif()
  245. idf_build_get_property(target IDF_TARGET)
  246. -if(CONFIG_FREERTOS_SMP)
  247. +if(CONFIG_IDF_RTOS_RTTHREAD)
  248. + set(freertos_root "../../../FreeRTOS_Wrapper-latest/FreeRTOS")
  249. + set(srcs
  250. + "${freertos_root}/portable/esp-idf/riscv/port.c")
  251. +
  252. + set(include_dirs
  253. + "${freertos_root}/include"
  254. + esp_additions/include
  255. + esp_additions/include/freertos
  256. + "${freertos_root}/portable/esp-idf/riscv/include")
  257. +
  258. + set(private_include_dirs
  259. + "${freertos_root}/portable/esp-idf/riscv/include/freertos")
  260. +
  261. + list(APPEND srcs
  262. + "${freertos_root}/portable/esp-idf/port_common.c"
  263. + "${freertos_root}/portable/esp-idf/port_rt.c"
  264. + "${freertos_root}/event_groups.c"
  265. + "${freertos_root}/queue.c"
  266. + "${freertos_root}/tasks.c"
  267. + "${freertos_root}/timers.c"
  268. + "${freertos_root}/list.c"
  269. + "FreeRTOS-openocd.c"
  270. + "esp_additions/freertos_v8_compat.c")
  271. +
  272. + list(APPEND private_include_dirs
  273. + "${freertos_root}/include/freertos"
  274. + "esp_additions/private_include")
  275. +
  276. +elseif(CONFIG_FREERTOS_SMP)
  277. set(ldfragments linker_smp.lf)
  278. if(CONFIG_IDF_TARGET_ARCH_XTENSA)
  279. set(srcs
  280. @@ -133,11 +162,19 @@ else()
  281. endif()
  282. endif()
  283. +if(CONFIG_IDF_RTOS_RTTHREAD)
  284. +idf_component_register(SRCS "${srcs}"
  285. + INCLUDE_DIRS ${include_dirs}
  286. + PRIV_INCLUDE_DIRS ${private_include_dirs}
  287. + PRIV_REQUIRES soc esp_pm)
  288. +else()
  289. idf_component_register(SRCS "${srcs}"
  290. INCLUDE_DIRS ${include_dirs}
  291. PRIV_INCLUDE_DIRS ${private_include_dirs}
  292. LDFRAGMENTS "${ldfragments}"
  293. + REQUIRES main
  294. PRIV_REQUIRES soc esp_pm)
  295. +endif()
  296. idf_component_get_property(COMPONENT_DIR freertos COMPONENT_DIR)
  297. @@ -153,6 +190,16 @@ if(CONFIG_FREERTOS_DEBUG_OCDAWARE)
  298. idf_build_set_property(COMPILE_OPTIONS "-DconfigENABLE_FREERTOS_DEBUG_OCDAWARE=1" APPEND)
  299. endif()
  300. +if(CONFIG_IDF_RTOS_RTTHREAD)
  301. +set_source_files_properties(
  302. + tasks.c
  303. + event_groups.c
  304. + timers.c
  305. + queue.c
  306. + PROPERTIES COMPILE_DEFINITIONS
  307. + _ESP_FREERTOS_INTERNAL
  308. + )
  309. +else()
  310. set_source_files_properties(
  311. tasks.c
  312. event_groups.c
  313. @@ -162,6 +209,7 @@ set_source_files_properties(
  314. PROPERTIES COMPILE_DEFINITIONS
  315. _ESP_FREERTOS_INTERNAL
  316. )
  317. +endif()
  318. # The freertos component provides the `start_app` and `start_app_other_cores`
  319. # if it is included in the build. It then calls `app_main`
  320. 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
  321. index f5ecdbb5a9..96fc4f73ce 100644
  322. --- a/components/freertos/esp_additions/private_include/freertos_tasks_c_additions.h
  323. +++ b/components/freertos/esp_additions/private_include/freertos_tasks_c_additions.h
  324. @@ -34,8 +34,9 @@
  325. struct _reent *__getreent(void)
  326. {
  327. // No lock needed because if this changes, we won't be running anymore.
  328. - TCB_t *pxCurTask = xTaskGetCurrentTaskHandle();
  329. struct _reent *ret;
  330. +#if !defined CONFIG_IDF_RTOS_RTTHREAD
  331. + TCB_t *pxCurTask = xTaskGetCurrentTaskHandle();
  332. if (pxCurTask == NULL) {
  333. // No task running. Return global struct.
  334. ret = _GLOBAL_REENT;
  335. @@ -43,6 +44,9 @@ struct _reent *__getreent(void)
  336. // We have a task; return its reentrant struct.
  337. ret = &pxCurTask->xNewLib_reent;
  338. }
  339. +#else
  340. + ret = _GLOBAL_REENT;
  341. +#endif
  342. return ret;
  343. }
  344. #endif // configUSE_NEWLIB_REENTRANT == 1
  345. diff --git a/components/riscv/vectors.S b/components/riscv/vectors.S
  346. index 9b868280db..23236f3d8d 100644
  347. --- a/components/riscv/vectors.S
  348. +++ b/components/riscv/vectors.S
  349. @@ -10,6 +10,9 @@
  350. #include "soc/soc_caps.h"
  351. #include "sdkconfig.h"
  352. +#define STORE sw
  353. +#define LOAD lw
  354. +#define REGBYTES 4
  355. .equ SAVE_REGS, 32
  356. .equ CONTEXT_SIZE, (SAVE_REGS * 4)
  357. @@ -210,6 +213,8 @@ _return_from_exception:
  358. */
  359. .global _interrupt_handler
  360. .type _interrupt_handler, @function
  361. +#ifndef CONFIG_IDF_RTOS_RTTHREAD
  362. +
  363. _interrupt_handler:
  364. /* Start by saving the general purpose registers and the PC value before
  365. * the interrupt happened. */
  366. @@ -308,3 +313,177 @@ _interrupt_handler:
  367. /* exit, this will also re-enable the interrupts */
  368. mret
  369. .size _interrupt_handler, .-_interrupt_handler
  370. +#else
  371. +_interrupt_handler:
  372. + /* 此时CPU的sp = from_thread->sp */
  373. + /* 注意: 在这里,并没有将mepc的值赋值为from_thread栈中的epc,但后面会赋值 */
  374. + addi sp, sp, -32 * REGBYTES /* sp = sp - 32 * 4 栈指针向下偏移32个寄存器长度,用来将CPU的寄存器保存到from_thread的栈中*/
  375. + STORE x1, 1 * REGBYTES(sp) /* 将CPU的x1寄存器,即ra寄存器,保存到from_thread->栈中 */
  376. +
  377. + li t0, 0x80 /* t0 = 0x80 */
  378. + STORE t0, 2 * REGBYTES(sp) /* mstatus = t0, 即关闭全局中断 */
  379. +
  380. + /* 将 CPU 的其他寄存器的值,保存到from_thread的任务栈中 */
  381. + STORE x4, 4 * REGBYTES(sp)
  382. + STORE x5, 5 * REGBYTES(sp)
  383. + STORE x6, 6 * REGBYTES(sp)
  384. + STORE x7, 7 * REGBYTES(sp)
  385. + STORE x8, 8 * REGBYTES(sp)
  386. + STORE x9, 9 * REGBYTES(sp)
  387. + STORE x10, 10 * REGBYTES(sp)
  388. + STORE x11, 11 * REGBYTES(sp)
  389. + STORE x12, 12 * REGBYTES(sp)
  390. + STORE x13, 13 * REGBYTES(sp)
  391. + STORE x14, 14 * REGBYTES(sp)
  392. + STORE x15, 15 * REGBYTES(sp)
  393. + STORE x16, 16 * REGBYTES(sp)
  394. + STORE x17, 17 * REGBYTES(sp)
  395. + STORE x18, 18 * REGBYTES(sp)
  396. + STORE x19, 19 * REGBYTES(sp)
  397. + STORE x20, 20 * REGBYTES(sp)
  398. + STORE x21, 21 * REGBYTES(sp)
  399. + STORE x22, 22 * REGBYTES(sp)
  400. + STORE x23, 23 * REGBYTES(sp)
  401. + STORE x24, 24 * REGBYTES(sp)
  402. + STORE x25, 25 * REGBYTES(sp)
  403. + STORE x26, 26 * REGBYTES(sp)
  404. + STORE x27, 27 * REGBYTES(sp)
  405. + STORE x28, 28 * REGBYTES(sp)
  406. + STORE x29, 29 * REGBYTES(sp)
  407. + STORE x30, 30 * REGBYTES(sp)
  408. + STORE x31, 31 * REGBYTES(sp)
  409. +
  410. + /* 备份 CPU 的 sp (这时,CPU的sp其实就是from thread的sp指针) 寄存器的值到 s0 寄存器中,下面会使用s0,恢复 CPU 的寄存器 */
  411. + move s0, sp /* s0 = sp */
  412. +
  413. + /* 在中断函数中,中断函数中调用的C函数,需要使用 sp, 这里,在中断函数中,使用的 sp 为,系统的栈资源 */
  414. + /* switch to interrupt stack */
  415. + la sp, __stack_end__ /* sp = _sp */
  416. +
  417. + /* interrupt handle */
  418. + /* 注意: 在调用C函数之前,比如sp的值为0x30001000, 在执行完C函数后,sp的值还是会变成 0x30001000 */
  419. + call rt_interrupt_enter /* 执行所有的中断函数前,调用该函数 */
  420. +
  421. + csrr s1, mcause
  422. + csrr s2, mstatus
  423. +
  424. + /* Save the interrupt threshold level */
  425. + la t0, INTERRUPT_CORE0_CPU_INT_THRESH_REG
  426. + lw s3, 0(t0)
  427. +
  428. + li t2, 0x7fffffff
  429. + and t1, s1, t2 /* t1 = mcause & mask */
  430. + slli t1, t1, 2 /* t1 = mcause * 4 */
  431. + la t2, INTC_INT_PRIO_REG(0)
  432. + add t1, t2, t1 /* t1 = INTC_INT_PRIO_REG + 4 * mcause */
  433. + lw t2, 0(t1) /* t2 = INTC_INT_PRIO_REG[mcause] */
  434. + addi t2, t2, 1 /* t2 = t2 +1 */
  435. + sw t2, 0(t0) /* INTERRUPT_CORE0_CPU_INT_THRESH_REG = t2 */
  436. + fence
  437. +
  438. + li t0, 0x8
  439. + csrrs t0, mstatus, t0
  440. +
  441. + /* call the C dispatcher */
  442. + mv a0, sp /* argument 1, stack pointer */
  443. + mv a1, s1 /* argument 2, interrupt number (mcause) */
  444. + /* mask off the interrupt flag of mcause */
  445. + li t0, 0x7fffffff
  446. + and a1, a1, t0
  447. + jal _global_interrupt_handler
  448. +
  449. + li t0, 0x8
  450. + csrrc t0, mstatus, t0
  451. +
  452. + /* restore the interrupt threshold level */
  453. + la t0, INTERRUPT_CORE0_CPU_INT_THRESH_REG
  454. + sw s3, 0(t0)
  455. + fence
  456. +
  457. + call rt_interrupt_leave /* 执行所有的中断函数后,调用该函数 */
  458. +
  459. + /* 上面,将保存执行中断服务函数之前的CPU的sp寄存器到了s0所指向的位置处,当执行完中断服务函数,需要将之前的CPU寄存器,恢复一下,此时sp又变成了from thread的sp了 */
  460. + move sp, s0 /* sp = s0 */
  461. +
  462. + /* 下面两句话,相当于将 rt_thread_switch_interrupt_flag 值,赋值给了s2 */
  463. + /* 将 rt_thread_switch_interrupt_flag 的地址值,赋值给 s0 寄存器*/
  464. + la s0, rt_thread_switch_interrupt_flag /* s0 = &rt_thread_switch_interrupt_flag */
  465. + /* 将 s0 所指向的地址处的内容,取出来,赋值给 s2 寄存器,其实就是将 rt_thread_switch_interrupt_flag 的值,赋值给了 s2 寄存器*/
  466. + lw s2, 0(s0) /* s2 = *s0 = rt_thread_switch_interrupt_flag */
  467. +
  468. + /* 如果 s2的值,即 rt_thread_switch_interrupt_flag 值,如果不为0,则需要继续执行下一条指令,如果为0,则需要跳转到 spurious_interrupt 标号处 执行 */
  469. + /* 如果 s2的值等于0,rt_thread_switch_interrupt_flag等于0, 则不需要在中断处理函数中,进行上下文切换,反之则需要 */
  470. + /* 如果不需要上下文切换, */
  471. +
  472. + /* 在这里,跳转到 spurious_interrupt的话,是不会进行上下文切换的,因为,此时CPU的sp指针还是from线程的*/
  473. + beqz s2, spurious_interrupt /* if (s2 == 0) goto spurious_interrupt; else 执行下一条语句*/
  474. +
  475. + /* 需要上下文切换: 主要目的是将CPU的sp指针,赋值为to_thread的sp */
  476. +
  477. + /* 将 s0 所执向的地址的内容设置为0, 也就是,将变量 rt_thread_switch_interrupt_flag 赋值为了 0 */
  478. + /* s0存放的值是 rt_thread_switch_interrupt_flag 变量的地址*/
  479. + sw zero, 0(s0) /* *s0 = 0; 也就是 rt_thread_switch_interrupt_flag = 0 */
  480. + /* 将 mepc 的值,赋值给 a0 寄存器,mepc 的值是,跳转到中断函数执行之前的 PC 指针 */
  481. + /* 这时的mpec其实,还是from线程,在跳转到中断执行前的一个PC地址 */
  482. + csrr a0, mepc /* a0 = mepc */
  483. +
  484. + /* 将 mpec 的值写回到freom thread任务栈中的 epc 中,待后续,恢复from线程时,使用 */
  485. + STORE a0, 0 * REGBYTES(sp) /* from_thread->sp->epc = a0 ,中断入口处*/
  486. +
  487. + /* 将from_thread的sp指针,赋值为CPU的sp指针 */
  488. + la s0, rt_interrupt_from_thread /* s0 = &rt_interrupt_from_thread 注意: rt_interrupt_from_thread = &(from_thread->sp) */
  489. + LOAD s1, 0(s0) /* s1 = rt_interrupt_from_thread,也就是s1 = &(from_thread->sp) */
  490. + STORE sp, 0(s1) /* from_thread->sp = sp*/
  491. +
  492. + /* 接下来,需要开始恢复CPU的sp为to_thread的sp了 */
  493. + la s0, rt_interrupt_to_thread /* s0 = &rt_interrupt_to_thread 注意: rt_interrupt_to_thread = &(to_thred->sp)*/
  494. + LOAD s1, 0(s0) /* s1 = rt_interrupt_to_thread, 也就是s1 = &(to_thred->sp) */
  495. + LOAD sp, 0(s1) /* sp = (to_thred->sp)*/
  496. +
  497. + /* 将CPU的 mepc设置为to_thred的mepc,待中断退出,执行mret指令后,将从该地址开始执行 */
  498. + LOAD a0, 0 * REGBYTES(sp) /* a0 = to_thread的mepc的值*/
  499. + csrw mepc, a0 /* mepc = a0 */
  500. +
  501. +
  502. +spurious_interrupt:
  503. + LOAD x1, 1 * REGBYTES(sp)
  504. +
  505. + /* Remain in M-mode after mret */
  506. + li t0, 0x00001800
  507. + csrs mstatus, t0
  508. + LOAD t0, 2 * REGBYTES(sp)
  509. + csrs mstatus, t0
  510. +
  511. + LOAD x4, 4 * REGBYTES(sp)
  512. + LOAD x5, 5 * REGBYTES(sp)
  513. + LOAD x6, 6 * REGBYTES(sp)
  514. + LOAD x7, 7 * REGBYTES(sp)
  515. + LOAD x8, 8 * REGBYTES(sp)
  516. + LOAD x9, 9 * REGBYTES(sp)
  517. + LOAD x10, 10 * REGBYTES(sp)
  518. + LOAD x11, 11 * REGBYTES(sp)
  519. + LOAD x12, 12 * REGBYTES(sp)
  520. + LOAD x13, 13 * REGBYTES(sp)
  521. + LOAD x14, 14 * REGBYTES(sp)
  522. + LOAD x15, 15 * REGBYTES(sp)
  523. + LOAD x16, 16 * REGBYTES(sp)
  524. + LOAD x17, 17 * REGBYTES(sp)
  525. + LOAD x18, 18 * REGBYTES(sp)
  526. + LOAD x19, 19 * REGBYTES(sp)
  527. + LOAD x20, 20 * REGBYTES(sp)
  528. + LOAD x21, 21 * REGBYTES(sp)
  529. + LOAD x22, 22 * REGBYTES(sp)
  530. + LOAD x23, 23 * REGBYTES(sp)
  531. + LOAD x24, 24 * REGBYTES(sp)
  532. + LOAD x25, 25 * REGBYTES(sp)
  533. + LOAD x26, 26 * REGBYTES(sp)
  534. + LOAD x27, 27 * REGBYTES(sp)
  535. + LOAD x28, 28 * REGBYTES(sp)
  536. + LOAD x29, 29 * REGBYTES(sp)
  537. + LOAD x30, 30 * REGBYTES(sp)
  538. + LOAD x31, 31 * REGBYTES(sp)
  539. +
  540. + addi sp, sp, 32 * REGBYTES
  541. + mret
  542. + .size _interrupt_handler, .-_interrupt_handler
  543. +#endif
  544. \ No newline at end of file
  545. --
  546. 2.32.0 (Apple Git-132)
  547. From 394259fb2164e513abd4f0d23d88da92c2a2ac9e Mon Sep 17 00:00:00 2001
  548. From: tangzz98 <tangz98@outlook.com>
  549. Date: Fri, 23 Sep 2022 00:12:13 -0400
  550. Subject: [PATCH 2/2] Specify freertos_root in project CMakeLists.txt
  551. ---
  552. components/freertos/CMakeLists.txt | 2 +-
  553. 1 file changed, 1 insertion(+), 1 deletion(-)
  554. diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt
  555. index 5cd54494f6..33c901c187 100644
  556. --- a/components/freertos/CMakeLists.txt
  557. +++ b/components/freertos/CMakeLists.txt
  558. @@ -7,7 +7,7 @@ endif()
  559. idf_build_get_property(target IDF_TARGET)
  560. if(CONFIG_IDF_RTOS_RTTHREAD)
  561. - set(freertos_root "../../../FreeRTOS_Wrapper-latest/FreeRTOS")
  562. + message(${freertos_root})
  563. set(srcs
  564. "${freertos_root}/portable/esp-idf/riscv/port.c")
  565. --
  566. 2.32.0 (Apple Git-132)