0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

全志D1程序烧录失败引发的向量指令的学习

冬至子 来源:牧尘 作者:牧尘 2023-09-13 16:12 次阅读

前一段时间遇到给D1下载程序触发异常的问题。研究许久无果,多日后终得解决。

问题
使用全志提供的命令下载的方式,若在第一个线程启动前不做停止操作(添加while(1),延时)等操作,使用该种方式下载会触发异常。

使用全志PhoenixSuit工具下载不会触发异常。

问题定位
最终问题出现定位在第一个线程启动前。可惜水平有限,还是没找到原因。

问题解决
经高人指点,发现mstatus中的vs位在第一个线程启动前被修改。

于是在启动第一个线程前,开始排查修改vs位的地方。

最终发现是在初始化线程的现场时被修改。

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;
}
上述代码修改前,下载会触发异常:

frame- >mstatus = MSTATUS_PUM | MSTATUS_FS | MSTATUS_MPP | MSTATUS_MPIE;    /* enable FPU */

修改后,下载正常:

frame- >mstatus = MSTATUS_VS| MSTATUS_PUM | MSTATUS_FS | MSTATUS_MPP | MSTATUS_MPIE;    /* enable FPU */

为什么这么改?请看下文:

事情到这就清晰了,是因为没有初始化向量指令控制位VS.

1.jpg

回到最初的问题:

下载主要的操作就是数据拷贝,使用向量指令拷贝会大大加速下载速度,所以全志的下载算法会使用向量指令去拷贝,这里没有初始化VS,当然会触发异常了。

到这还有个疑问:

mstatus的vs在用户程序中修改的,这里按道理已经在用户程序了,整么还在下载,这个问题就不得而知了,你知道吗,反正我不知道

一番操作过后,看看这个向量指令到底是个啥吧:

向量指令
向量指令:单条指令操作多个数据,并行

使用场景:数据拷贝 用并行方式代替循环的方式

向量指令使用举例:
一段上下文切换中的代码:

#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小学生,不住之处请多多指教.

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 控制器
    +关注

    关注

    112

    文章

    16191

    浏览量

    177346
  • 寄存器
    +关注

    关注

    31

    文章

    5310

    浏览量

    119983
  • 触发器
    +关注

    关注

    14

    文章

    1995

    浏览量

    61044
  • RT-Thread
    +关注

    关注

    31

    文章

    1272

    浏览量

    39905
收藏 人收藏

    评论

    相关推荐

    平头哥D1 DocK Pro开发板上手评测

    Lichee RV Dock是志在线AWOL联合深圳矽速科技sipeed推出的一款基于珠海D1 CPU的单板计算机,其主控
    的头像 发表于 07-14 15:02 1132次阅读
    平头哥<b class='flag-5'>D1</b> DocK Pro开发板上手评测

    #科技 D1芯片 #开箱 视频

    whycan晕哥
    发布于 :2022年09月23日 22:28:46

    如何解决D1 SDK附带的g++不支持RVV的问题?

    我在使用D1 SDK交叉编译OpenCV时遇到下面提示:Performing Test HAVE_CPU_RVV_SUPPORT (check file: cmake/checks
    发表于 12-28 06:29

    请问D1芯片如何对D1主频进行调节?

    D1项目开发的过程中,有时候需要调节CPU主频,以对一些场景、功耗或性能进行测试,那么D1芯片如何对D1主频进行调节?
    发表于 12-29 06:20

    D1-H裸奔工具XFEL

    工欲善其事,必先利其器,D1沿用传统设计思路,brom里面集成了FEL模式,这个模式是一个很有用的模式,可以烧录,测试,能干的事情很多,本来这种工具也是有成熟的可用,比如:sunx
    发表于 03-14 16:48

    如何解决D1 SDK附带的g++不支持RVV的问题?

    我在使用D1 SDK交叉编译OpenCV时遇到下面提示:Performing Test HAVE_CPU_RVV_SUPPORT (check file: cmake/checks
    发表于 03-29 19:15

    D1开发板RISCV64开箱评测

    /perf-abc-risc-v-soc-board 还有awol的社区也很多相关的资料 https://bbs.aw-ol.com/category/6/d1 但是对于底层编程来说,关键的芯片手册,寄存器手册,还是很关键。
    发表于 08-16 07:05

    符合Open Board规范的首款开发板科技D1哪吒开始正式发售

    近日,符合Open Board规范的第一款开发板——科技D1哪吒开始正式线上发售。   该开发板由科技全资子公司
    的头像 发表于 05-25 10:06 3996次阅读

    D1芯片的启动流程最底层分析

    关于d1哪吒开发板的启动流程分析 1.本文概述 2.D1上电后启动的第一个程序 3.启动SPL 4.启动opensbi 5.裸机程序的编写
    的头像 发表于 06-15 17:44 8662次阅读

    D1和t113对比

    D1和t113对比 D1和t113是两款非常常见的芯片,比较轻巧,适合需要轻松搭建系统的
    的头像 发表于 08-17 11:28 3375次阅读

    D1和h3的参数对比

    D1和h3的参数对比 科技旗下的D1和H3是两款热门的芯片,也是家庭智能终端产品中常见的
    的头像 发表于 08-17 11:28 2742次阅读

    d1d1-h的区别

    d1d1-h的区别
    的头像 发表于 08-17 11:28 1927次阅读

    D1与f1c200s性能比较

    D1与f1c200s性能比较 D1和f
    的头像 发表于 08-17 11:28 4139次阅读

    20210520定位图D1哪吒开发板

    20210520定位图D1哪吒开发板
    发表于 03-21 09:51 2次下载

    20210520定位图D1哪吒开发板

    20210520定位图D1哪吒开发板
    发表于 10-19 15:11 0次下载