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

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

3天内不再提示

RISC-V MCU开发实战 (三):移植鸿蒙OS项目

电子发烧友论坛 来源:未知 作者:肖冰 2021-11-01 11:08 次阅读
移植准备:
步骤一:MRS中新建一个CH32V307的工程,将源码直接拖到工程中,就添加进来了,然后去添加头文件路径即可22c30b86-3a1a-11ec-82a9-dac502259ad0.png源码中包含比较全面,我们可以选择不需要的部分将其排除在编译之外,2330a04c-3a1a-11ec-82a9-dac502259ad0.png操作方法为右键目录或文件,点击Include/Exclude From Build菜单项恢复编译,同样的方法再选一遍即可。
下面说些移植操作系统的注意事项: ARM上移植实时操作系统大家可能比较熟悉,对于RISC-V内核的MCU,可能相对比较陌生。下面结合WCH的CH32V103CH32V307两款芯片来详细说下针对RISC-V平台,移植实时操作系统的注意点。 在移植前,有必要对RISC-V的一些基本知识点有一定的了解,这里对RISC-V的概况,发展,指令集,特权模式等不作详述,仅结合WCH的RISC-V内核的MCU,简单介绍我们移植实时操作系统有可能遇到的关键点做一下描述。 这里之所以选取V103和V307两款芯片,主要其极具代表性: 首先,直观上其外设的使用方法和我们之前熟悉的F103,F107等是兼容的,这样降低了我们使用和移植时的难度,基于WCH提供的外设库,我们以前上层的代码甚至于不用修改可直接使用。 其次,V103是WCH RISC-V内核家族中的V3内核,V307为V4内核,V3内核支持RV32IMAC指令集,即除支持RISC-V基本的32位整数指令集外,还支持硬件乘除法,原子指令,压缩指令。V4在V3的基础上增加了单精度硬件浮点,并且其性能也比V3高。 除上述之外,虽然两者的中断控制器(PFIC)相较于现行的PLIC均不同,均不是统一入口,而是采用中断向量表寻址的方式,但是V3的中断向量表处存放是一条指令,而V4的向量表既可以存放指令,也可以存放中断处理函数的地址。两者均支持中断嵌套和硬件压栈,区别在于V3最大嵌套两级,V4最大可达八级,同时V3的硬件压栈深度两级,V4的硬件压栈深度为三级。这里需要注意的是,移植实时操作系统时需要关闭硬件压栈,在切换任务时所有寄存器,我们希望是由我们自己控制其压栈和出栈的内容。 RISC-V寄存器如下图所示,其中x0-x31为整形寄存器,f0-f31为浮点寄存器(V3没有浮点寄存器)。所有带caller的寄存器,当发生中断时需要保存,值得注意的是,WCH的硬件压栈保存的寄存器仅仅保存整数的16个caller saved 寄存器。正常一个中断函数的寄存器保存我们不用关心,编译器会帮我们做的很好。但是当我们从一个汇编入口进中断函数的时候这些过程就不得不由我们自己来实现。寄存器中几个相对特殊的x0恒为0,x1是返回地址寄存器ra,函数调用时用来存放返回地址,x2为堆栈指针sp,x3为gp全局指针,用来寻址全局变量。对于一个正常运行的程序,除了x0,gp两个初始值固定的外,其余的均会是不确定的,所有在进行上下文保护时,均需要保存。用到硬件浮点的时候,更是要保存32个浮点寄存器。23a3deae-3a1a-11ec-82a9-dac502259ad0.png 除了上述的寄存器,移植还要关心的是几个csr寄存器mstatus,mepc。正常情况下大部分csr只能在机器模式下操作(WCH的v3和v4内核支持机器模式和用户模式)。mstatus中,MIE为中断使能,当进中断时MPIE更新为MIE,返回时MIE更新为MPIE。MPP用于保存进中断之前的特权模式,如果我们设置其为MPP=0b11,那么将一直处于机器模式,其mret返回后还是处于机器模式。mepc是机器模式下异常程序指针,其只会在发生异常是被更新(中断也是一类异常),进异常时我们可以从另外两个csr寄存器mcause来看引起异常原因通过mtval查看引起异常时的值。当从异常返回时mepc的值被更新给pc。我们正是通过进中断修改mepc来实现任务的切换的,后面会详细说明这个过程。 实时操作系统大家应该不陌生,常见的uCOSFreeRTOSRT-Thread,LiteOS-M等等,其基本的思路都是一样的,需要一个定时器用于系统时间片的实现,一个中断用于任务切换。想要其能够在一个MCU上成功的跑起来,需要弄清除一下几个事情:
(1)进中断需要保存哪些内容。
从之前的描述中,应该知道,对于risc-v内核来说其进中断压栈的是caller saved的寄存器。从下图一可以看出,进Systick中断函数,先进行寄存器保存,退出中断时进行寄存器恢复,如果开启硬件浮点,同时还会对浮点寄存器进行保存和恢复。这个过程是编译器帮我们实现,有一点需要注意的是我们移植的代码里面进中断后获取了中断的堆栈“csrrw sp,mscratch,sp”,返回时恢复了线程的堆栈指针“csrrw sp,mscratch,sp”中断堆栈指针初始值是在任务开始时存入mscratch寄存器的,如果采用C形式中断函数,中断堆栈的获取会在压栈操作之后,中断压入的堆栈是当前运行任务的任务堆栈区域,如果想要中断函数压栈时压入的自己的堆栈区域,可以使用汇编入口,进中断后先修改sp,然后压栈,再调用中断处理函数,如图二所示。241e58dc-3a1a-11ec-82a9-dac502259ad0.png 图1 249d26b2-3a1a-11ec-82a9-dac502259ad0.png 图2 (2)任务栈需要保存哪些内容。
前文说过对于一个正常运行的程序,切换任务前,除了x0恒0,x3 gp指针外,其余的寄存器均需要保存,每个RTOS中都会定义一个上下文保存相关的结构体,这里我们以华为鸿蒙LiteOS_M为例,看一下这个结构体:24f7b550-3a1a-11ec-82a9-dac502259ad0.png 图3在创建任务的时候均会为一个任务分配一个id和堆栈大小并对这个堆栈做初始化:258e3ee4-3a1a-11ec-82a9-dac502259ad0.png 图4 261155a4-3a1a-11ec-82a9-dac502259ad0.png 图5任务创建好了后会关联一个根据任务id关联一个任务控制块taskCB,总的任务个数是在头文件中配置的(target_config.h)总的任务块的初始化也是在LOS_KernelInit被初始化。269261f8-3a1a-11ec-82a9-dac502259ad0.png 图6从上面可以看出来,task--->taskCB--->sp指针--->memory这样的路线,而这片memory开始位置用于上下文保存。
这样的方式在其他RTOS中也可以看到,例如RT-Thread中用于上下文保存的结构体rt_hw_stack_frame,和taskCB类似的结构体rt_thread等。27276988-3a1a-11ec-82a9-dac502259ad0.png图727a4d9d6-3a1a-11ec-82a9-dac502259ad0.png图8
(3)如何开启任务调度。
前面看了每个任务上下文保存位置,注意到堆栈初始化的时候把任务的入口地址给了context->epc。同时LiteOS_M源码中定义了一个LosTask类型的全局变量g_losTask,其内部只有两个任务控制块指针,一个指向当前运行的任务,一个指向新任务,即要切换至的任务。283c6152-3a1a-11ec-82a9-dac502259ad0.png图9当做好一系列初始化后,LiteOS会调用HalStartSchedule来初始化系统节拍定时器,并注册系统定时器的中断处理函数,然后开始转向执行第一个任务,如下图所示:2897cfce-3a1a-11ec-82a9-dac502259ad0.png图10其中OsSchedStart函数从任务列表中获取第一个任务,并赋值给g_losTask里面的runTask和newTask。然后调用HalStartToRun转向执行runTask所指示的任务。HalStartToRun是一段汇编代码,下面就具体看其如何切换至runTask,具体如下图的注释:292bbfae-3a1a-11ec-82a9-dac502259ad0.png图11这样mret之后就转向去执行第一个任务,并且不会再有返回,因为每个任务本身会是个循环,这里也就能理解其源码注释 never return的含义。29a57e34-3a1a-11ec-82a9-dac502259ad0.png图12其他操作系统中也有类似的操作,例如RT-Thread中有个rt_hw_context_switch_to函数,其也是汇编代码实现,它是一个带参数的函数,其传入的参数为(&to_thread->sp),如下图:2a4bfcf0-3a1a-11ec-82a9-dac502259ad0.png图13从名字就可以看出,传递的参数为启动执行的第一个线程的控制块的堆栈指针sp的值,后面赋值mepc,mstatus,其他寄存器等等都是和LiteOS_M一致的。


