小熊派HarmonyOS 任务管理

1 任务相关概念

1.1 任务状态

任务通常分为分为四个状态,分别是:
(1)就绪——任务在就绪列表
(2)运行——任务正在运行
(3)阻塞——任务不在就绪列表,也没在执行,等待着被事件触发
(4)退出——任务运行结束,等待系统回收资源

  • 任务运行结束时或者阻塞的任务调用删除接口时,任务会进入退出态
  • 任务调度的机制主要围绕就绪、运行、阻塞进行变化。

1.2 任务控制块TCB

TCB包含了任务上下文栈指针(stack pointer)、任务状态、任务优先级、任务ID、任务名、任务栈大小等信息。TCB可以反映出每个任务运行情况。

1.3 任务入口函数

任务得到调度之后将执行的函数。(能控制任务状态的API任务接口)

1.4 任务优先级

表示任务执行的优先顺序,在此处数字越大优先级越高。不修改内核代码的情况下为0~31共32的优先级。

1.5 任务ID

任务创建时通过参数返回给用户,作为任务的一个非常重要的标识。

1.6 任务栈

每一个任务都拥有一个独立的栈空间,称为任务栈。

1.7 任务上下文

任务在运行过程中使用到的一些资源,如寄存器等,称为任务上下文。LiteOS在任务挂起的时候会将本任务的任务上下文信息,保存在自己的任务栈里面,以便任务恢复后,从栈空间中恢复挂起时的上下文信息,从而继续执行被挂起时被打断的代码。

1.8 任务切换

任务切换包含获取就绪列表中最高优先级任务、切出任务上下文保存、切入任务上下文恢复等动作。

2 任务调度

任务调度是安排任务执行的行为,实际上是依赖于任务状态的切换(不是任务切换,是状态切换)。
任务状态的切换图如图2.1所示。

任务状态切换图

图2.1 任务调度关系图

各个任务状态的切换中,需要注意的有以下几点:

  • 阻塞态要切换到运行态,需要先切换成就绪态,并在优先级运行的前提下等待系统调度,进入运行态。
  • 发生任务切换时,就绪列表中最高优先级的任务被执行,从而进入运行态,但此刻该任务依旧在就绪列表中。
  • 任务运行结束,内核自动将此任务删除,此时由运行态变为退出态。
  • 阻塞的任务调用删除接口,任务状态由阻塞态变为退出态。
  • 任务运行因挂起、读信号量等待等,在就绪列表中被删除进入阻塞。

3 任务管理

实现任务的管理实际,在适当的情况下运行所需要的任务,这就得依赖任务调度机制。
实现任务管理中需要用到cmsis_os2的API任务接口,常用的API任务接口如表3.1所示

表3.1 常用API任务接口
接口名功能
osThreadNew创建任务
osThreadTerminate删除任务
osThreadSuspend任务挂起
osThreadResume任务恢复

此处围绕任务创建的参数进行展开说明:
osThreadNew(osThreadFunc_t func, void * argument, const osThreadAttr_t * attr)
func:任务函数
argument:作为启动参数传递给任务函数的指针
attr:任务入口函数的参数列表,此处就传递给osThreadNew()任务接口。
任务创建函数的返回值即为任务ID

4 实战案例

案例实现目标:创建两个任务,分别以不同的时间间隔打印对应信息,穿插任务状态切换的过程。
主要使用任务创建函数接口。
示例代码一:任务函数

void threadHi(void)
{
	printf("enter threadHi\r\n");
	osDelay(1);
	printf("threadHi delay done\r\n");
	osThreadSuspend(threadHiID);//任务一挂起
	printf("threadHi osThreadResume success\r\n");
	osThreadTerminate(threadHiID);//删除任务一
}

void threadLo(void)
{
	for(int i = 0; i < 10; i++)
	{
		printf("enter threadLo\r\n");
	}
	printf("threadHi osThreadSuspend success\r\n");
	osThreadResume(threadHiID);//任务一恢复
	osThreadTerminate(threadLoID);//任务二删除
}

示例代码二:创建任务

osThreadId_t threadHiID ;//任务一ID
osThreadId_t threadLoID ;//任务二ID
/*****任务创建*****/
static void Thread_example(void)
{
	osThreadAttr_t attr;
	attr.name = "threadHi";
	attr.attr_bits = 0U;
	attr.cb_mem = NULL;
	attr.cb_size = 0U;
	attr.stack_mem = NULL;
	attr.stack_size = 1024 * 4;
	attr.priority = 25;
	threadHiID = osThreadNew((osThreadFunc_t)threadHi, NULL, &attr);
	if ( threadHiID == NULL)
	{
		printf("Falied to create threadHi!\n");
	}
	attr.name = "threadLo";
	attr.priority = 24;
	threadLoID = osThreadNew((osThreadFunc_t)threadLo, NULL, &attr); 
	if (threadLoID == NULL)
	{
		printf("Falied to create threadLo!\n");
	}
}
SYS_RUN(Thread_example);//自启动

最后在业务gn文件和模块gn文件上进行相应修改,编译烧写到开发板中。

5 案例分析

案例一开始设置了任务的一些相关参数,用以进行任务创建。通过任务ID判断任务创建的情况,根据创建成功与否的情况打印相应的信息。此次分析主要分析任务调度的情况。

因为任务一的优先级为25,高于任务二24,所以任务创建时两个任务处于就绪态。
具体流程如图5.1所示
任务运行流程图

图5.1 任务运行流程图

初次学习,描述有误欢迎评论区指出。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值