FreeRTOS+POSIX之任务管理API详解

FreeRTOS概述

在嵌入式领域中,嵌入式实时操作系统正得到越来越广泛的应用。采用嵌入式实时操作系统(RTOS)可以更合理、更有效地利用CPU的资源,简化应用软件的设计,缩短系统开发时间,更好地保证系统的实时性和可靠性。FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。相对μC/OS-II、embOS等商业操作系统,FreeRTOS操作系统是完全免费的操作系统,具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行。目前,FreeRTOS已经发展到支持包含X86,ARM、Xilinx,Altera等多种的硬件平台,其广阔的应用前景已经越来越受到业内人士的瞩目。

由EE Times(EE Times是一家电子行业杂志,自1972年开始在美国发行)发布的2017年嵌入式市场调研报告关于嵌入式操作系统的使用情况可知FreeRTOS占据份额为20%,排名第二。

EE Times的2017年嵌入式市场调研报告中还对未来一年内考虑使用的嵌入式实时操作做了调研,FreeRTOS以%28位列第一。以上调研结果在一定程度上反应了FreeRTOS使用的广泛性。

FreeRTOS+POSIX概述

可移植操作系统接口(Portable Operating System Interface,缩写为POSIX)是IEEE为要在各种UNIX操作系统上运行软件,而定义API的一系列互相关联的标准的总称,其正式称呼为IEEE Std 1003,而国际标准名称为ISO/IEC 9945。它基本上是Portable Operating System Interface(可移植操作系统接口)的缩写,而X则表明其对Unix API的传承。FreeRTOS + POSIX实现了POSIX线程 API 的子集。借助FreeRTOS + POSIX,可以轻松将现有的POSIX兼容应用程序移植到FreeRTOS生态系统。FreeRTOS + POSIX部分实现了IEEE Std 1003.1-2017 Edition The Open Group Technical Standard Base Specification,Issue 7。

FreeRTOS + POSIX主要实现了任务管理、互斥量、条件变量、消息队列和时钟/定时器等POSIX接口功能。

FreeRTOS+POSIX任务管理

pthread_create() 创建任务

该接口使用指定的属性 attr 创建一个新的任务,如果 attr 为空,则使用默认的任务属性。在任务创建后修改 attr 中的属性值是无效的,并不会影响当前任务的属性。任务创建成功, pthread_create()接口通过参数 thread 返回所创建任务的 ID。被创建的任务使用参数 arg作为start_routine 执行的唯一参数。

pthread_equal() 比较任务 ID

该接口用于比较任务的 ID,如果 t1 和 t2 相等,返回非零;否则返回零。

pthread_exit() 任务退出

该接口终止当前任务,同时使 value_ptr 的值对于任意等待该任务终止的其他任务可用。任务终止的过程中,那些已经压栈但还没出栈的取消处理函数都会以与入栈相反的顺序出栈并执行。如果任务有私有数据,那么在所有的取消处理函数被执行之后,任务会调用这些私有数据的析构函数。任务终止会释放一些系统资源,如互斥信号量和文件描述符等。任务终止后,访问任务的本地(自动)变量的结果是不确定的。因此,任务的本地变量不能作为参数值给pthread_exit()的。

pthread_join() 等待任务终止

该接口将挂起调用任务,直到参数 thread 指定的任务终止。用非空的参数 value_ptr 调用

pthread_join(),则在 pthread_join()成功返回时,任务 thread 会将传递给 pthread_exit()的值赋值给value_ptr 所引用的区域。 pthread_join()成功返回就表明任务 thread 已经终止。一个 joinable 状态下的任务终止后,该任务的内存资源不会被释放,直到有任务对它使用pthread_join()时才被释放,因此必须对创建为 PTHREAD_CREATE_JOINABLE 的任务调用一次pthread_join(),以避免内存泄露。 pthread_join()是一个取消点,即如果任务在 pthread_join()中等待时被取消,该任务将立即继续执行并被取消,而不再等待 thread 指定的任务终止。

pthread_self() 获取调用任务自身的标示符(ID)

该接口用来获取调用任务的 ID。

pthread_attr_init() 初始化任务属性对象

该接口使用默认值初始化一个任务属性对象 attr,初始化默认值是由系统确定的,任务属性对象用于指定任务创建时的属性信息。pthread_create()接口使用该接口初始化的属性对象来定义被创建任务的属性,可以在多个同时调用的 pthread_create()中使用同一个任务属性对象。对于应根据任务进行分别设置的属性,如任务堆栈地址,系统会自动进行分配,保证不会发生重叠。调用设置属性值的接口可以修改已初始化的属性对象。

pthread_attr_destroy() 删除任务属性对象

该接口用来删除线程属性对象,将 attr 引用的对象设定为一个无效值。已删除的 attr 属性对象可以使用 pthread_attr_init() 重新进行初始化。属性对象被删除后不能对其引用。

pthread_attr_getdetachstate() 获取任务的 detachstate 属性

该接口用于获取任务属性对象 attr 中的 detachstate 属性。如果 attr 的 detachstate 属性设置为PTHREAD_CREATE_DETACHED , 则 所 有 使 用 attr 创 建 的 任 务 都 处 于 分 离 状 态 ; 如 果 设 置 为PTHREAD_CREATE_JOINABLE,则所有使用 attr 创建的任务处于联合状态。如果任务被创建为分离的(PTHREAD_CREATE_DETACHED),那么以该任务 ID 作为参数调用 pthread_detach()或 pthread_join()时会失败。

pthread_attr_getschedparam 获取调度策略属性。

pthread_attr_getschedparam()和pthread_attr_setschedparam()函数分别获取和设置调度参数属性。param结构的内容在<sched.h>头文件中定义。调度策略包括SCHED_FIFO和SCHED_RR策略。

pthread_attr_setschedparam 设置调度策略属性。

pthread_attr_getschedparam()和pthread_attr_setschedparam()函数分别获取和设置调度参数属性。param结构的内容在<sched.h>头文件中定义。调度策略包括SCHED_FIFO和SCHED_RR策略。

pthread_attr_getstacksize() 获取任务的 stacksize 属性

该接口用于获取任务属性对象 attr 中的任务创建的 stacksize 属性。

pthread_attr_setdetachstate() 设置任务的 detachstate 属性

该接口用于获取任务属性对象 attr 中的 detachstate 属性。如果 attr 的 detachstate 属性设置为PTHREAD_CREATE_DETACHED , 则 所 有 使 用 attr 创 建 的 任 务 都 处 于 分 离 状 态 ; 如 果 设 置 为PTHREAD_CREATE_JOINABLE,则所有使用 attr 创建的任务处于联合状态。如果任务被创建为分离的(PTHREAD_CREATE_DETACHED),那么以该任务 ID 作为参数调用 pthread_detach()或 pthread_join()时会失败。

pthread_attr_setschedpolicy () 设置任务的 schedpolicy 属性

该接口用于设置任务属性对象 attr 中的 schedpolicy 属性。任 务 调 度 策 略 , 取 值 包 括 SCHED_FIFO 、 SCHED_RR 、 SCHED_OTHER。

pthread_attr_setstacksize() 设置任务的 stacksize 属性

该接口用于设置任务属性对象 attr 中的 stacksize 属性,该属性指定了创建任务栈需分配的长度(字节)。

sched_get_priority_max() 获取任务优先级最大值

该接口用于获取调度策略 policy 对应的调度优先级的最大值。

sched_get_priority_min() 获取任务优先级最小值

该接口用于获取调度策略 policy 对应的调度优先级最小值。

后续文章会详细介绍互斥量、消息队列、时钟/定时器和条件变量相关接口。

今日热门