(4)如何进行任务切换。

了解了如何切换至第一个任务,那么如何实现不同任务之间的切换呢,在这之前我们应该都有了解,RTOS是根据任务的优先级和时间片进行轮转的,每个任务执行一段时间,然后切换至下一个任务执行。每次切换前我们需要把当前任务的运行状态进行保存,然后切换至新任务,对其运行状态进行恢复,如此循环反复,实现任务调度。时间片实现使用的是内核的SysTick定时器,LiteOS_M是在los_timer.c中实现的,这个只需要根据实际硬件的进行初始化就行。其他操作系统也是类似,像RT-Thread源码中我们根据硬件完成board.c。对于任务切换,我们利用内核的软中断,只要使能该中断,并且当需要切换任务时,把中断控制器的对应的pendset位置1,即可触发该中断进行任务切换。下图是liteOS_M切换过程:

2aa9edec-3a1a-11ec-82a9-dac502259ad0.png图14 2b15f17c-3a1a-11ec-82a9-dac502259ad0.png图15

其他操作系统也是大同小异,具体的区别仅仅是在切换新任务时,新任务如何获取的问题,上图可以看到LiteOS_M是通过g_losTask来管理,RT-Thread中定义了from_thread,to_thread,顾名思义从一个线程切换至另外一个线程。

弄清楚以上的问题,对于某一个RTOS的基本移植来说应该就比较明了。

