未验证 提交 ee1e0a0d 编写于 作者: Thomas_Fly's avatar Thomas_Fly 提交者: GitHub

[bsp][esp][esp32c3] add the bsp of esp32c3 (#5869)

* add the ESP32_C3 first version

* add the blinky ok version

* fix the code

* format file

* add the readme

* fix the formate

* Update README.md

* Update main.c

* fix the readme

* fix rtconfig.h

* remove cpp config
上级 62d2403e
{
"version": "0.2.0",
"configurations": [
{
"type": "espidf",
"name": "Launch",
"request": "launch"
}
]
}
\ No newline at end of file
{
"C_Cpp.intelliSenseEngine": "Tag Parser",
"idf.adapterTargetName": "esp32c3",
"idf.openOcdConfigs": [
"board/esp32c3-builtin.cfg"
],
"idf.portWin": "COM7",
"idf.flashType": "UART",
"files.associations": {
"panic_internal.h": "c",
"rtthread.h": "c",
"bitset": "c",
"chrono": "c",
"algorithm": "c",
"rtdebug.h": "c",
"rtservice.h": "c",
"rtdef.h": "c",
"rtconfig.h": "c",
"thread": "c",
"rthw.h": "c",
"typeinfo": "c",
"serial.h": "c",
"timer.h": "c"
},
"RTT_Studio.Build.Parallel_Jobs": "4"
}
{
"version": "2.0.0",
"tasks": [
{
"label": "Build - Build project",
"type": "shell",
"command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py build",
"windows": {
"command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py build",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^\\.\\.(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
{
"owner": "cpp",
"fileLocation": "absolute",
"pattern": {
"regexp": "^[^\\.](.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Set ESP-IDF Target",
"type": "shell",
"command": "${command:espIdf.setTarget}",
"problemMatcher": {
"owner": "cpp",
"fileLocation": "absolute",
"pattern": {
"regexp": "^(.*):(//d+):(//d+)://s+(warning|error)://s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"label": "Clean - Clean the project",
"type": "shell",
"command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py fullclean",
"windows": {
"command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py fullclean",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^\\.\\.(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
{
"owner": "cpp",
"fileLocation": "absolute",
"pattern": {
"regexp": "^[^\\.](.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
]
},
{
"label": "Flash - Flash the device",
"type": "shell",
"command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py -p ${config:idf.port} -b ${config:idf.flashBaudRate} flash",
"windows": {
"command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py flash -p ${config:idf.portWin} -b ${config:idf.flashBaudRate}",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^\\.\\.(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
{
"owner": "cpp",
"fileLocation": "absolute",
"pattern": {
"regexp": "^[^\\.](.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
]
},
{
"label": "Monitor: Start the monitor",
"type": "shell",
"command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py -p ${config:idf.port} monitor",
"windows": {
"command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py -p ${config:idf.portWin} monitor",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^\\.\\.(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
{
"owner": "cpp",
"fileLocation": "absolute",
"pattern": {
"regexp": "^[^\\.](.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
],
"dependsOn": "Flash - Flash the device"
},
{
"label": "OpenOCD: Start openOCD",
"type": "shell",
"presentation": {
"echo": true,
"reveal": "never",
"focus": false,
"panel": "new"
},
"command": "openocd -s ${command:espIdf.getOpenOcdScriptValue} ${command:espIdf.getOpenOcdConfigs}",
"windows": {
"command": "openocd.exe -s ${command:espIdf.getOpenOcdScriptValue} ${command:espIdf.getOpenOcdConfigs}",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": {
"owner": "cpp",
"fileLocation": "absolute",
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"label": "adapter",
"type": "shell",
"command": "${config:idf.pythonBinPath}",
"isBackground": true,
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}",
"PYTHONPATH": "${command:espIdf.getExtensionPath}/esp_debug_adapter/debug_adapter"
}
},
"problemMatcher": {
"background": {
"beginsPattern": "\bDEBUG_ADAPTER_STARTED\b",
"endsPattern": "DEBUG_ADAPTER_READY2CONNECT",
"activeOnStart": true
},
"pattern": {
"regexp": "(\\d+)-(\\d+)-(\\d+)\\s(\\d+):(\\d+):(\\d+),(\\d+)\\s-(.+)\\s(ERROR)",
"file": 8,
"line": 2,
"column": 3,
"severity": 4,
"message": 9
}
},
"args": [
"${command:espIdf.getExtensionPath}/esp_debug_adapter/debug_adapter_main.py",
"-e",
"${workspaceFolder}/build/${command:espIdf.getProjectName}.elf",
"-s",
"${command:espIdf.getOpenOcdScriptValue}",
"-ip",
"localhost",
"-dn",
"${config:idf.adapterTargetName}",
"-om",
"connect_to_instance"
],
"windows": {
"command": "${config:idf.pythonBinPathWin}",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}",
"PYTHONPATH": "${command:espIdf.getExtensionPath}/esp_debug_adapter/debug_adapter"
}
}
}
}
]
}
\ No newline at end of file
From 8c8c4bd282ed5bf359ef1c0eaeace4c4fbe8ff52 Mon Sep 17 00:00:00 2001
From: supperthomas <78900636@qq.com>
Date: Mon, 18 Apr 2022 22:59:02 +0800
Subject: [PATCH] add fixed of rtthread
---
.../esp_system/ld/esp32c3/sections.ld.in | 19 ++
components/freertos/port/port_common.c | 11 +-
components/freertos/port/port_systick.c | 56 ++---
components/riscv/vectors.S | 236 +++++++++++++++---
4 files changed, 254 insertions(+), 68 deletions(-)
diff --git a/components/esp_system/ld/esp32c3/sections.ld.in b/components/esp_system/ld/esp32c3/sections.ld.in
index 0ebeda06c1..10506d38a3 100644
--- a/components/esp_system/ld/esp32c3/sections.ld.in
+++ b/components/esp_system/ld/esp32c3/sections.ld.in
@@ -183,6 +183,25 @@ SECTIONS
_noinit_end = ABSOLUTE(.);
} > dram0_0_seg
+ .stack_dummy (COPY):
+ {
+ . = ALIGN(8);
+ __STACKSIZE__ = 40960;
+ __stack_start__ = .;
+ *(.stack*)
+ . += __STACKSIZE__;
+ __stack_cpu0 = .;
+ __stack_end__ = .;
+ } > dram0_0_seg
+
+ .stack_dummy (COPY):
+ {
+ . = ALIGN(8);
+ __HEAPSIZE__ = 40960;
+ __heap_start__ = .;
+ . += __STACKSIZE__;
+ __heap_end__ = .;
+ } > dram0_0_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
diff --git a/components/freertos/port/port_common.c b/components/freertos/port/port_common.c
index ffca3d5429..dd3cc46f16 100644
--- a/components/freertos/port/port_common.c
+++ b/components/freertos/port/port_common.c
@@ -74,11 +74,12 @@ void esp_startup_start_app_common(void)
esp_gdbstub_init();
#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
- portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main",
- ESP_TASK_MAIN_STACK, NULL,
- ESP_TASK_MAIN_PRIO, NULL, ESP_TASK_MAIN_CORE);
- assert(res == pdTRUE);
- (void)res;
+ // portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main",
+ // ESP_TASK_MAIN_STACK, NULL,
+ // ESP_TASK_MAIN_PRIO, NULL, ESP_TASK_MAIN_CORE);
+ ///assert(res == pdTRUE);
+ app_main();
+ //(void)res;
}
static void main_task(void* args)
diff --git a/components/freertos/port/port_systick.c b/components/freertos/port/port_systick.c
index 0c14a155a1..cf525f9383 100644
--- a/components/freertos/port/port_systick.c
+++ b/components/freertos/port/port_systick.c
@@ -116,34 +116,34 @@ void vPortSetupTimer(void)
*/
IRAM_ATTR void SysTickIsrHandler(void *arg)
{
- uint32_t cpuid = xPortGetCoreID();
- systimer_hal_context_t *systimer_hal = (systimer_hal_context_t *)arg;
-#ifdef CONFIG_PM_TRACE
- ESP_PM_TRACE_ENTER(TICK, cpuid);
-#endif
-
- uint32_t alarm_id = SYSTIMER_LL_ALARM_OS_TICK_CORE0 + cpuid;
- do {
- systimer_ll_clear_alarm_int(systimer_hal->dev, alarm_id);
-
- uint32_t diff = systimer_hal_get_counter_value(systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK) / systimer_ll_get_alarm_period(systimer_hal->dev, alarm_id) - s_handled_systicks[cpuid];
- if (diff > 0) {
- if (s_handled_systicks[cpuid] == 0) {
- s_handled_systicks[cpuid] = diff;
- diff = 1;
- } else {
- s_handled_systicks[cpuid] += diff;
- }
-
- do {
- xPortSysTickHandler();
- } while (--diff);
- }
- } while (systimer_ll_is_alarm_int_fired(systimer_hal->dev, alarm_id));
-
-#ifdef CONFIG_PM_TRACE
- ESP_PM_TRACE_EXIT(TICK, cpuid);
-#endif
+// uint32_t cpuid = xPortGetCoreID();
+// systimer_hal_context_t *systimer_hal = (systimer_hal_context_t *)arg;
+// #ifdef CONFIG_PM_TRACE
+// ESP_PM_TRACE_ENTER(TICK, cpuid);
+// #endif
+
+// uint32_t alarm_id = SYSTIMER_LL_ALARM_OS_TICK_CORE0 + cpuid;
+// do {
+// systimer_ll_clear_alarm_int(systimer_hal->dev, alarm_id);
+
+// uint32_t diff = systimer_hal_get_counter_value(systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK) / systimer_ll_get_alarm_period(systimer_hal->dev, alarm_id) - s_handled_systicks[cpuid];
+// if (diff > 0) {
+// if (s_handled_systicks[cpuid] == 0) {
+// s_handled_systicks[cpuid] = diff;
+// diff = 1;
+// } else {
+// s_handled_systicks[cpuid] += diff;
+// }
+
+// do {
+// xPortSysTickHandler();
+// } while (--diff);
+// }
+// } while (systimer_ll_is_alarm_int_fired(systimer_hal->dev, alarm_id));
+
+// #ifdef CONFIG_PM_TRACE
+// ESP_PM_TRACE_EXIT(TICK, cpuid);
+// #endif
}
#endif // CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
diff --git a/components/riscv/vectors.S b/components/riscv/vectors.S
index 1006d5bea5..91bb4aa39e 100644
--- a/components/riscv/vectors.S
+++ b/components/riscv/vectors.S
@@ -17,6 +17,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)
@@ -218,25 +221,25 @@ _call_panic_handler:
*/
.global _interrupt_handler
.type _interrupt_handler, @function
-_interrupt_handler:
+_interrupt_handler1:
/* entry */
- save_regs
- save_mepc
+ save_regs /* 保存寄存器 */
+ save_mepc /* 保存MEPC */
/* Before doing anythig preserve the stack pointer */
/* It will be saved in current TCB, if needed */
- mv a0, sp
+ mv a0, sp /* 保存SP a0 = sp */
call rtos_int_enter
/* Before dispatch c handler, restore interrupt to enable nested intr */
- csrr s1, mcause
- csrr s2, mstatus
+ csrr s1, mcause /* 保存mcause s1 = mcause */
+ csrr s2, mstatus /* 保存mstatus s2 = mstatus */
- /* Save the interrupt threshold level */
- la t0, INTERRUPT_CORE0_CPU_INT_THRESH_REG
- lw s3, 0(t0)
+ /* Save the interrupt threshold level 保存中断嵌套层数? */
+ la t0, INTERRUPT_CORE0_CPU_INT_THRESH_REG /* 保存mstatus t0 = &INTERRUPT_CORE0_CPU_INT_THRESH_REG */
+ lw s3, 0(t0) /* s3 = mstatus */
- /* Increase interrupt threshold level */
+ /* Increase interrupt threshold level 增加中断嵌套层数*/
li t2, 0x7fffffff
and t1, s1, t2 /* t1 = mcause & mask */
slli t1, t1, 2 /* t1 = mcause * 4 */
@@ -247,56 +250,219 @@ _interrupt_handler:
sw t2, 0(t0) /* INTERRUPT_CORE0_CPU_INT_THRESH_REG = t2 */
fence
- li t0, 0x8
- csrrs t0, mstatus, t0
-
- #ifdef CONFIG_PM_TRACE
- li a0, 0 /* = ESP_PM_TRACE_IDLE */
- #if SOC_CPU_CORES_NUM == 1
- li a1, 0 /* No need to check core ID on single core hardware */
- #else
- csrr a1, mhartid
- #endif
- la t0, esp_pm_trace_exit
- jalr t0 /* absolute jump, avoid the 1 MiB range constraint */
- #endif
+ li t0, 0x8 /* t0 = 8 */
+ csrrs t0, mstatus, t0 /*设置状态MIE寄存器,开总中断*/
- #ifdef CONFIG_PM_ENABLE
- la t0, esp_pm_impl_isr_hook
- jalr t0 /* absolute jump, avoid the 1 MiB range constraint */
- #endif
/* 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 */
+ /* mask off the interrupt flag of mcause 屏幕异常中断*/
li t0, 0x7fffffff
and a1, a1, t0
jal _global_interrupt_handler
- /* After dispatch c handler, disable interrupt to make freertos make context switch */
+ /* After dispatch c handler, disable interrupt to make freertos make context switch
+ 在调用c函数之后,disable 中断让freertos能够做内容切换
+ */
li t0, 0x8
- csrrc t0, mstatus, t0
+ csrrc t0, mstatus, t0 /*清状态MIE寄存器 关总中断*/
- /* restore the interrupt threshold level */
+
+ /* restore the interrupt threshold level 中断嵌套 */
la t0, INTERRUPT_CORE0_CPU_INT_THRESH_REG
sw s3, 0(t0)
fence
/* Yield to the next task is needed: */
- mv a0, sp
+ mv a0, sp /* a0 = sp*/
call rtos_int_exit
/* The next (or current) stack pointer is returned in a0 */
- mv sp, a0
+ mv sp, a0 /* sp = a0*/
/* restore the rest of the registers */
- csrw mcause, s1
- csrw mstatus, s2
+ csrw mcause, s1 /* mcause = s1 */
+ csrw mstatus, s2 /* mstatus = s2 */
restore_mepc
restore_regs
/* exit, this will also re-enable the interrupts */
mret
+ .size _interrupt_handler1, .-_interrupt_handler1
+
+
+
+_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 */
+
+ /* 将 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
--
2.35.1.windows.2
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(rtthread)
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := rtthread
include $(IDF_PATH)/make/project.mk
# ESP32-C3 BSP 说明
## 简介
本文档为 乐鑫ESP32-C3 开发板的[ESP32C3](http://luatos.com/t/esp32c3) BSP (板级支持包) 说明。
主要内容如下:
- 开发板资源介绍
- BSP 快速上手
通过阅读快速上手章节开发者可以快速地上手该 BSP,将 RT-Thread 运行在开发板上。
## 开发板介绍
目前测试了两款开发板,运行都正常,由于两款开发板LED小灯引脚不同,请根据自己开发板修改GPIO引脚,目前默认使用的开发板是LUATOS_ESP32C3。已测开发板外观如下图所示:
- [LUATOS_ESP32C3](https://wiki.luatos.com/chips/esp32c3/board.html)
![LUATOS_ESP32C3](images/luatos_esp32c3.png)
- [HX-DK-商](https://docs.wireless-tech.cn/doc/7/)
![hongxu](images/hx_shang.png)
该LUATOS_ESP32C3开发板常用 **板载资源** 如下:
- MCU:[esp32-c3](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf),主频 160MHz, 407.22 CoreMark; 2.55 CoreMark/MHz
- 芯片内置:384KB ROM, 400KB SRAM,
- 常用外设
- 红色LED:2个,D4 (IO12), D5(IO13)
- 按键:2个,K1(BOOT) K2(RST)
- SPI FLASH: 2M
- 常用接口:USB UART等
开发板更多详细信息请参考 [ESP32-C3开发板介绍](https://wiki.luatos.com/chips/esp32c3/board.html)
## 外设支持
本 BSP 目前对外设的支持情况如下:
| **片上外设** | **支持情况** | **备注** |
| :----------------- | :----------: | :------------------------------------- |
| GPIO | 待支持 | |
| UART | 待支持 | |
## 使用说明
### 快速上手
说先要搭建IDE开发环境,乐鑫官方推荐使用IDF开发。
IDF的搭建方法有很多种,尝试了很多种方法之后,总结了一个最快速的方法,并且可以使用vscode跨平台安装,非常简单方便,具体方法见链接[ESP-IDF 一键式搭建环境基于VSCODE](https://blog.csdn.net/lt6210925/article/details/123699249)。 安装的时候IDF版本请选择IDF 4.4版本。如果你对官方IDF命令行的方式熟悉的话,你也可以使用命令行的方式,这边已经测试过,是可以使用的。
### IDF patch加载
由于IDF使用的是FREERTOS需要修改一些文件,将`0001-add-fixed-of-rtthread.patch` 这个文件拷贝到安装的时候的IDF的代码目录,执行命令 `git apply 0001-add-fixed-of-rtthread.patch` 打上patch
#### 编译下载
编译选择最下面的按钮:
![build](images/build.png)
这边通常采用串口下载,需要根据你自己开发板选择对应的串口(如果有JTAG的,也可以用JTAG下载和调试)
![burn](images/burn.png)
#### 运行结果
下载程序成功之后,系统会运行,红色的 D4以 1S 周期闪烁。
刚接触ESP32, 目前仅实现LED小灯闪烁,可以print打印,后续计划将pin设备和console对接上去,也欢迎大家一起来贡献,感兴趣的可以通过公众号`Thomas的小火车`来联系
## 注意事项
- 目前RTTHREAD支持起来了,后续会需要继续完善一些其他功能,刚开始使用ESP32,欢迎小伙伴一起来讨论和贡献。
## 联系人信息
维护人:
- [supperthomas](https://github.com/supperthomas) 邮箱:<78900636@qq.com>
## 特别感谢
- 感谢[chenyingchun0312](https://github.com/chenyingchun0312) 提供了RISCV的强力支持
idf_component_register(SRCS "main.c"
"../../../libcpu/risc-v/common/cpuport.c"
"../../../libcpu/risc-v/common/context_gcc.S"
"../../../src/components.c"
"../../../src/scheduler.c"
"../../../src/device.c"
"../../../src/clock.c"
"../../../src/irq.c"
"../../../src/thread.c"
"../../../src/mempool.c"
"../../../src/ipc.c"
"../../../src/mem.c"
"../../../src/object.c"
"../../../src/idle.c"
"../../../src/timer.c"
"../../../src/kservice.c"
INCLUDE_DIRS
"../../../include"
"../../../libcpu/risc-v/common"
"../")
ADD_DEFINITIONS(
-D__RTTHREAD__
)
\ No newline at end of file
/*
* Copyright (c) 2021-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-04-24 supperthomas first version
*/
#include <stdio.h>
#include "driver/gpio.h"
#include "esp_private/panic_internal.h"
#include "hal/uart_hal.h"
#include "driver/timer.h"
#include "soc/periph_defs.h"
#include "hal/systimer_hal.h"
#include "hal/systimer_ll.h"
#include "esp_intr_alloc.h"
#include "rtthread.h"
#include "rthw.h"
void main_thread_entry(void *parameter)
{
#define BLINK_GPIO 12
gpio_reset_pin(BLINK_GPIO);
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
while (1)
{
gpio_set_level(BLINK_GPIO, 1);
rt_thread_mdelay(1000);
gpio_set_level(BLINK_GPIO, 0);
rt_thread_mdelay(1000);
}
}
void rt_application_init(void)
{
rt_thread_t tid;
#define RT_MAIN_THREAD_STACK_SIZE 2048
#define RT_MAIN_THREAD_PRIORITY 10
tid = rt_thread_create("main", main_thread_entry, RT_NULL,
RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(tid != RT_NULL);
rt_thread_startup(tid);
}
//component
static uint32_t uwTick = 0;
static systimer_hal_context_t systimer_hal;
IRAM_ATTR void rt_SysTickIsrHandler(void *arg)
{
systimer_ll_clear_alarm_int(systimer_hal.dev, 1);
rt_interrupt_enter();
rt_tick_increase();
uwTick++;
/* leave interrupt */
rt_interrupt_leave();
systimer_ll_is_alarm_int_fired(systimer_hal.dev, 1);
}
void rt_hw_systick_init(void)
{
uint8_t system_timer_counter=1;
//rt_hw_interrupt_enable(0);
esp_intr_alloc(ETS_SYSTIMER_TARGET1_EDGE_INTR_SOURCE, ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_LEVEL1, rt_SysTickIsrHandler, &systimer_hal, NULL);
systimer_hal_init(&systimer_hal);
systimer_ll_set_counter_value(systimer_hal.dev, system_timer_counter, 0);
systimer_ll_apply_counter_value(systimer_hal.dev, system_timer_counter);
uint32_t alarm_id = 1 ;
systimer_hal_connect_alarm_counter(&systimer_hal, alarm_id, system_timer_counter);
systimer_hal_set_alarm_period(&systimer_hal, alarm_id, 1000000UL / 1000);
systimer_hal_select_alarm_mode(&systimer_hal, alarm_id, SYSTIMER_ALARM_MODE_PERIOD);
systimer_hal_counter_can_stall_by_cpu(&systimer_hal, 1, 0, true);
systimer_hal_enable_alarm_int(&systimer_hal, alarm_id);
systimer_hal_enable_counter(&systimer_hal, SYSTIMER_LL_COUNTER_OS_TICK);
}
void rt_hw_board_init(void)
{
rt_hw_systick_init();
extern int __heap_start__;
extern int __heap_end__;
printf("%s:%d__heap_start__:%p,__heap_end__:%p\n",__func__,__LINE__,&__heap_start__,&__heap_end__);
rt_system_heap_init((void *)&__heap_start__, (void *)&__heap_end__);
}
static void rtthread_startup(void)
{
rt_hw_interrupt_disable();
/* init board */
rt_hw_board_init();
/* show RT-Thread version */
rt_show_version();
/* timer system initialization */
rt_system_timer_init();
/* scheduler system initialization */
rt_system_scheduler_init();
/* create init_thread */
rt_application_init();
/* timer thread initialization */
rt_system_timer_thread_init();
/* idle thread initialization */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* init scheduler system */
/* never reach here */
return ;
}
void app_main(void)
{
/* startup RT-Thread RTOS */
rtthread_startup();
return;
}
#ifndef RT_CONFIG_H__
#define RT_CONFIG_H__
/* Automatically generated file; DO NOT EDIT. */
/* RT-Thread Configuration */
/* RT-Thread Kernel */
#define RT_NAME_MAX 8
#define RT_ALIGN_SIZE 4
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 1000
#define IDLE_THREAD_STACK_SIZE 256
/* kservice optimization */
/* Inter-Thread communication */
#define RT_USING_SEMAPHORE
/* Memory Management */
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_SMALL_MEM_AS_HEAP
#define RT_USING_HEAP
/* Kernel Device Object */
#define RT_VER_NUM 0x40004
/* RT-Thread Components */
/* C++ features */
/* Command shell */
/* Device virtual file system */
/* Device Drivers */
/* Using USB */
/* POSIX layer and C standard library */
/* Network */
/* Socket abstraction layer */
/* Network interface device */
/* light weight TCP/IP stack */
/* AT commands */
/* VBUS(Virtual Software BUS) */
/* Utilities */
/* RT-Thread Utestcases */
/* RT-Thread online packages */
/* IoT - internet of things */
/* Wi-Fi */
/* Marvell WiFi */
/* Wiced WiFi */
/* IoT Cloud */
/* security packages */
/* language packages */
/* JSON: JavaScript Object Notation, a lightweight data-interchange format */
/* XML: Extensible Markup Language */
/* multimedia packages */
/* LVGL: powerful and easy-to-use embedded GUI library */
/* u8g2: a monochrome graphic library */
/* PainterEngine: A cross-platform graphics application framework written in C language */
/* tools packages */
/* system packages */
/* enhanced kernel services */
/* POSIX extension functions */
/* acceleration: Assembly language or algorithmic acceleration packages */
/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
/* Micrium: Micrium software products porting for RT-Thread */
/* peripheral libraries and drivers */
/* AI packages */
/* miscellaneous packages */
/* project laboratory */
/* samples: kernel and components samples */
/* entertainment: terminal games and other interesting software packages */
#endif
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册