LiteOS设备开发(6)——任务管理

1、Huawei LiteOS内核简介

2、任务管理简介

3、任务相关概念

4、任务的运作机制

5、操作系统抽象层简介

6、实现任务的创建

7、实验结果与扩展实验
LiteOS设备开发(6)——任务管理

Huawei LiteOS内核简介

背景介绍

HuaweiLiteOS是轻量级的实时操作系统,是华为IOTOS。HuaweiLiteOSKernel的基本框架图。HuaweiLiteOS基础内核是最精简的HuaweiLiteOS操作系统代码,包括任务管理、内存管理、时间管理、通信机制、中断管理、队列管理、事件管理、定时器等操作系统基础组件,可以单独运行。

HuaweiLiteOSKernel的优势

  • 高实时性,高稳定性。
  • 超小内核,基础内核体积可以裁剪至不到10K。
  • 低功耗。
  • 支持动态加载、分散加载。
  • 支持功能静态裁剪。各模块简介

LiteOS设备开发(6)——任务管理

任务管理简介

基本概念

1、从系统的角度看,任务是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源,并独立于其它任务运行。

2、HuaweiLiteOS的任务模块可以给用户提供多个任务,实现了任务之间的切换和通信,帮助用户管理业务程序流程。这样用户可以将更多的精力投入到业务功能的实现中。

3、HuaweiLiteOS是一个支持多任务的操作系统。在HuaweiLiteOS中,一个任务表示一个线程。

4、HuaweiLiteOS中的任务是抢占式调度机制,同时支持时间片轮转调度方式。

5、高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。

6、HuaweiLiteOS的任务一共有32个优先级(0-31),最高优先级为0,最低优先级为31

任务状态

任务状态通常分为以下四种:

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

LiteOS设备开发(6)——任务管理
任务状态迁移说明

  • 就绪态→运行态:创建任务会在就绪列表中,运行态的任务会被高优先级打断而就绪。
  • 运行态→阻塞态:任务运行因挂起、读信号量等待等,在就绪列表中被删除进入阻塞。
  • 阻塞态→就绪态(阻塞态→运行态):阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的任务会被加入就绪列表,从而由阻塞态变成就绪态;此时如果被恢复任务的优先级高于正在运行任务的优先级,则会发生任务切换,将该任务由就绪态变成运行态。
  • 就绪态→阻塞态:任务也有可能在就绪态时被阻塞(挂起)。
  • 运行态→就绪态:有更高优先级任务创建或者恢复后,发生任务切换而进入就绪列表。
  • 运行态→退出态:任务运行结束,内核自动将此任务删除,此时由运行态变为退出态。
  • 阻塞态→退出态:阻塞的任务调用删除接口,任务状态由阻塞态变为退出态。

任务管理简介

  • 任务ID:在任务创建时通过参数返回给用户,作为任务的一个非常重要的标识。
  • 任务优先级:优先级表示任务执行的优先顺序。
  • 任务入口函数:每个新任务得到调度后将执行的函数。
  • 任务控制块TCB:每一个任务都含有一个任务控制块(TCB)。TCB包含了任务上下文栈指针(stackpointer)、任务状态、任务优先级、任务ID、任务名、任务栈大小等信息。TCB可以反映出每个任务运行情况。
  • 任务栈:每一个任务都拥有一个独立的栈空间,我们称为任务栈。
  • 任务上下文:任务在运行过程中使用到的一些资源,如寄存器等,我们称为任务上下文。HuaweiLiteOS在任务挂起的时候会将本任务的任务上下文信息,保存在自己的任务栈里面,以便任务恢复后,从栈空间中恢复挂起时的上下文信息,从而继续执行被挂起时被打断的代码。
  • 任务切换:任务切换包含获取就绪列表中最高优先级任务、切出任务上下文保存、切入任务上下文恢复等动作。

运作机制

1、HuaweiLiteOS任务管理模块提供任务创建、任务删除、任务延时、任务挂起和任务恢复、更改任务优先级、锁任务调度和解锁任务调度、根据任务控制块查询任务ID、根据ID查询任务控制块信息功能。

2、在任务模块初始化时,系统会先申请任务控制块需要的内存空间,如果系统可用的内存空间小于其所需要的内存空间,任务模块就会初始化失败。如果任务初始化成功,则系统对任务控制块内容进行初始化。

3、用户创建任务时,系统会将任务栈进行初始化,预置上下文。此外,系统还会将“任务入口函数”地址放在相应位置。这样在任务第一次启动进入运行态时,将会执行“任务入口函数”。

操作系统抽象层简介

概述

为了让SDK能够更广泛的应用,所以提出了OSAL。SDK内部集成的组件以及SDK本身使用的OS功能,都调用的是OSAL接口,因为SDK要运行起来,必须注册相关的OS进OSAL才行。

osal使用说明

osal的api接口声明在<osal.h>中,使用相关的接口需要包含该头文件,关于函数的详细参数请参考该头文件的声明。目前已经适配了LiteOS/LINUX/MACOS等,SDK可以在这些系统下运行。如果你需要在非上述系统下运行SDK,您需要将新系统适配进OSAL,保障SDK需要的OS功能正常。

适配OSAL

您需要在您的系统初始化完毕之后,调用osal_install接口将您的系统注册进SDK即可。使用该接口需要包含<osal_imp.h>,相关的宏定义在<osal_type.h>中。详情参考该头文件。

LiteOS设备开发(6)——任务管理

创建任务:void*osal_task_create(constchar*name,int(*task_entry)(void*args),void*args,intstack_size,void*stack,intprior);
删除某个任务:intosal_task_kill(void*task);
任务退出:voidosal_task_exit();
任务休眠:voidosal_task_sleep(intms);

创建任务接口详解:void*osal_task_create(constchar*name,int(*task_entry)(void*args),void*args,intstack_size,void*stack,intprior);

LiteOS设备开发(6)——任务管理

实现任务创建

LiteOS设备开发(6)——任务管理

实验结果与扩展实验

#include <osal.h>

#define USER_TASK1_PRI  12
#define USER_TASK2_PRI  11

uint32_t user_task1_id = 0;
uint32_t user_task2_id = 0;

static int user_task1_entry()
{
    int n = 0;

    for(n = 0; n < 5; n++)
    {
        printf("task1: my task id is %ld, n = %d!\r\n", user_task1_id, n++);
        osal_task_sleep(2*1000);
    
    }

    printf("user task 1 exit!\r\n");
    return 0;
}
static int user_task2_entry()
{
    while (1)
    {
        printf("task 2: my task id is %ld!\r\n", user_task2_id);
        osal_task_sleep(2*1000);
    }
}

int standard_app_demo_main()
{
    user_task1_id = osal_task_create("user_task1",user_task1_entry,NULL,0x400,NULL,USER_TASK1_PRI);
    user_task2_id = osal_task_create("user_task2",user_task2_entry,NULL,0x400,NULL,USER_TASK2_PRI);

    return 0;
}

系统启动后,串口shell的优先级为10,最先打印shell信息,接下来task1先创建,但是优先级较低,所以后创建的task2抢占执行,task2打印后主动挂起2s,这时task1开始执行,依次执行5次后task1结束,task2一直保持运行

上一篇:2022/2/2 Java开发之Java web编程 第五章 使用三层架构实现业务处理


下一篇:Tekton DAG代码