[FFH]OpenHarmony南向研究-系统移植和驱动开发(1) 原创 精华
系统移植和驱动开发(1)-入门FAQ
OpenHarmony系统的概述 --基于小熊派nano,IMX6ULL
OpenHarmony内核的架构
windows | RTOS |
---|---|
BIOS | bootloader(uboot) |
windows | RTOS内核(内核加驱动) |
C盘 | 根文件系统 |
APP | APP |
两部分: 最小系统移植以及使用,驱动开发
操作系统入门+重点整合
实时操作系统和非实时操作系统,OpenHarmony简介QA
参见Donal Gillies在Realtime Computing FAQ中提出定义:实时系统指系统的计算正确性不仅取决于计算的逻辑正确性,还取决于产生结果的时间。如果未满足系统的时间约束,则认为系统失效。
POSIX 标准 1003.1 将操作系统的“实时”定义为:
“操作系统中的实时性:操作系统的能力
在有限的响应时间内提供所需的服务水平”
1. RTOS(实时操作系统)必须是多线程的,并且
可抢占的。
2.线程优先级的概念必须存在,因为目前没有
截止日期驱动的操作系统。
3. 操作系统必须支持可预测的线程同步机制
4. 必须存在优先继承制度
5.操作系统行为应该是已知的
Q: windows 是实时操作系统还是非实时操作系统
A: windows不是实时操作系统,
一个实时操作系统面对变化的负载(从最小到最坏的情况)时必须确定性地保证满足时间要求。请注意,必须要满足**确定性,而不是要求速度足够快!例如,如果使用足够强大的CPU,Windows在CPU空闲时可以提供非常短的典型中断响应。但是,当某些后台任务正在运行时,有时候响应会变得非常漫长,以至于某一个简单的读取文件的任务会长时间无响应,甚至直接挂死。这是一个基本的问题:并不是Windows不够快或效率不够高,而是因为它不能提供确定性,**所以,Windows不是一个实时操作系统。
Q:OpenHarmony是实时操作系统还是非实时操作系统
A;关于这个问题要从底层的内核部分谈起,
OpenHarmony的内核架构
OpenHarmony 不能算是一个完整的操作系统,他是HarmonyOS的开源部分,取消了一些商业认证和商用接口。
OpenHarmony分为三种系统类型:轻量系统,小型系统和标准系统 ,轻量系统专注于提供低成本有效硬件资源的MCU类处理器,而小型系统和标准系统则提供了更多北向的功能,包括视频处理,UI交互界面,完整的图形能力等
OpenHarmony除了支持linux kernel系统外还同时支持 litos自研轻量级内核,这种内核提供的功能是更大宽容度的多端适配。
在底层除了内核外还有依托于内核启动的HDF驱动,这部分驱动开启了OpenHarmony的外设连接,包括总线常用信号量输出,接收等等的基础硬件功能。
在通常的操作系统分类中,根据操作系统的功能及作业处理方式可以分为:批处理操作系统、分时操作系统、实时操作系统和网络操作系统,嵌入式操作系统。
批处理操作系统出现于20世纪的60年代,能最大化的提高资源的利用率和系统的吞吐量。其处理方式是系统管理员将用户的作业组合成一批作业,输入到计算机中形成一个连续的作业流,系统自动依次处理每个作业,再由管量员将作业结果交给对应的用户。
分时操作系统可以实现多个用户共用一台主机,在一定程度上节约了资源。借助于通信线路将多个终端连接起来,多个用户轮流的占用主机上的一个时间片处理作业。用户通过自己的终端向主机发送作业请求,系统在相应的时间片内响应请求并反馈响应结果,用户再根据反馈信息提出下一步请求,这样重复会话过程,直至完成作业。因为计算机处理的速度快,给用户的感觉是在独占计算机。
实时操作系统(RealTimeOperatingSystem,RTOS)是指使计算机能及时响应外部事件的请求在规定的严格时间内完成对该事件的处理,并控制所有实时设备和实时任务协调一致地工作的操作系统。实时操作系统要追求的目标是:对外部请求在严格时间范围内做出反应,有高可靠性和完整性。
嵌入式操作系统(EmbeddedOperating System)是运行在嵌入式系统环境中,对整个嵌入式系统以及它所操作、控制的各种部件装置等资源进行统一协调、调度、指挥和控制的系统软件。程,并使整个系统能高效地运行。
LInux算是典型的TSOS,在以之为内核的标准版OpenHarmony系统中可以视为分时操作系统,以liteos为内核的实时轻量级操作系统是一种RTOS,可以完善执行快速响应。
值得一提的是普通的RTOS一般无法调度MMU,内核空间以及APP隔离,也不支持POSIX接口,大量的开源软件无法使用,而liteos尝试解决了这个问题,liteos-a和liteos-m分别对不同的情形进行了支持,这也许是未来操作系统的发展方向,从底层上更快速更多元。
Q:liteos-a 和liteos-m的区别是什么?
A:Liteos-a 为物联网而生,支持 MMU,支持内核/APP 空间隔离、支持各个 APP 空间隔离,系统更健壮; 支持 POSIX 接口,大量开源软件可以在 Liteos-a 上直接使用;启动快,省电。 Liteos-a 是一个轻量级的内核,设计精巧。它要成功,就必须持更多芯片、更多外设。除了 Liteos-a,还有一个 Liteos-m,后者运行在没有 MMU 的芯片上,也就是运行在 MCU 上。
综述
在此次的分析和学习中重点基于liteos的轻量系统和liteos-m两种嵌入式方向,对南向相对友好的两款入手开始学习,使用liteos-m在小熊派nano板上进行操作系统相关的基础知识的学习,使用liteos-a进行系统移植的学习。
cmsis-RTOS2+litos-m
中间层采用CMSIS-RTOS2作为中间层,以API的方式封装了liteos-m的代码,上层可以进行应用开发和中间件开发
https://arm-software.github.io/CMSIS_5/RTOS2/html/index.html
cmsis - RTOS2的接口API介绍和reference
任务管理和调度
任务是操作系统中执行和竞争系统资源的最小单元,任务可以使用CPU,内存等等资源,并且独立于其他的任务进行运行。
LiteOS中的任务是抢占式调度机制,高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或
结束后才能得到调度,同时支持时间片轮转调度方式。
liteos的任务默认有32个优先级,最高为0,最低为31,一般的系统任务运行在7优先级,普通任务调度应该在14优先级之后。
抢占式调度和时间片轮转调度
- 抢占式调度
每个任务都有不同的优先级,任务会一直运行直到被高优先级任务抢占或者遇到阻塞式的 API 函数,
-
时间片调度
每个任务都有相同的优先级,任务会运行固定的时间片个数或者遇到阻塞式的 API 函数
,才会执行同优先级任务之间的任务切换。
操作系统中任务的状态分类
就绪,运行,阻塞,退出态
本次基本点灯过程中用到的API接口如下
osThreadNew(osThreadFunc_t func,void * argument,const osThreadAttr_t * attr)
//创建
osThreadTerminate(osThreadId_t thread_id);
//删除
osThreadSuspend(osThreadId_t thread_id)
//挂起
osThreadResume (osThreadId_t thread_id)
API接口的解释和具体信息
函数osThreadNew通过将线程添加到活动线程列表并将其设置为就绪状态来启动线程函数。线程函数的参数使用参数指针*argument传递。当创建的thread函数的优先级高于当前运行的线程时,创建的thread函数立即启动并成为新的运行线程。线程属性是用参数指针attr定义的。属性包括线程优先级、堆栈大小或内存分配的设置。可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,但不能在内核初始化 (调用 osKernelInitialize)之前调用该函数。
[in] func thread function.
[in] argument pointer that is passed to the thread function as start argument.
[in] attr thread attributes; NULL: default values.
例程和编译
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
//1
void thread1(void)
{
int sum = 0;
while (1)
{
printf("T1%d\r\n", sum++);
sleep(1);
}
}
//2
void thread2(void)
{
int sum = 0;
while (1)
{
printf("T2%d\r\n", sum++);
sleep(5);
}
}
//establish new mission
static void Thread_example(void)
{
//os句柄名称
osThreadAttr_t attr;
attr.name = "thread1";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 1024 * 4;
attr.priority = 25;
if (osThreadNew((osThreadFunc_t)thread1, NULL, &attr) == NULL)
{
printf("Falied to create thread1!\n");
}
attr.name = "thread2";
if (osThreadNew((osThreadFunc_t)thread2, NULL, &attr) == NULL)
{
printf("Falied to create thread2!\n");
}
}
//创建gn编译对象
APP_FEATURE_INIT(Thread_tset);
static_library("Thread_tset") {
sources = [
"Thread_tset.c"
]
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
]
}
import("//build/lite/config/component/lite_component.gni")
lite_component("app") {
features = ["kernal_thread:thread_test",]
}