华为设备认证笔记
内核部分
任务管理
任务管理简介
基本概念
1、从系统的角度看,任务是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源,并独立于其它任务运行。
2、LiteOS的任务模块可以给用户提供多个任务,实现了任务之间的切换和通信,帮助用户管理业务程序流程。这样用户可以将更多的精力投入到业务功能的实现中。
3、LiteOS中的任务是抢占式调度机制,高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度,同时支持时间片轮转调度方式。
4、LiteOS的任务默认有32个优先级(0-31),最高优先级为0,最低优先级为31。用户可使用的有(10-31)。数字越小优先级越高。
任务相关概念
任务状态
任务状态通常分为以下四种:
**就绪(Ready):**该任务在就绪列表中,只等待CPU。
**运行(Running):**该任务正在执行。
**阻塞(Blocked):**该任务不在就绪列表中。包含任务被挂起、任务被延时、任务正在等待信号量、读写队列或者等待读写事件等。
**退出态(Dead):**该任务运行结束,等待系统回收资源。
**任务ID:**在任务创建时通过参数返回给用户,作为任务的一个非常重要的标识。
**任务优先级:**优先级表示任务执行的优先顺序。
**任务入口函数:**每个新任务得到调度后将执行的函数。
**任务控制块TCB:**每一个任务都含有一个任务控制块(TCB)。TCB包含了任务上下文栈指针(stack pointer)、任务状态、
任务优先级、任务ID、任务名、任务栈大小等信息。TCB可以反映出每个任务运行情况。
**任务栈:**每一个任务都拥有一个独立的栈空间,我们称为任务栈。
**任务上下文:**任务在运行过程中使用到的一些资源,如寄存器等,我们称为任务上下文。LiteOS在任务挂起的时候会将本任务的任务上下文信息,保存在自己的任务栈里面,以便任务恢复后,从栈空间中恢复挂起时的上下文信息,从而继续执行被挂起时被打断的代码。
**任务切换:**任务切换包含获取就绪列表中最高优先级任务、切出任务上下文保存、切入任务上下文恢复等动作。
任务的调度机制
任务状态迁移说明:
**就绪态→运行态:**任务创建后进入就绪态,发生任务切换时,就绪列表中最高优先级的任务被执行,从而进入运行态,但
此刻该任务依旧在就绪列表中。
**运行态→阻塞态:**任务运行因挂起、读信号量等待等,在就绪列表中被删除进入阻塞。
**阻塞态→就绪态(阻塞态→运行态):**阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),
此时被恢复的任务会被加入就绪列表,从而由阻塞态变成就绪态;此时如果被恢复任务的优先级高于正在运行任务的优先
级,则会发生任务切换,将该任务由就绪态变成运行态。
**就绪态→阻塞态:**任务也有可能在就绪态时被阻塞(挂起)。
**运行态→就绪态:**有更高优先级任务创建或者恢复后,发生任务切换而进入就绪列表。
**运行态→退出态:**任务运行结束,内核自动将此任务删除,此时由运行态变为退出态。
**阻塞态→退出态:**阻塞的任务调用删除接口,任务状态由阻塞态变为退出态。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pv7iP9oG-1646479961453)(设备附件\任务调度.png)]
实现任务管理
cmsis_os2的API任务接口简介:
接口名 | 功能描述 |
---|---|
osThreadNew | 创建任务 |
osThreadTerminate | 删除某个任务(一般是对非自任务操作) |
osThreadSuspend | 任务挂起 |
osThreadResume | 任务恢复 |
程序中的具体应用
/*****任务一*****/
void thread1(void)
{
int sum = 0;
while (1)
{
printf("This is BearPi Harmony Thread1----%d\r\n", sum++);
usleep(1000000);
}
}
/*****任务二*****/
void thread2(void)
{
int sum = 0;
while (1)
{
printf("This is BearPi Harmony Thread2----%d\r\n", sum++);
usleep(500000);
}
}
/*****任务创建*****/
static void Thread_example(void)
{
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");
}
}
API解析
osThreadNew()
osThreadId_t osThreadNew(osThreadFunc_t func, void *argument,const osThreadAttr_t *attr )
描述:
函数osThreadNew通过将线程添加到活动线程列表并将其设置为就绪状态来启动线程函数。线程函数的参数使用参数指针*argument传递。当创建的thread函数的优先级高于当前运行的线程时,创建的thread函数立即启动并成为新的运行线程。线程属性是用参数指针attr定义的。属性包括线程优先级、堆栈大小或内存分配的设置。可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,但不能在内核初始化 (调用 osKernelInitialize)之前调用该函数。
注意 :不能在中断服务调用该函数
参数:
名字 | 描述 |
---|---|
func | 线程函数. |
argument | 作为启动参数传递给线程函数的指针 |
attr | 线程属性 |
osThreadTerminate()
osStatus_t osThreadTerminate ( osThreadId_t thread_id )
描述:
函数osThreadTerminate从活动线程列表中删除由参数thread_id指定的线程。如果线程当前是RUNNING,则线程终止并继续执行下一个READY线程。如果不存在这样的线程,该函数将不会终止正在运行的线程,而是返回osErrorResource。
注意 :不能在中断服务调用该函数
避免使用不存在或已终止的thread_id调用函数。
osThreadTerminate销毁不可连接的线程并从系统中删除它们的 thread_id。随后对 thread_id 的访问(例如osThreadGetState)将返回一个osThreadError。可加入的线程不会被销毁并返回状态osThreadTerminated,直到它们与osThreadJoin加入。
参数:
名字 | 描述 |
---|---|
thread_id | 线程 ID通过osThreadNew或osThreadGetId获得的线程 ID |
osThreadSuspend()
osStatus_t osThreadSuspend ( osThreadId_t thread_id )
描述:
函数osThreadSuspend暂停由参数thread_id标识的线程的执行。线程被置于BLOCKED状态(osThreadBlocked)。暂停正在运行的线程将导致上下文立即切换到另一个处于READY状态的线程。在使用函数osThreadResume显式恢复之前,不会执行挂起的线程。
注意 : 不能从中断服务程序调用此函数。
当内核被锁定时,不能调用 这个函数来挂起正在运行的线程,即osKernelLock。
参数:
名字 | 描述 |
---|---|
thread_id | 线程 ID通过osThreadNew或osThreadGetId获得的线程 ID |
返回值:
-
*osOK:*线程已成功挂起。
-
osErrorParameter: thread_id为NULL或无效。
-
*osErrorResource:*线程处于无效状态。
-
*osErrorISR:*函数osThreadSuspend不能从中断服务例程中调用。
osThreadResume ()
描述:
函数osThreadResume将由参数thread_id标识的线程(必须处于BLOCKED状态)返回到READY状态。如果恢复的线程比正在运行的线程具有更高的优先级,则立即发生上下文切换。无论线程被阻塞的原因如何,线程都准备就绪。因此不建议恢复未被osThreadSuspend挂起的线程。
注意 : 不能从中断服务程序调用此函数。
当内核被锁定(osKernelLock )时,可能会调用 此函数。在这种情况下,潜在的上下文切换会延迟到内核解锁,即osKernelUnlock或osKernelRestoreLock。
参数:
名字 | 描述 |
---|---|
thread_id | 线程 ID通过osThreadNew或osThreadGetId获得的线程 ID |
返回值:
-
*osOK:*线程已成功恢复。
-
osErrorParameter: thread_id为NULL或无效。
-
*osErrorResource:*线程处于无效状态。
-
*osErrorISR:*函数osThreadResume不能从中断服务例程中调用。
| | |
返回值:
-
*osOK:*线程已成功恢复。
-
osErrorParameter: thread_id为NULL或无效。
-
*osErrorResource:*线程处于无效状态。
-
*osErrorISR:*函数osThreadResume不能从中断服务例程中调用。