Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
全志_RISCV_D1_D1S
原创征文
由全志D1程序烧录失败引发的向量指令的学习
发布于 2023-09-06 13:38:31 浏览:394
订阅该版
[tocm] # 全志D1程序烧录失败引发的向量指令的学习 前一段时间遇到给D1下载程序触发异常的问题。研究许久无果,多日后终得解决。 ## 问题 使用全志提供的命令下载的方式,若在第一个线程启动前不做停止操作(添加`while(1)`,`延时`)等操作,使用该种方式下载会触发异常。 使用全志`PhoenixSuit`工具下载不会触发异常。 ## 问题定位 最终问题出现定位在第一个线程启动前。可惜水平有限,还是没找到原因。 ## 问题解决 经高人指点,发现`mstatus`中的`vs`位在第一个线程启动前被修改。 于是在启动第一个线程前,开始排查修改`vs`位的地方。 最终发现是在初始化线程的现场时被修改。 ```c rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit) { struct rt_hw_stack_frame *frame; rt_uint8_t *stk; int i; extern int __global_pointer$; stk = stack_addr + sizeof(rt_ubase_t); stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_ubase_t)stk, REGBYTES); stk -= sizeof(struct rt_hw_stack_frame); frame = (struct rt_hw_stack_frame *)stk; for (i = 0; i < sizeof(struct rt_hw_stack_frame) / sizeof(rt_ubase_t); i++) { ((rt_ubase_t *)frame)[i] = i; } frame->ra = (rt_ubase_t)texit; frame->gp = (rt_ubase_t)&__global_pointer$; frame->a0 = (rt_ubase_t)parameter; frame->epc = (rt_ubase_t)tentry; frame->x2 = (rt_ubase_t)stk; /* force to supervisor mode(SPP=1) and set SPIE and SUM to 1 */ #ifdef ENABLE_FPU frame->mstatus = MSTATUS_VS| MSTATUS_PUM | MSTATUS_FS | MSTATUS_MPP | MSTATUS_MPIE; /* enable FPU */ #else frame->mstatus = MSTATUS_PUM | MSTATUS_MPP | MSTATUS_MPIE; #endif return stk; } ``` 上述代码修改前,下载会触发异常: ```c frame->mstatus = MSTATUS_PUM | MSTATUS_FS | MSTATUS_MPP | MSTATUS_MPIE; /* enable FPU */ ``` 修改后,下载正常: ```c frame->mstatus = MSTATUS_VS| MSTATUS_PUM | MSTATUS_FS | MSTATUS_MPP | MSTATUS_MPIE; /* enable FPU */ ``` 为什么这么改?请看下文: 事情到这就清晰了,是因为没有初始化向量指令控制位VS. ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230906/96bc2e767d004f8916099deec369c27d.png.webp) 回到最初的问题: 下载主要的操作就是数据拷贝,使用向量指令拷贝会大大加速下载速度,所以全志的下载算法会使用向量指令去拷贝,这里没有初始化`VS`,当然会触发异常了。 到这还有个疑问: `mstatus`的`vs`在用户程序中修改的,这里按道理已经在用户程序了,整么还在下载,这个问题就不得而知了,你知道吗,反正我不知道 一番操作过后,看看这个向量指令到底是个啥吧: ## 向量指令 > 向量指令:单条指令操作多个数据,并行 > 使用场景:数据拷贝 用并行方式代替循环的方式 ##### 向量指令使用举例: 一段上下文切换中的代码: ```assembly #ifdef __riscv_vector addi sp, sp, -(20+20) csrr t0, vl // 记录 矢量寄存器 能 处理的 数据 个数 sd t0, (0 +0 )(sp) // 备份 csrr t0, vtype // 描述 矢量寄存器 数据 类型 sd t0, (4 +4 )(sp) // 备份 csrr t0, vstart // 向量 起始 索引 向量指令 执行 第一个元素 的 索引 sd t0, (8 +8 )(sp) // 备份 csrr t0, vxsat // 描述 运算 结果 是否 饱和 sd t0, (12 +12 )(sp) // 备份 csrr t0, vxrm // 舍入 模式 类似四舍五入的(略) 那种 sd t0, (16 +16 )(sp) // 备份 addi sp, sp, -(256+256) vsetvli zero, zero, e8, m8 // 设置 数据宽度8(1字节) 8个向量寄存器为一组 vsb.v v0, (sp) //存储V0 ~ V7 矢量寄存器数据至 内存 存储数量 (128:矢量寄存器宽度 / 8:数据宽度) * 8:矢量寄存器组中的矢量寄存器的个数 addi sp, sp, 128// vsb.v v8, (sp) // 存储V8 ~ V15 addi sp, sp, 128 vsb.v v16, (sp)// 存储V16 ~ V23 addi sp, sp, 128 vsb.v v24, (sp)// 存储V24 ~ V31 addi sp, sp, -(256+256-128) #endif la t2, do_irq// 处理中断 jalr t2 #ifdef __riscv_vector vsetvli zero, zero, e8, m8 // 采用与之前同样的配置方式 vlb.v v0, (sp) addi sp, sp, 128//拷贝V0 ~ V7 内存 至矢量寄存器数 拷贝数量 (128:矢量寄存器宽度 / 8:数据宽度) * 8:矢量寄存器组中的矢量寄存器的个数 vlb.v v8, (sp) addi sp, sp, 128//拷贝V8 ~ V15 vlb.v v16, (sp) addi sp, sp, 128//拷贝V16 ~ V23 vlb.v v24, (sp) addi sp, sp, 128//拷贝V24 ~ V31 lwu t0, (0 +0)(sp)// 加载 vl lwu t1, (4 +4)(sp)// 加载 vtype lwu t2, (8 +8)(sp)// 加载 vstart vsetvl zero, t0, t1 // 重新设置 vl vtype csrw vstart, t2// 加载 vstart lwu t2, (12 +12)(sp) csrw vxsat, t2 // 加载 vxsat lwu t2, (16 +16)(sp) csrw vxrm, t2 // 加载 vxrm addi sp, sp, (20+20) #endif ``` RISC-V小学生,不住之处请多多指教.
2
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
rv666
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
文章
20
回答
62
被采纳
9
关注TA
发私信
相关文章
1
求助全志D1S&amp;RDC纪念版资料以及RTSMART移植教程
2
D1S scons编译
3
D1s M7工具链求寻
4
全志D1运行RT-Thread在烧录程序时异常
5
rtthread d1s编译报错
6
目前最新版的userapps如何安装D1s环境
7
[SOLVED] Not compiled for Allwinner D1H
8
导入bsp\allwinner\d1sb出错
9
[SOLVED] Allwinner D1H USB host
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
812
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
2
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部