当前位置:   article > 正文

LiteOS学习笔记-1LiteOS内核_怎么阅读liteos

怎么阅读liteos


此文参考华为云官方社区多篇文章,如有侵权,请联系删除。

Lite OS特点

轻量化,大小为10KB;面向IoT;支持功能静态裁剪;使用make文件可支持动态加载、分散加载。

Lite OS内核

与正常的操作系统内核一样,包括任务管理、内存管理、时间管理、通信机制、中断管理、队列管理、事件管理、定时器等操作系统基础组件,可以单独运行。
在这里插入图片描述

LiteOS SDK

LiteOS SDK 是 Huawei LiteOS 软件开发工具包(Software Development Kit),包括端云互通组件,FOTA,JS引擎、传感器框架等内容。
在这里插入图片描述

Huawei IoT Link SDK

Huawei IoT Link SDK(下文统一简称SDK)是部署在具备广域网能力、对功耗/存储/计算资源有苛刻限制的终端设备上的轻量级互联互通中间件.
在这里插入图片描述

1.SDk之OS选择

Huawei IoT Link SDK 的底层拥有OS适配层,可以适配Linux、MacOS、LiteOS,以及其它第三方OS(需要自行适配),笔者适配的OS是LiteOS。

2.SDk之代码位置

为了用户开发方便,SDK的代码不会出现在 IoT Studio 中,IoT Studio中只有用户的目标工程代码(target),但是,SDK的代码会在编译的时候被编译进工程。
SDK代码位置:C:\Users\XXXXX\.iotlink

3.SDk之编译设置

SDK使用 arm-none-eabi-gcc 工具链进行编译,使用 make 工具构建编译,使用*.mk 文件留给用户配置一些 makefile 中的选项。

  1. 设置编译器和make工具路径
    一般情况下为默认即可。
  2. 设置工程makefile
    整个工程的 makefile 在 GCC 目录下,在编译之前,要确保在IoT SDK设置中指定该makefile。

LiteOS 内核之任务管理

LiteOS 内核提供任务的创建、删除、延迟、挂起、恢复等功能,以及锁定和解锁任务调度,支持任务按优先级高低的抢占调度及同优先级时间片轮转调度。

一、任务

在 LiteOS 中,一个任务就是一个线程,多个任务按照优先级进行抢占式调度,达到多个任务“同时”运行的目的。
每个任务都有多种运行状态。当系统初始化完成并启动调度器后,系统中所有创建的任务就由内核进行调度,在不同运行状态之间切换,同时在系统中竞争一定的资源。

1.任务状态

任务的状态有以下四种:

  • 就绪(Ready):该任务在就绪列表中,只等待 CPU;
  • 运行(Running):该任务正在执行;
  • 阻塞(Blocked):该任务不在就绪列表中。包含任务被挂起、任务被延时、任务正在等待信号量、读写队列或者等待读写事件等;
  • 退出态(Dead):该任务运行结束,等待系统回收资源。
2.任务ID

任务 ID 在任务创建时通过参数返回给用户,作为任务的一个非常重要的标识。
用户可以通过任务ID对指定任务进行任务挂起、任务恢复、查询任务名等操作。

3.任务优先级

优先级表示任务执行的优先顺序。任务的优先级决定了在发生任务切换时即将要执行的任务,在就绪列表中的最高优先级的任务将得到执行。
Huawei LiteOS 的任务一共有 32 个优先级 (0-31),最高优先级为 0,最低优先级为 31。
因为是LiteOS的内核是抢占式调度内核,所以:
高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。

4.多任务运作机制

Liteos由用户实现每个新任务得到调度后将执行的函数,该函数称为任务入口函数
在多任务操作系统的内核中,为了方便对每个任务进行管理,每一个任务都有一个任务控制块(TCB),其中包含了任务上下文栈指针(stack pointer)、任务状态、任务优先级、任务ID、任务名、任务栈大小等信息,TCB 相当于每个任务在内核中的身份证,可以反映出每个任务运行情况。
每个任务相当于一个裸机程序,每个任务之间相互独立,这个“独立”指的是每个任务都有自己的运行环境 —— 栈空间,称为任务栈,栈空间里保存的信息包含局部变量、寄存器、函数参数、函数返回地址等。
用户创建任务时,系统会先申请任务控制块需要的内存空间,申请成功后,系统会将任务栈进行初始化,预置上下文。此外,系统还会将“任务入口函数”地址放在相应位置。这样在任务第一次启动进入运行态时,将会执行“任务入口函数”。

