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

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

3天内不再提示

关于RTOS的基本移植鸿蒙OS项目

电子发烧友论坛 来源:电子发烧友论坛 作者:电子发烧友论坛 2021-12-01 17:07 次阅读

移植准备:

软件平台:MounRiver Studio( MRS);

硬件平台: CH32V307开发板;

源码获取:https://gitee.com/openharmony/kernel_liteos_m

步骤一:在MRS中新建一个CH32V307的工程,将源码直接拖到工程中,就添加进来了,然后去添加头文件路径即可

18faeb7c-5285-11ec-b2e9-dac502259ad0.png

源码中包含比较全面,我们可以选择不需要的部分将其排除在编译之外,操作方法为右键目录或文件,点击Include/Exclude From Build菜单项恢复编译,同样的方法再选一遍即可。

下面说些移植操作系统的注意事项:

ARM上移植实时操作系统大家可能比较熟悉,对于RISC-V内核的MCU,可能相对比较陌生。下面结合WCH的CH32V103和CH32V307两款芯片来详细说下针对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个浮点寄存器。

1927392a-5285-11ec-b2e9-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,然后压栈,再调用中断处理函数,如图二所示。

195e9816-5285-11ec-b2e9-dac502259ad0.png

图1

19911e30-5285-11ec-b2e9-dac502259ad0.png

图2

(2)任务栈需要保存哪些内容。

前文说过对于一个正常运行的程序,切换任务前,除了x0恒0,x3 gp指针外,其余的寄存器均需要保存,每个RTOS中都会定义一个上下文保存相关的结构体,这里我们以华为鸿蒙LiteOS_M为例,看一下这个结构体:

19bcc38c-5285-11ec-b2e9-dac502259ad0.png

图3在创建任务的时候均会为一个任务分配一个id和堆栈大小并对这个堆栈做初始化:

19e7012e-5285-11ec-b2e9-dac502259ad0.png

图4

1a148090-5285-11ec-b2e9-dac502259ad0.png

图5任务创建好了后会关联一个根据任务id关联一个任务控制块taskCB,总的任务个数是在头文件中配置的(target_config.h)总的任务块的初始化也是在LOS_KernelInit被初始化。

1a3da60a-5285-11ec-b2e9-dac502259ad0.png

图6从上面可以看出来,task---》taskCB---》sp指针---》memory这样的路线,而这片memory开始位置用于上下文保存。

这样的方式在其他RTOS中也可以看到,例如RT-Thread中用于上下文保存的结构体rt_hw_stack_frame,和taskCB类似的结构体rt_thread等。

1a5ddab0-5285-11ec-b2e9-dac502259ad0.png

图7

1a96f0de-5285-11ec-b2e9-dac502259ad0.png

图8

(3)如何开启任务调度。

前面看了每个任务上下文保存位置,注意到堆栈初始化的时候把任务的入口地址给了context-》epc。同时LiteOS_M源码中定义了一个LosTask类型的全局变量g_losTask,其内部只有两个任务控制块指针,一个指向当前运行的任务,一个指向新任务,即要切换至的任务。

1abe904e-5285-11ec-b2e9-dac502259ad0.png

图9当做好一系列初始化后,LiteOS会调用HalStartSchedule来初始化系统节拍定时器,并注册系统定时器的中断处理函数,然后开始转向执行第一个任务,如下图所示:

1ad415b8-5285-11ec-b2e9-dac502259ad0.png

图10其中OsSchedStart函数从任务列表中获取第一个任务,并赋值给g_losTask里面的runTask和newTask。然后调用HalStartToRun转向执行runTask所指示的任务。HalStartToRun是一段汇编代码,下面就具体看其如何切换至runTask,具体如下图的注释:

1afc5d3e-5285-11ec-b2e9-dac502259ad0.png

图11这样mret之后就转向去执行第一个任务,并且不会再有返回,因为每个任务本身会是个循环,这里也就能理解其源码注释 never return的含义。

1b282f2c-5285-11ec-b2e9-dac502259ad0.png

图12其他操作系统中也有类似的操作,例如RT-Thread中有个rt_hw_context_switch_to函数,其也是汇编代码实现,它是一个带参数的函数,其传入的参数为(&to_thread-》sp),如下图:

1b4fcd48-5285-11ec-b2e9-dac502259ad0.png

图13从名字就可以看出,传递的参数为启动执行的第一个线程的控制块的堆栈指针sp的值,后面赋值mepc,mstatus,其他寄存器等等都是和LiteOS_M一致的。

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

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

1b739ac0-5285-11ec-b2e9-dac502259ad0.png

图14

1b9e9180-5285-11ec-b2e9-dac502259ad0.png

图15

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

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

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

1bca47e4-5285-11ec-b2e9-dac502259ad0.png

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

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

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

    关注

    37

    文章

    6284

    浏览量

    121874
  • RT-Thread
    +关注

    关注

    31

    文章

    1148

    浏览量

    38867
  • 鸿蒙OS
    +关注

    关注

    0

    文章

    127

    浏览量

    4279

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

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