最后移植好的鸿蒙os,RT-Thread等实时操作系统的代码均已在MRS上线,可以直接创建,开发相关应用

2b9ca4ba-3a1a-11ec-82a9-dac502259ad0.png


原文标题:RISC-V MCU开发实战 (三):移植鸿蒙OS项目

文章出处:【微信公众号:电子发烧友论坛】欢迎添加关注!文章转载请注明出处。

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

    关注

    41

    文章

    1904

    浏览量

    45054
  • 鸿蒙OS
    +关注

    关注

    0

    文章

    147

    浏览量

    4280

原文标题:RISC-V MCU开发实战 (三):移植鸿蒙OS项目

文章出处:【微信号:gh_9b9470648b3c,微信公众号:电子发烧友论坛】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    开发板上玩GTA,RISC-V多项移植项目成功运作中

    开发板上玩GTA ,RISC-V 多项移植项目成功运作中   RISC-V近期再度掀起了不小的热度,苹果招募
    的头像 发表于 09-15 09:47 4805次阅读

    项目实战】基于RISC-V单片机的鸿蒙开发项目

    本帖最后由 张飞电子学院张角 于 2021-1-20 13:35 编辑 大家好,我是张飞实战电子的张角老师。我目前正在做的一个项目开发一块基于RISC-V架构单片机的
    发表于 01-20 13:31

    项目实战】基于RISC-V单片机的鸿蒙系统开发项目日记连载(持续更新中)

    本帖最后由 张飞电子学院张角 于 2021-3-25 15:08 编辑 大家好,我是张飞实战电子的张角老师。我目前正在做的一个项目开发一块基于RISC-V架构单片机的
    发表于 03-02 14:41

    RISC-V中***会子活动之一:基于RISC-V鸿蒙开发板设计

    RISC-V厂商、研究机构及国内高校、开源技术组织。 受RISC-V中***会主办方邀请,华秋电子联合张飞实战电子举办“基于RISC-V鸿蒙
    发表于 06-03 16:26

    项目实战】基于RISC-V单片机的鸿蒙系统开发项目日记连载【RISC-V鸿蒙开发板单片机简介】

    `作者:张角老师(张飞实战电子高级工程师)RISC-V鸿蒙开发板单片机简介我们使用的单片机是深圳睿思芯科公司出品的Pygmy-E系列的单片机,它是面向IOT超低功耗32位SOC,内含睿
    发表于 07-01 10:09

    项目实战RISC-V鸿蒙系统开发板单片机简介2-I2C接口简介

    本帖最后由 松山归人 于 2021-7-4 19:07 编辑 作者:张角老师(张飞实战电子高级工程师)RISC-V鸿蒙开发板单片机简介2这篇文章我们来简要的介绍一下Pygmy-E
    发表于 07-02 12:01

    RISC-V MCU开发 (一):集成开发环境

    基于RISC-V MCU项目开发,与之配套的集成开发环境必不可少。目前市场上可供选择的RISC
    发表于 09-22 14:44

    RISC-V MCU开发实战 ():移植鸿蒙OS项目

    Include/Exclude From Build菜单项恢复编译,同样的方法再选一遍即可。下面说些移植操作系统的注意事项ARM上移植实时操作系统大家可能比较熟悉,对于RISC-V内核的MCU
    发表于 10-28 19:33

    RISC-V/ARM IDE的相关资料分享

    RISC-V/ARM IDE ——MRS双核开发项目实战近年来,RISC-V生态发展一片欣欣向荣,众多行业巨头纷纷布局,国内也涌现了一批
    发表于 11-04 08:34

    RISC-V MCU开发相关资料分享

    工作中。 工欲善其事必先利其器,要想实现基于RISC-V MCU项目开发,与之配套的集成开发环境必不可少。目前市场上可供选择的
    发表于 11-10 07:50

    RISC-V MCU开发相关资料分享

    RISC-V MCU开发 (二):工程创建与管理MounRiver® Studio(MRS)内置了GD、WCH等芯片厂家的RISC-V/ARM以及R
    发表于 12-09 08:14

    RISC-V MCU开发的相关资料分享

    RISC-V MCU开发 (十一):跨内核工程转换大多数嵌入式工程师使用Keil进行开发,但Keil目前不支持RISC-V内核,只支持ARM
    发表于 02-11 06:17

    RISC-V MCU开发实战(一) :DHT11

    近年来,RISC-V生态获得了空前的繁荣发展,国内外众多科技公司纷纷下场布局、行业应用层出不穷,搭载RISC-V内核的MCU也逐渐走入了工程师的日常开发工作中。工欲善其事必先利其器,要
    发表于 03-06 15:17

    RISC-V MCU开发实战 ():移植鸿蒙OS项目

    ARM上移植实时操作系统大家可能比较熟悉,对于RISC-V内核的MCU,可能相对比较陌生。下面结合WCH的CH32V103和CH32V307
    发表于 03-07 10:47

    目前国内RISC-V架构的MCU从程序从arm移植RISC-V难度大吗?

    目前国内RISC-V架构的MCU从程序从arm移植RISC-V难度大吗?
    发表于 03-09 10:00