一个专门为水下机器人(ROV/AUV)进行优化的实时操作系统,暂命名为 Nitori
,中文名 荷取
可以通过修改硬件兼容层(Port)进行移植
预计最初版本支持stm32f407和stm32h750,并在实验室目前的水下机器人中进行部署
- ROV/AUV任务对RTOS内核多线程依赖轻,传统RTOS内核冗余大:一般的ROV/AUV的单片机主控系统只需要线程调度、信号量和消息队列功能,并开启少量的线程即可完成常用的传感器数据采集、舵机/推进器控制任务;复杂的网络通讯任务都会通过上位的Linux主机完成,但有时MCU还需要使用TCP/IP传输数据,使用IoT-OS会导致很多性能损失
- ROV/AUV控制逻辑可重用性高,底层设备可重用性低,需要针对硬件优化,而传统RTOS往往专注于顶层软件逻辑重用而忽视控制逻辑重用:ROV制造目的千奇百怪,可以重用的硬件驱动部分仅仅包括基本的水下传感器读取、摄像头数据读取、姿态控制和数据传输,更高层次的软件架构可重用性接近0
- ROV/AUV实时性、安全性要求高,而传统RTOS的线程间通讯机制缓慢,并且稳定性较低:理论上使用裸机编程和FPGA(ASIC)进行控制可以达到最高的实时性,但是相对实现难度较高;MCU控制时则需要保证CPU在大量传感器数据接收和上位机通信两任务间进行快速通信,并在未收取到传感器数据或与上位机连接中断的情况下及时报错,传统RTOS难以高效实现功能
- 传统RTOS很难支持对FPGA的调度:由于水下声学、水下视觉往往需要利用CNN等算法机制,这些神经网络算法需求算力高但水下舱内环境很难支持GPU等,所以往往需要使用FPGA进行运算加速,传统RTOS缺少对异构计算设备的软件包支持
- 没有一个可用于机器人控制的分布式RTOS:由于ROV/AUV的舱体积限制,往往难以搭载高算力设备,而如果使用一套分布式RTOS,将计算加速器、MCU控制核的资源进行统一管理,就可以提高水下机器人的整体算力,传统RTOS没有一个组件可用于MCU间互联实现实时的并行运算
其实RT-Thread和FreeRTOS可以满足上面大部分需求,但是它们难以平衡小内核+大外设库,再加上我想写一个RTOS,所以本项目就出现了
系统分为四层,六个主要组件:
-
硬件兼容层:用于移植到不同的硬件项目,只要修改少数关键API即可实现同型号内核间移植。只需要将所有项目源码放在工程根目录中,并在应用程序引用所需组件的头文件,即可完成系统移植和应用
组件:Port
-
内核层:包括了一个极其微型的抢占式操作系统内核,能够实现时间片轮转调度、信号量、互斥量、消息队列功能,其中大量借鉴(照抄)了国产RTOS RT-Thread的代码,并部分加入(照抄)FreeRTOS、uCOS-ii和LiteOS的设计理念,该层的主要目的是为上层应用提供一个既能直接调用指针完成数据快速存取,又能通过线程调度和硬件抽象层完成硬件外设控制、控制算法快速移植的中间平台,这也是本操作系统的核心思想:接近裸机但不是裸机的操作系统
组件:Sys Thread
-
硬件抽象层:使用Port组件中定义的API对底层寄存器进行控制,自带了许多常用的控制算法和一些特殊算法,可以实现对PWM设备的高效率调用(直接控制寄存器)、根据经验公式控制任意数量的水下推进器(自带一个六轴/八轴控制算法)、灵活的机械臂控制(基于查找表的空间映射)和可以快速调参(如果有可能会实现自整定)的PID控制、高实时性定向定深算法
组件:BasicCtrl Algorithm
-
传感器控制层:通过指针直接控制底层传感器数据采集,可以使用硬件抽象层的统一接口直接控制底层传感器数据(通过指针直接操作缓存区),同时预留了硬件加速和AUV的编程接口,用于后续配合其他先进机型
组件:Sensor
-
可以任意裁剪的“最小操作系统” 可以根据需要的模块,从底层开始分模块裁剪。
Port组件是一套完整的“CPU驱动”,可以提供中断管理、线程切换(PendSV)管理、硬件加速器驱动等API;Thread组件需要事先启用Port组件,提供了简单的线程类和基于链表的线程调度器;Sys组件需要和Thread组件同时工作,但是也可以选择使用其他RTOS搭配这个组件,提供了一套简单的信号量、互斥量、消息队列、外设驱动模型系统组件,其中外设驱动模型是可选的。BasicCtrl组件基于外设驱动模型(Sys组件)工作,但是可以将其拆开进而部署到任意水下机器人架构,可以基于指针提供水下机器人常用的机械臂、推进器(PWM)、串口数据传输、ROS协同工作等功能;Algorithm组件实现了仅依赖于Port层工作,可以为它单独实现基于FPGA或其他DSA的硬件加速API,这个组件为系统提供了常用的控制算法;Sensor组件基于Sys和BasicCtrl模块工作,也可以独立使用硬件厂商提供的寄存器库、HAL库工作,该组件可实现相对高效的通用硬件模型
-
最接近裸机的RTOS Nitori的核心组件包括Thread、BasicCtrl、Algorithm、Sensor,它们均可作为OurEDA水下机器人控制库组件单独应用在各种ROV项目中。只使用Thread组件时,系统的资源占用极小,由于只有线程调度功能,因此除了支持多任务外几乎能够发挥硬件的全部性能
-
简单的实现,搬运高效代码 主要是因为作者比较菜,所以底层使用了很简单的汇编,同时借鉴(照抄)了各大知名RTOS(FreeRTOS、RT-Thread、Harmony LiteOS等)的内核实现,形成一个缝合怪体系,效率还是比较高的(大概)
-
C面向对象编程
基于C面向对象的设计理念,每层都由C对象构成,可控性良好
本项目的前身,一个可快速部署于水下机器人下位机的控制库,并可针对所需传感器、舵机、推进器和上下传数据流格式进行裁剪
基于HAL硬件抽象层和STM32HAL库构建,可通过移植底层函数快速适配各种主控IC
分为以下几个版本:
- V1.0:最初版本,使用指针和库内部的全局变量实现。适合于快速移植,但代码较难看懂
- V2.0:使用结构体封装和位运算实现。封装较完善,但效率相对较低,但较容易理解,此外该版本存在一些bug有待修复
- V3.0:V2.0的衍生版本,修复了可能存在的控制指令下传不正确的bug,改正了大端存储数据和小端存储数据
- V4.0:最新迭代。增强代码鲁棒性,加入声呐传感器驱动,优化代码结构,但是传感器读取与延迟部分还存在问题
- V5.0:目前正在筹划的版本。使用c面向对象重写,可基于FreeRTOS/RT-Thread快速部署到任何主控的机器人上,支持统一的传感器数据传输接口和PWM驱动,允许最多三个从设备进行级联,支持驱动ASIC/FPGA。效率降低
- V6.0:画大饼版本。使用c面向对象重写,底层基于指针和寄存器,紧密耦合基于ROV优化的FPGA软核,自带任务调度器、互斥量、邮箱,通过硬件直接解析传感器数据、控制PWM,自带PID、卡尔曼滤波、奇偶校验算法,效率极高,一个经过特殊优化的RTOS
其中V5.0、V6.0版本被直接分割为 Nitori-OS
的V1.0版本进行开发
- 对stm32(Cortex-M系列内核)-HAL库的底层软硬件支持
- 向上为ROS(机器人操作系统)提供访问接口,根据URPC(全国水下机器人大赛)给出ROS数据外传接口作为标准
- 识别并分配下传的ROS_DOMAIN_ID作为从机识别符(ID)
- 根据上位机ROS提供的Topic(话题)进行操作命令解析
- 可支持以上位机ROS为核心的多机互联和以stm32级联为核心的数据上传
- 支持经过裁剪的ROS
对RISC-V(RV32IM指令集)的底层软硬件支持- 基于systick实现的系统时钟
- 多任务时间片轮转调度
- 信号量、互斥量、消息队列
- PWM设备驱动
- 使用十六进制/字符串数据解析的串口传感器驱动框架
- 一套完整的九轴、温湿度大气压传感器、水深水温传感器、声呐深度传感器解析类
- 推进器、云台、摄像头、网络接口抽象类
- 支持多mcu级联数据传输
- 快速定义数据上传协议
- FPGA自定义寄存器控制API
- 对硬件运算和自主控制的API支持
- 可基于qemu环境或实际stm32f407部署
- 自带一套基于[arm-none-eabi-gcc/riscv32-unknown-linux-gnu-gcc]-[make]-[CMake]-[KernelConfig]的工具链
- Port组件的Cortex-M4移植(暂不支持HardwareAccelerate)
- 基于Cortex-M4的内核TestBench与线程调度示例代码
- Thread组件中任务调度器基本功能(暂不支持内核对象类)
- Sys组件中信号量功能(暂不支持互斥量、消息队列、外设驱动模型)
- 暂不支持Sensor组件和BasicCtrl组件
- Algorithm组件中除硬件加速外所有功能
整理架构图、工具链与部署方案搭建两套测试环境- 移植到Cortex-M4并运行Thread组件
- 实现Sys组件中的信号量功能