收藏 人收藏

    评论

    相关推荐

    鸿蒙开发实战:基于【Markwon】移植和开发

    项目是基于开源项目**Markwon**进行适用harmonyos的移植和开发的。
    的头像 发表于 03-25 16:27 461次阅读
    <b class='flag-5'>鸿蒙</b>开发实战:基于【Markwon】<b class='flag-5'>移植</b>和开发

    鸿蒙ArkUI【开发移植Carbon】

    项目是基于开源项目[Carbon] 进行harmonyos化的移植和开发的。
    的头像 发表于 03-25 15:41 205次阅读
    <b class='flag-5'>鸿蒙</b>ArkUI【开发<b class='flag-5'>移植</b>Carbon】

    2024款鸿蒙OS 最新HarmonyOS Next_HarmonyOS4.0系列教程分享

    鸿蒙的出现,标志着中国科技的崛起。HarmonyOS就是我们说的华为鸿蒙系统,截止到2023年8月4日已有超过7亿台设备搭载了鸿蒙OS系统。据多家媒体报道,2024年国内有21所985
    发表于 02-28 10:29

    盘点那些硬件+项目学习套件:Hi3861鸿蒙开发板及入门常见问题解答

    华清远见20岁了~过去3年里,华清远见研发中心针对个人开发板业务,打造了多款硬件+项目学习套件,涉及STM32单片机、嵌入式、物联网、人工智能、鸿蒙、ESP32、阿里云IoT等多技术方向。 今天我们
    发表于 02-01 16:55

    鸿蒙OS和开源鸿蒙什么关系?

    内核,其他功能都以模块的形式存在。     华为用的是鸿蒙OS 我们都知道,华为手机的鸿蒙OS是可以运行安卓软件的,是因为系统中有安卓兼容层,所以可以简单这么理解:
    的头像 发表于 01-30 15:44 375次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b>和开源<b class='flag-5'>鸿蒙</b>什么关系?

    鸿蒙 OS 应用开发初体验

    的操作系统平台和开发框架。HarmonyOS 的目标是实现跨设备的无缝协同和高性能。 DevEco Studio 对标 Android Studio,开发鸿蒙 OS 应用的 IDE。 启动页面
    发表于 11-02 19:38

    使用MM32F3270基于Azure RTOS (ThreadX) 的移植

    使用MM32F3270基于Azure RTOS (ThreadX) 的移植
    的头像 发表于 10-27 10:15 474次阅读
    使用MM32F3270基于Azure <b class='flag-5'>RTOS</b> (ThreadX) 的<b class='flag-5'>移植</b>

    Orange Pi OS(OH)发布,开源鸿蒙PC端来了!

    正式向大家宣布一个喜讯:基于OpenHarmony定制研发的Orange Pi OS(OH)即将发布!日前,迅龙开源鸿蒙的工程师团队已经在搭载RK3566的开发板Orange Pi 3B上完成
    发表于 10-26 11:32

    基于DWC_ether_qos的以太网驱动开发-RTOS环境移植LWIP与性能测试

    /s/E80GdN3RzrG3NeXfdwi4_Q 一.  前言 前面我们基于无OS环境移植了LWIP,这一篇我们来基于RTOS移植LWIP,与无O
    的头像 发表于 09-11 11:20 1091次阅读
    基于DWC_ether_qos的以太网驱动开发-<b class='flag-5'>RTOS</b>环境<b class='flag-5'>移植</b>LWIP与性能测试

    STM32 RTOS介绍

    R(real) T(time) OS 实时多任务操作系统、RTOS是一种操作系统,属于嵌入式操作系统,RTOS种类很多:有商业的、DIY和开源的。
    发表于 09-07 08:08

    史上最强Mate手机华为Mate 60 Pro推送最新鸿蒙OS 4

    史上最强Mate手机华为Mate 60 Pro推送最新鸿蒙OS 4 华为Mate 60 Pro这部号称史上最强的Mate手机华为官方已推送最新鸿蒙OS 4.0.0.113版本更新,安装
    的头像 发表于 09-06 14:45 1375次阅读

    基于DWC_ether_qos的以太网驱动开发-无OS环境移植LWIP

    /s/u1Bv6s_oh7jZ3sjS3nxbEA 一.前言 前面我们实现了数据的收发,现在我们就可以移植协议栈了。LWIP是一个适合嵌入式平台的著名的轻量级协议栈,我们这一篇就来无OS环境移植LWIP,下一篇再基于
    的头像 发表于 09-06 08:40 800次阅读
    基于DWC_ether_qos的以太网驱动开发-无<b class='flag-5'>OS</b>环境<b class='flag-5'>移植</b>LWIP

    RTOS核心:调度和分割

    对许多嵌入式项目来说,系统设计师都倾向于选择实时操作系统(RTOS)。但RTOS总是必要的吗?答案是取决于具体的应用,因此了解我们要达到什么目标是决定RTOS是必要的还是花瓶的关键。
    的头像 发表于 06-22 10:46 435次阅读

    华为鸿蒙OS4.0定档8月4号,华为Mate60首发

      在本届大会上,华为将展示鸿蒙生态界的新成果、新开放能力以及鸿蒙开发产品套件。对于许多用户来说,本次会议最值得期待的是鸿蒙os 4.0。
    的头像 发表于 06-15 10:55 4942次阅读

    51单片机可以移植RTOS吗?

    说起RTOS移植,我们首先会想到32位单片机。
    发表于 05-23 17:09 1451次阅读