二、任务管理API

LiteOS 任务管理提供的 API 都是以 LOS 开头,但是这些 API 使用起来比较复杂,所以Huawei IoT Link SDK 提供了统一API接口,这些接口底层已经使用 LiteOS 提供的API实现,对用户而言更为简洁,API列表如下:

接口名功能描述
osal_task_create创建任务
osal_task_kill删除任务(非自身)
osal_task_exit任务退出
osal_task_sleep任务休眠

osal的api接口声明在osal.h中,使用相关的接口需要包含该头文件,关于函数的详细参数请参考该头文件的声明。
任务相关的接口定义在osal.c中,基于LiteOS的接口实现在 liteos_imp.c文件中.

2.1.osal_task_create
void* osal_task_create(const char *name,int (*task_entry)(void *args),\
                      void *args,int stack_size,void *stack,int prior)
{
    void *ret = NULL;

    if((NULL != s_os_cb) &&(NULL != s_os_cb->ops) &&(NULL != s_os_cb->ops->task_create))
    {
        ret = s_os_cb->ops->task_create(name, task_entry,args,stack_size,stack,prior);
    }

    return ret;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
2.2.osal_task_kill
int osal_task_kill(void *task)
{
    int ret = -1;

    if((NULL != s_os_cb) &&(NULL != s_os_cb->ops) &&(NULL != s_os_cb->ops->task_kill))
    {
        ret = s_os_cb->ops->task_kill(task);
    }

    return ret;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
2.3.osal_task_exit
void osal_task_exit()
{

    if((NULL != s_os_cb) &&(NULL != s_os_cb->ops) &&(NULL != s_os_cb->ops->task_exit))
    {
        s_os_cb->ops->task_exit();
    }
    return ;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
2.4.osal_task_sleep
void osal_task_sleep(int ms)
{
    if((NULL != s_os_cb) &&(NULL != s_os_cb->ops) &&(NULL != s_os_cb->ops->task_sleep))
    {
        s_os_cb->ops->task_sleep(ms);
    }

    return ;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

LiteOS 内核之信号量

在多任务操作系统中,不同的任务之间需要同步运行,信号量功能可以为用户提供这方面的支持。信号量(Semaphore)是一种实现任务间通信的机制,实现任务之间同步或临界资源的互斥访问。

一、信号量

1.信号量使用方式

信号量可以被任务获取或者申请,不同的信号量通过信号量索引号来唯一确定,每个信号量都有一个计数值和任务队列。
通常一个信号量的计数值用于对应有效的资源数,表示剩下的可被占用的互斥资源数,其值的含义分两种情况:

  • 0:表示没有积累下来的 Post 操作,且有可能有在此信号量上阻塞的任务;
  • 正值:表示有一个或多个 Post 下来的释放操作;

当任务申请(Pend)信号量时,如果申请成功,则信号量的计数值递减,如若申请失败,则挂起在该信号量的等待任务队列上,一旦有任务释放该信号量,则等待任务队列中的任务被唤醒开始执行。

2.信号量使用场景
  • 互斥锁

用作互斥时,信号量创建后记数是满的,在需要使用临界资源时,先申请信号量,使其变空,这样其他任务需要使用临界资源时就会因为无法申请到信号量而阻塞,从而保证了临界资源的安全。

  • 任务间同步

用作同步时,信号量在创建后被置为空,任务1申请信号量而阻塞,任务2在某种条件发生后,释放信号量,于是任务1得以进入 READY 或 RUNNING 态,从而达到了两个任务间的同步。

  • 资源计数

用作资源计数时,信号量的作用是一个特殊的计数器,可以递增或者递减,但是值永远不能为负值,典型的应用场景是生产者与消费者的场景。

  • 中断与任务的同步

用作中断与任务的同步时,可以在中断未触发时将信号量的值置为0,从而堵塞断服务处理任务,一旦中断被触发,则唤醒堵塞的中断服务处理任务进行中断处理。

3.信号量申请模式

信号量有三种申请模式:非阻塞模式、永久阻塞模式、定时阻塞模式,用 timeout 参数的值选择。

  • 非阻塞模式(0):

任务需要申请信号量,若当前信号量的任务数没有到信号量设定的上限,则申请成功。否则,立即返回申请失败

  • 永久阻塞模式(cn_osal_timeout_forever或0xFFFFFFFF):

任务需要申请信号量,若当前信号量的任务数没有到信号量设定的上限,则申请成功。否则,该任务进入阻塞态,系统切换到就绪任务中优先级最高者继续执行。任务进入阻塞态后,直到有其他任务释放该信号量,阻塞任务才会重新得以执行

  • 定时阻塞模式(任意定时值,32bit):

任务需要申请信号量,若当前信号量的任务数没有到信号量设定的上限,则申请成功。否则,该任务进入阻塞态,系统切换到就绪任务中优先级最高者继续执行。任务进入阻塞态后,指定时间超时前有其他任务释放该信号量,或者用户指定时间超时后,阻塞任务才会重新得以执行

由于中断不能被阻塞,因此在申请信号量时,阻塞模式不能在中断中使用。

二、信号量API

API相关文件与任务管理相同。API列表如下:

接口名功能描述
osal_semp_create信号量创建
osal_semp_del信号量删除
osal_semp_pend信号量申请
osal_semp_post信号量释放
2.1.osal_semp_create
bool_t  osal_semp_create(osal_semp_t *semp,int limit,int initvalue)
{
    bool_t ret = false;

    if((NULL != s_os_cb) &&(NULL != s_os_cb->ops) &&(NULL != s_os_cb->ops->semp_create))
    {
        ret = s_os_cb->ops->semp_create(semp,limit,initvalue);
    }

    return ret;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
2.2.osal_semp_del
bool_t  osal_semp_del(osal_semp_t semp)
{
    bool_t ret = false;

    if((NULL != s_os_cb) &&(NULL != s_os_cb->ops) &&(NULL != s_os_cb->ops->semp_del))
    {
        ret = s_os_cb->ops->semp_del(semp);
    }

    return ret;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
2.3.osal_semp_pend
bool_t  osal_semp_pend(osal_semp_t semp,unsigned int timeout)
{
    bool_t ret = false;

    if((NULL != s_os_cb) &&(NULL != s_os_cb->ops) &&(NULL != s_os_cb->ops->semp_pend))
    {
        ret = s_os_cb->ops->semp_pend(semp,timeout);
    }

    return ret;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
2.4.osal_semp_post
bool_t  osal_semp_post(osal_semp_t semp)
{
    bool_t ret = false;

    if((NULL != s_os_cb) &&(NULL != s_os_cb->ops) &&(NULL != s_os_cb->ops->semp_post))
    {
        ret = s_os_cb->ops->semp_post(semp);
    }

    return ret;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

LiteOS 内核之互斥锁

在多任务环境下,往往存在多个任务竞争同一共享资源的应用场景,互斥锁可被用于对共享资源的保护从而实现独占式访问。互斥锁(mutex)又称互斥型信号量,是一种特殊的二值信号量,用于实现对共享资源的独占式处理。另外,Huawei LiteOS提供的互斥锁通过优先级继承算法,解决了优先级翻转问题。 互斥锁操作与信号量类似,不再赘述。

LiteOS 内核之内存管理

LiteOS动态内存支持 DLINK 和 BEST LITTLE 两种标准算法。
LiteOS动态内存管理的方法使用宏定义的方法使能,在用户工程目录下的OS_CONFIG中的target_config.h文件中配置。
在该文件中,找到下面这两项宏定义,置为 YES 则表示使能:

  • 开启BEST LITTLE 算法
 #define LOSCFG_MEMORY_BESTFIT   YES
  • 1
  • 开启SLAB机制
#define LOSCFG_KERNEL_MEM_SLAB  YES
  • 1

此处不对算法进行赘述,直接看API。

内存管理API

API相关文件与任务管理相同。API列表如下:

接口名功能描述
osal_malloc按字节申请分配动态内存空间
osal_free释放已经分配的动态内存空间
osal_zalloc按字节申请分配动态内存空间,分配成功则初始化这块内存所有值为0
osal_realloc重新申请分配动态内存空间
osal_calloc申请分配num个长度为size的动态内存空间

无论选择使用哪种动态内存管理算法,都使用该API。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/226305
推荐阅读
相关标签
  

闽ICP备14008679号