[libcpu/risc-v]更新移植readme

This commit is contained in:
Yaochenger 2023-03-07 17:01:11 +08:00 committed by Man, Jianting (Meco)
parent e722733178
commit cfc6bf9b12
1 changed files with 31 additions and 56 deletions

View File

@ -2,7 +2,7 @@
#### 1.概述
为了简化RISC-V架构内核移植RT-Thread的流程RT-Thread提供一分通用代码于common文件夹
为了简化32位RISC-V架构内核移植RT-Thread的流程RT-Thread提供一分通用代码于common文件夹
| 文件名 | 文件内容 |
| :-----------------: | :----------------------------: |
@ -16,7 +16,7 @@
#### 2.移植接口
1软件中断触发函数通常向量管理中断需实现该函数非向量中断管理方式一般不需要
1软件中断触发函数通常向量管理中断方式需实现该函数,非向量中断管理方式一般不需要
```c
void rt_trigger_software_interrupt(void)
@ -34,7 +34,7 @@ void rt_hw_do_after_save_above(void)
步骤2加载中断处理函数的入口参数
步骤3调用中断处理函数
步骤3调用中断处理函数新移植的BSP推荐使用RT-Thread common_trap.c文件中提供的统一中断处理函数:rt_rv32_system_irq_handler
步骤4从栈中加载返回地址(ra)返回至SW_handler函数
@ -49,8 +49,6 @@ void rt_hw_do_after_save_above(void)
#### 4.移植步骤
<font color=red>对于新移植的RISC-V 32位内核若采用非向量中断管理方式推荐使用common中的文件除了下述步骤中必要的修改以及中断初始化与注册步骤外用户仅需拷贝一份cv32e40p移植文件重命名为具体内核名称即可 。</font>
- 步骤一:配置中断管理入口,相关中断入口函数位于**common/interrupt_gcc.S**,入口函数为**SW_handler**
- 根据使用的中断管理方式,执行下述操作
@ -88,7 +86,7 @@ void rt_hw_do_after_save_above(void)
- 步骤二:修改链接脚本,在中断栈顶名称后添加示例代码
- 将下述代码放置于链接脚本中中断栈顶名之后
- 将下述代码放置于链接脚本中中断栈顶名之后
```assembly
PROVIDE( __rt_rvstack = . );
@ -112,11 +110,11 @@ void rt_hw_do_after_save_above(void)
- 步骤三:实现在中断上下文切换的函数接口
<font color=red>RISC-V架构的内核通常采用非向量中断的管理方式为了进一步降低难度为用户提供了统一的中断查询分发函数以及相关函数 该部分内容位于common文件夹的trap_common.c文件中对于移植一个新的RV32内核推荐使用RT-Thread提供的统一函数接口。以下是两种实现方式的示例:</font>
<font color=red>RISC-V架构的内核通常采用非向量中断的管理方式为了进一步降低难度针对非向量模式的中断管理方式common文件夹中的trap_common.c为用户提供了一套统一的中断查询分发、中断入口函数注册以及中断初始化函数在rthw.h中声明对于移植一个新的RV32内核若采用非向量中断管理的方式推荐使用方式一若采用向量中断管理方式或针对中断的处理有专门的优化时推荐使用方式二,期望采用原有裸机工程的统一的中断查询与处理函数也可使用方式二。以下是两种实现方式的示例:</font>
采用RT-Thread通用中断分发函数
方式一:面向非向量中断管理方式(例:core-v-mcu)
采用RT-Thread提供的通用中断查询分发函数时移植文件直接拷贝一份cv32e40p内核移植文件重命名为具体内核名称即可移植代码如下
在RT-Thread的BSP框架中的board文件夹创建一个统一名称的汇编文件trap_gcc.S,将该文件添加到编译环境即可,该函数的实现如下(用户直接使用,无需修改)
```assembly
#include "cpuport.h"
@ -137,70 +135,47 @@ void rt_hw_do_after_save_above(void)
ret
```
RT-Thread提供的通用中断分发函数如下:
随后用户仅需调用rt_hw_interrupt_init进行初始化再将中断入口函数通过rt_hw_interrupt_install函数注册即可注册的中断入口函数为裸机原有的中断入口函数示例代码如下(相关设备的中断入口函数注册之前不可使用该设备):
```c
rt_weak void rt_rv32_system_irq_handler(rt_uint32_t mcause)
{
rt_uint32_t mscratch = read_csr(0x340);
rt_uint32_t irq_id = (mcause & 0x1F);
rt_uint32_t exception = !(mcause & 0x80000000);
if(exception)
{
s_stack_frame = (rt_hw_stack_frame_t *)mscratch;
rt_show_stack_frame();
}
else
{
rv32irq_table[irq_id].handler(irq_id, rv32irq_table[irq_id].param);
}
}
rt_hw_interrupt_init();//中断入口函数初始化
rt_hw_interrupt_install(0x7, timer_irq_handler, RT_NULL, "timerirq");//注册系统定时器中断入口函数
rt_hw_interrupt_install(0xb, fc_soc_event_handler1, RT_NULL, "eventirq");//注册外部中断入口函数
```
随后用户仅需调用rt_hw_interrupt_init进行初始化然后将中断入口函数通过rt_hw_interrupt_install函数注册即可注册的中断入口函数为裸机原有的中断入口函数示例代码如下:
```c
rt_hw_interrupt_init();
rt_hw_interrupt_install(0x7, timer_irq_handler, RT_NULL, "timerirq");
rt_hw_interrupt_install(0xb, fc_soc_event_handler1, RT_NULL, "eventirq");
```
(二)采用原有裸机的中断入口处理函数
新建一个文件夹,并以移植的内核的名称命名:
方式二:面向向量中断管理方式(例:CH32)与针对中断管理有专门优化的内核(例:GD32)
- 向量中断(可参考ch32)
1在刚才新建的文件夹下创建一个c文件用于实现上文提供的两个函数接口
2实现上述两个函数接口
在RT-Thread的BSP框架中的board文件夹创建需要的文件实现下述的两个函数
- 在void rt_trigger_software_interrupt(void) 中实现触发软件中断的操作
- 在void rt_hw_do_after_save_above(void)中实现触发软件中断之后的工作,通常是清除软件中断置位标志位或类似操作
- 非向量中断(可参考cv32e40p)
- 在刚才新建的文件夹下,创建一个汇编文件,实现上述提供的函数接口
- 对于非向量中断的管理方式仅需实现rt_hw_do_after_save_above函数即可
示例代码:
```assembly
- 在void rt_hw_do_after_save_above(void) 中实现触发软件中断之后的工作,通常是清除软件中断置位标志位或类似操作
- 非向量中断(期望采用原有裸机工程的统一的中断查询与处理函数)
在RT-Thread的BSP框架中的board文件夹创建一个统一名称的汇编文件trap_gcc.S,将该文件添加到编译环境即可,此步骤与方式一提供的方法相似,仅在调用中断处理函数以及传递的参数不同,需要根据具体的移植工程实现,方式二下该函数的实现如下:
示例代码:
```assembly
#include "cpuport.h"
.globl rt_hw_do_after_save_above
.type rt_hw_do_after_save_above,@function
rt_hw_do_after_save_above:
addi sp, sp, -4 // 移动栈指针
addi sp, sp, -4 // 移动栈指针
STORE ra, 0 * REGBYTES(sp) // 将返回地址寄存器值保存至栈中
csrr a0, mscratch // 加载函数入口参数
call trap_entry // 调用中断处理函数
csrr a0, mscratch// 加载函数入口参数
call trap_entry// 调用中断处理函数
LOAD ra, 0 * REGBYTES(sp) // 从栈中恢复返回地址寄存器值
addi sp, sp, 4 // 移动栈指针
ret // 返回SW_handler
```
addi sp, sp, 4// 移动栈指针
ret // 返回SW_handler
```
trap_entry为用户实现的中断源查询分发的函数在移植时仅需要将该函数名修改为用户的中断查询分发函数即可。