目录
项目资源库:https://github.com/Gabrielle-OyO/AliOS-Things-Term
源码资源库:https://github.com/Gabrielle-OyO/AliOS-Things-rel_3.1.0/tree/main/AliOS
课程目标
学习完本课程后,你将能够:
1. 了解AliOS Things操作系统的内核编程
2. 了解AliOS Things常用组件的使用
课程目录
1. AliOS Things源代码编译
1.1 使用命令行
1.2 使用VSCODE
2. AliOS Things源代码
3. 智能硬件
AliOS Things操作系统的特点
• 内核:rhino
•
公开源代码(大部分)
•
可移植性(Portable)
• 大部分源码用C编写
• 微处理器硬件相关的那部分用汇编语言写的,尽可能少
• 可以在很多微处理器上运行
•
可固化(ROMable)
•
可裁剪(Scalable)
• 代码以组件形式,通过文件中的#define进行裁剪
• ESP32内核功能裁剪:AliOS-Things-rel_3.1.0\platform\board\board_legacy\esp32devkitc\k_config.h(覆盖默认配置)
• 内核的默认配置:AliOS-Things-rel_3.1.0\core\rhino\include\k_default_config.h
•
调度方式
• 基于优先级的调度
• 基于优先级的时间片调度(默认)
•
系统服务
• 信号量、互斥信号量(处理优先级反转问题)、消息队列、事件、内存管理、软件定时器等
嵌入式系统代码结构(不带操作系统)
带中断的轮转结构
•
中断程序处理硬件特别紧急
的需求,设置标志
•
主循环轮询这些标志,根据
这些需求进行后续的处理
•
前后台系统:前台—中断, 后台—循环
BOOL fDeviceA=FALSE;
BOOL fDeviceB=FALSE;
…
BOOL fDeviceZ=FALSE;
void interrupt vHandleDeviceA(void)
{
fDeviceA=TRUE;
}
void interrupt vHandleDeviceB(void)
{
fDeviceB=TRUE;
}…
void interrupt vHandleDeviceB(void)
{
fDeviceZ=TRUE;
}
嵌入式系统代码结构(带操作系统)
•
代码由一系列任务代码组成
•
将系统功能分解成一系列的任务
•
任务轮流运行互相配合,实现系统功能
•
任务就是一个进程,解决特定的问题,具有特定的数据结构
•
任务由操作系统内核,根据任务优先级及时间片轮流调度运行
•
任务分类
•
系统任务—系统自带,提供某些服务,如空闲任务
•
用户任务—解决用户的实际问题实际应用问题
•
Alios程序结构
•
用户负责创建任务
•
不直接调用任务代码,任务由操作系统调度运行

任务的基本概念
•
任务代码的结构
• 形式:
C语言函数
•
参数
• 指向void的指针,可以指向任何内容
•
代码结构
• 无限循环,永不返回
• 包括放弃CPU使用权的代码
•
代码特点
• 各任务互相独立,运行时独占处理器
• 任务
局部变量
放在栈中,为任务私有数据
• 任务间交换私有数据通过操作系统的服务
•
全局变量
需要互斥访问


AliOS中的任务
•
两种调度策略
• 基于优先级的抢占式调度
—
任务间优先级不能相同
• 运行系统中优先级最高的、就绪的任务
• 基于优先级的抢占
+
基于时间片的轮转调度(默认方式)
—
任务间优先级可以相同
• 运行系统中优先级最高的、就绪的任务
• 假如这样的任务有多个,互相间根据时间片进行轮转调度,时间片用完放到当前优先级,调度队列的最后
• 默认时间片为50 ticks
(
RHINO_CONFIG_TIME_SLICE_DEFAULT
),系统时钟频率为
100
(
RHINO_CONFIG_TICKS_PER_SECOND
)
•
优先级分配
—
可配置修改
• 默认为
0
~
62
,
值越大表示优先级越低
,
• 其中空闲任务的优先级是
61
,无任务可运行时,执行空闲任务,内有钩子函数,用户可以编写自己的代码
• 用户任务优先级范围1-60,0、61、62保留
•
任务堆栈
• 根据任务局部变量的多少,分配堆栈的大小
• 堆栈溢出是造成系统崩溃的主要原因
• 系统具有栈溢出检测功能(RHINO_CONFIG_TASK_STACK_OVF_CHECK),开启后一旦溢出产生异常
•
任务的状态
• 任务状态分为就绪状态、挂起状态、休眠状态、阻塞状态、运行状态和删除状态
• 某些状态可以互相组合
• 任务必定处理以上状态中

内核函数说明
•
内核函数分为两个系列
•
krhino_xx系列
• rhino原生的API函数
• rhino升级后可能改变
• 功能丰富,参数多,使用复杂
•
aos_xx系列—
推荐使用
• alios封装后的内核操作函数
• 内部调用krhino_xx系列的函数实现
• 对函数的调用进行了部分简化,功能受一定限制
• 相对稳定,受内核升级影响较小

•
让出CPU资源
• 仅在时间片调度时有效
• 将当前运行任务放至同优先级就 绪任务队列的最后
• 任务仍为就绪,并不挂起任务

#include <stdio.h>
#include <aos/kernel.h>
void func1(void * arg)
{
int tmp=0;
while(1)
{
printf("task1 print %d\r\n",tmp);
tmp++;
aos_msleep(1000);
} }
void func2(void * arg)
{
int tmp=0;
while(1)
{
printf("task2 print %d\r\n",tmp);
tmp++;
aos_msleep(1000);
}
}
int application_start(int argc, char *argv[])
{
int tmp=0;
printf("nano entry here!\r\n");
aos_task_new("task1", func1,0, 8192);
aos_task_new("task2", func2,0, 8192);
while(1) {
printf("maintask print %d\r\n",tmp);
tmp++;
aos_msleep(1000);
};
}
时钟节拍与软件定时器
•
时钟节拍( Clock Tick )
• 操作系统通过硬件定时器,产生周期性的中断,是所有操作系统必须的
• 作用:(1)依靠该中断来调度任务(2)计算延迟时间
• 时钟节拍的频率:根据操作系统不同而不同,AliOS默认周期为10ms,频率通过
RHINO_CONFIG_TICKS_PER_SECOND定义
• 时钟节拍率越快,任务切换越及时,实时性更好
• 时钟节拍率越快,延时分辨率越高
• 时钟节拍率越快,系统的额外开销就越大
•
使用最小时钟节拍进行延时,为了确保延时时间,设置的延时数要+1
• 例如时钟节拍每20ms发生一次,现在要至少延迟20ms,假设Delay(x)是延迟时针节拍数函数,则要设置为Delay(2)
•
操作系统中软件延时的波动原理

•
软件定时器
• 定时器在嵌入式开发中广泛应用
• 系统利用时钟节拍和高优先级任务,提供了软件定时器服务
• 软件定时器功能:
指定延时特定时间后,一次或周期调用某个函数(回调函数)。延时时间以时钟节拍为单
位,回调函数由用户设定