目录
概述
UniProton是鸿蒙操作系统面向工业控制领域的轻量级实时操作系统(RTOS),专为资源受限的嵌入式设备设计。作为鸿蒙生态的重要组成部分,UniProton提供了高效的实时任务调度、内存管理和IPC机制,满足工业控制场景对实时性和可靠性的严格要求。
基本信息
- 版本: 3.1.0
- 许可证: BSD 3-clause
- 资源占用: ROM约300KB,RAM约100KB
- 支持架构: ARMv7-M和ARMv8架构
- 适用系统: mini系统类型
系统架构
UniProton采用分层架构设计,从下到上分为硬件抽象层、内核层和系统服务层。
分层架构
┌─────────────────────────────────────────┐
│ 应用层 │
├─────────────────────────────────────────┤
│ 系统服务层 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 文件系统 │ │ 网络协议 │ │ 设备管理 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
├─────────────────────────────────────────┤
│ 内核层 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 任务管理 │ │ 内存管理 │ │ IPC机制 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 定时器 │ │ 中断管理 │ │ 错误处理 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
├─────────────────────────────────────────┤
│ 硬件抽象层 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ CPU抽象 │ │ 中断抽象 │ │ 内存抽象 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────┘
模块介绍
UniProton内核由五大子系统构成,各子系统的职责如下:
1. Mem子系统
- 功能: 实现内存分区的创建,内存块的申请和释放等功能
- 算法: 采用FSC(First Fit with Segregation and Coalescing)内存管理算法
- 特点: 将内存划分为多个大小不同的分区,每个分区采用链表管理空闲内存块
2. Arch子系统
- 功能: 实现和芯片强相关的硬件特性功能,如硬中断、异常接管等
- 支持架构: ARMv7-M和ARMv8架构
- 抽象层: 提供CPU抽象、中断抽象和内存抽象
3. Kernel子系统
- 功能: 实现任务、软中断、TICK中断、软件定时器等功能
- 调度机制: 支持基于优先级的抢占式调度,同优先级任务采用时间片轮转算法
- 任务状态: 支持就绪态、运行态、阻塞态和挂起态四种状态
4. IPC子系统
- 功能: 实现事件、队列、信号量等进程间通信机制
- 通信方式: 提供信号量、事件、队列和互斥锁等多种IPC机制
- 应用场景: 满足不同应用场景下的进程间通信需求
5. OM子系统
- 功能: 实现cpup、hook等调测功能
- 监控能力: 提供CPU占用率统计、错误处理和钩子函数功能
- 运维支持: 帮助开发者进行系统监控和问题诊断
编译方法
环境要求
- 操作系统: SUSE Linux Enterprise Server
- Python: 3.4+
- CMake: 3.20.5
- 编译器 :
- ARMv7-M: GNU Arm Embedded Toolchain 10-2020-q4-major
- ARMv8: gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf
编译步骤
方法一:Linux环境编译
-
创建编译工具目录
bashmkdir -p /opt/buildtools && chmod -R 755 /opt/buildtools -
安装编译器
bash# ARMv7-M编译器 tar -xvf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 -C /opt/buildtools # ARMv8编译器 tar -xvf gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz -C /opt/buildtools -
安装CMake
bashtar -xvf cmake-3.20.5-Linux-x86_64.tar.gz -C /opt/buildtools -
下载代码
bashgit clone https://gitee.com/openeuler/UniProton.git -
下载依赖库
- 按照platform/README.md指导下载libboundscheck库
-
执行编译
bashcd UniProton python build.py m4 # 编译ARMv7-M版本 # 或 python build.py armv8 # 编译ARMv8版本
方法二:Docker环境编译
-
拉取镜像
bashdocker pull swr.cn-north-4.myhuaweicloud.com/openeuler-embedded/uniproton:v002 -
创建并进入容器
bashdocker run -it -v $(pwd):/home/uniproton swr.cn-north-4.myhuaweicloud.com/openeuler-embedded/uniproton:v002 -
下载代码
bashgit clone https://gitee.com/openeuler/UniProton.git -
下载依赖库
- 按照platform/README.md指导下载libboundscheck库
-
执行编译
bashcd UniProton python build.py m4
编译结果
- 生成的静态库文件存放在
output/UniProton/lib/cortex_m4目录下 - 生成的libboundscheck库文件存放在
output/libboundscheck/lib/cortex_m4目录下
使用方法
基本开发流程
-
准备开发环境
- 安装交叉编译工具链
- 配置CMake构建环境
- 准备目标硬件平台
-
创建应用项目
- 参考demos/helloworld目录结构
- 创建apps、bsp、build、config、include、libs等目录
-
配置系统参数
- 修改prt_config.c和prt_config.h文件
- 根据需求裁剪功能模块
-
编写应用代码
- 实现PRT_AppInit函数,创建任务
- 实现PRT_HardDrvInit函数,初始化硬件
- 实现PRT_HardBootInit函数,进行系统初始化
-
编译和链接
- 编译应用代码
- 链接UniProton静态库
- 生成可执行文件
-
烧录和调试
- 将可执行文件烧录到目标硬件
- 连接调试器进行调试
API接口使用
UniProton提供了丰富的API接口,主要包括:
-
任务管理接口
- PRT_TaskCreate: 创建任务
- PRT_TaskResume: 恢复任务
- PRT_TaskDelay: 任务延时
- PRT_TaskDelete: 删除任务
-
内存管理接口
- PRT_MemAlloc: 分配内存
- PRT_MemFree: 释放内存
-
IPC接口
- PRT_SemCreate: 创建信号量
- PRT_SemPend: 等待信号量
- PRT_SemPost: 释放信号量
- PRT_EventCreate: 创建事件
- PRT_EventRead: 读取事件
- PRT_EventWrite: 写入事件
使用场景
UniProton广泛应用于工业控制、物联网设备、智能家居、汽车电子等领域,特别适合对实时性要求高的场景:
-
工业自动化控制系统
- PLC控制器
- 运动控制系统
- 工业机器人控制
-
物联网设备
- 智能传感器网络
- 边缘计算节点
- 工业网关
-
智能家居
- 智能家电控制
- 安防监控系统
- 环境监测设备
-
汽车电子
- 车身控制模块
- 发动机控制单元
- 高级驾驶辅助系统
-
实时数据采集系统
- 数据采集终端
- 信号处理设备
- 仪器仪表
设计架构
代码目录结构
| 一级目录 | 二级目录 | 三级目录 | 说明 |
|---|---|---|---|
| build | uniproton_ci_lib | 编译框架的公共脚本 | |
| uniproton_config | config_m4 | cortex_m4芯片的功能宏配置文件 | |
| cmake | common | build_auxiliary_script | 转换Kconfig文件为buildef.h脚本 |
| functions | cmake的公共功能函数 | ||
| tool_chain | 编译器和编译选项配置文件 | ||
| demos | helloworld | apps | 示例程序的main函数文件以及业务代码 |
| bsp | 板级驱动适配代码 | ||
| build | demo构建及链接脚本 | ||
| config | 用户配置文件,功能宏定制头文件 | ||
| include | src/include/uapi及posix目录下头文件拷贝目录 | ||
| libs | 源码编译静态库文件存放目录 | ||
| Hi3093 | Hi3093芯片示例 | ||
| RASPI4 | 树莓派4B示例 | ||
| doc | 项目配置、规范、协议等文档 | ||
| design | UniProton系统架构和特性说明 | ||
| platform | libboundscheck使用说明 | ||
| libboundscheck | libboundscheck预留目录,用户将下载的源码放在此目录下 | ||
| src | arch | cpu | cpu对应架构的功能适配代码 |
| include | cpu对应架构的头文件 | ||
| config | 用户main函数入口 | ||
| config | 用户配置功能宏开关 | ||
| core | ipc | 事件、队列、信号量等功能 | |
| kernel | 任务、中断、异常、软件定时器等功能 | ||
| fs | littlefs | littlefs适配层代码,不包含完整littlefs代码 | |
| vfs | 文件系统vfs层接口代码 | ||
| include | uapi | 对外头文件 | |
| posix | posix接口头文件 | ||
| mem | 内存管理基本功能 | ||
| fsc | 内存管理FSC算法代码 | ||
| include | 内存管理头文件 | ||
| net | lwip-2.1 | lwip适配层代码,不包含完整lwip代码 | |
| om | cpup | cpu占用率统计功能 | |
| err | 错误处理功能 | ||
| hook | 钩子函数功能 | ||
| include | 系统管理头文件 | ||
| osal | posix | posix功能实现源码 | |
| security | rnd | 随机化功能 | |
| utility | lib | 公共库函数 |
核心设计理念
-
模块化设计
- 各子系统独立设计,降低耦合度
- 支持按需裁剪,减小系统体积
- 清晰的接口定义,便于扩展和维护
-
实时性保证
- 抢占式任务调度,确保高优先级任务及时执行
- 中断处理机制,快速响应外部事件
- 精确的定时器管理,满足时间敏感型应用
-
资源高效利用
- 轻量级内核,最小资源占用
- 高效的内存管理算法,减少内存碎片
- 优化的数据结构,提高系统性能
-
可靠性设计
- 完善的错误处理机制
- 内存保护机制,防止非法访问
- 栈溢出检测,提高系统稳定性
示例程序
Hello World示例
以下是一个简单的Hello World示例程序,展示如何使用UniProton创建任务并输出信息:
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "securec.h"
#include "rtt_viewer.h"
#include "prt_config.h"
#include "prt_config_internal.h"
#include "prt_clk.h"
#include "test.h"
void helloworld_task(U32 uwParam1, U32 uParam2, U32 uwParam3, U32 uwParam4)
{
printf("hello world!\n");
while (1) {
PRT_TaskDelay(10);
}
return;
}
U32 PRT_AppInit(void)
{
U32 ret;
TskHandle taskPid;
struct TskInitParam stInitParam = {helloworld_task, 10, 0, {0}, 0x500, "TaskA", 0};
ret = PRT_TaskCreate(&taskPid, &stInitParam);
if (ret) {
return ret;
}
ret = PRT_TaskResume(taskPid);
if (ret) {
return ret;
}
return OS_OK;
}
U32 PRT_HardDrvInit(void)
{
RttViewerInit();
RttViewerModeSet(0, RTT_VIEWER_MODE_BLOCK_IF_FIFO_FULL);
return OS_OK;
}
U32 g_testRandStackProtect;
void OsRandomSeedInit(void)
{
#if defined(OS_OPTION_RND)
U32 ret;
U32 seed;
seed = PRT_ClkGetCycleCount64();
g_testRandStackProtect = rand_r(&seed);
ret = PRT_SysSetRndNum(OS_SYS_RND_STACK_PROTECT,g_testRandStackProtect);
#endif
}
void OsGlobalDataInit(void)
{
}
void PRT_HardBootInit(void)
{
OsGlobalDataInit();
OsRandomSeedInit();
}
U32 PRT_Printf(const char *format, ...)
{
va_list vaList;
char buff[0x200] = { 0 };
S32 count;
U32 ret;
va_start(vaList, format);
count = vsprintf_s(buff, 0x200, format, vaList);
va_end(vaList);
if (count == -1) {
return OS_ERROR;
}
RttViewerWrite(0, buff, count);
return count;
}
S32 main(void)
{
return OsConfigStart();
}
编译和运行
- 将上述代码保存为main.c文件,放在demos/helloworld/apps目录下
- 按照编译方法中的步骤编译项目
- 将生成的可执行文件烧录到目标硬件
- 连接调试器,可以看到输出"hello world!"
总结
UniProton作为鸿蒙操作系统面向工业控制领域的轻量级实时操作系统,具有实时性强、可靠性高、资源占用少、模块化程度高等特点,广泛应用于工业控制、物联网设备、智能家居、汽车电子等领域。通过本文档的介绍,开发者可以了解UniProton的系统架构、模块功能、编译方法、使用方法和设计理念,为基于UniProton的应用开发提供指导。