Nuttx操作系统(二):任务

Nuttx是一个实时操作系统,其核心组成部分是调度器,负责控制任务执行。任务由任务控制块(TCB)表示,并存储在各种列表中以管理其状态。调度策略包括优先级调度SCHED_FIFO和循环调度SCHED_RR。Nuttx不支持进程,而是仅处理线程,同时支持POSIX线程(pthread)。任务和pthread之间的资源是共享的,并且可以通过task_create等接口创建。此外,Nuttx还包含内核线程,它们拥有更高的权限并能访问所有OS资源。

Nuttx操作系统 - 知乎 (zhihu.com)

1.1 Nuttx任务

1.1.1 调度器

操作系统是开发应用程序的完整环境。操作系统的一个重要组件是调度程序:控制任务或线程执行时间的逻辑。事实上,不止如此;调度程序真正决定了任务或线程是什么!从提供完整的操作环境的意义上来说,大多数微小的操作系统实际上不是操作“系统”。相反,这些微小的操作系统实际上只由一个调度器组成。这就是调度程序的重要性。

1.1.2 任务控制块

在NuttX中,线程是任何具有自己堆栈的可控指令执行序列。每个任务由称为任务控制块或TCB(Task Control Block)的数据结构表示。该数据结构在头文件include/nuttx/sched.h中定义。

1.1.3 任务列表

这些TCB保存在列表中。任务的状态由TCB的task_state字段和一系列任务列表指示。尽管并不总是必要的,但这些列表中的大多数都是优先排序的,以便可以使用通用的列表逻辑来处理(只需要对g_readytorun、g_pendingtasks和g_waitingforsemaphore列表进行优先排序)。

为激活任务列表g_inactivetasks:

Ø 这是已初始化但尚未激活的所有任务的列表。注意:这是唯一没有区分优先级的列表。

Ø 任务被初始化后,它将移动到准备运行列表中。有两个列表表示准备运行的线程,还有几个列表表示阻塞的线程。

以下是准备运行线程列表g_readtorun:

Ø 这是所有准备就绪任务的列表。此列表的头部是当前活动的任务;这个列表的尾部总是空闲任务。

准备就绪,处于阻塞列表g_pendingtasks:

Ø 这是所有准备运行的任务的列表,但不能放在g_readytorun列表中,因为:(1)它们的优先级高于g_readitorun表头部的当前活动任务;(2)并且当前活动任务已禁用了抢占。这些任务将保留在此等待列表中,直到再次启用抢占(或直到当前活动任务自动放弃CPU)。

Ø g_readytorun列表中的任务可能会被阻止。在这种情况下,他们的TCB将被移动到其中一个阻止列表中。当任务准备好运行时,其TCB将移回到g_readytorun或g_pendingtasks列表,这取决于是否禁用了抢占以及任务的优先级。

以下是被阻止的任务列表:

等待信号量队列g_waitingforsemaphore:

Ø 这是等待信号量而被阻止的所有任务的列表。

等待信号队列g_waitingforsignal:

Ø 这是被阻止等待信号的所有任务的列表(仅当信号支持未被禁用时)

等待消息队列变为非空队列g_waitingformqnotempty:

Ø 这是等待消息队列变为非空(仅当消息队列支持未被禁用时)而被阻止的所有任务的列表。

等待消息队列变为非满队列g_waitingformq:

Ø 这是等待消息队列变为非满而被阻止的所有任务的列表(仅当消息队列支持未被禁用时)。

等待page fill队列g_waitingforfill:

Ø 这是被阻止而等page fill的所有任务的列表(仅当选择paging)。

1.1.4 任务状态转换

Nuttx操作系统的任务状态转换如下所示:

Ø 任务被创建初期,任务处于为激活状态;

Ø 当任务资源准备就绪后,激活任务;

Ø 当前运行任务不可被抢占,把创建的任务设置为pending状态;

Ø 当前任务可以被抢占,把创建的任务设置为ready-to-run状态;

Ø 如果此任务优先级高于正在当前任务,任务被设置为running状态,系统进行上下文切换;

Ø 当前运行任务被抢占,任务被设置为read-to-run状态;

Ø 当前任务由于资源不可用,被设置为阻塞状态;

Ø 被阻塞的任务,资源可以使用,当前任务不可被抢占,阻塞任务被设置为pending状态;当前任务可以被抢占,阻塞任务被设置为ready-to-run状态;

Ø 系统进行调用,处于pending状态的任务被设置为ready-to-run状态;

1.1.5 调度策略

为了成为实时操作系统,RTOS必须支持SCHED_FIFO。也就是说,严格的优先级调度。优先级最高的线程运行若干周期。优先级最高的线程始终与g_readytorun列表开头的TCB相关联。

NuttX支持一个额外的实时调度策略:SCHED_RR。RR代表循环,这有时被称为循环调度。在这种情况下,NuttX支持时间间隔:如果具有SCHED_RR调度策略的任务正在运行,那么当每个时间间隔过去时,它将把CPU让给具有相同优先级的下一个任务。注意:(1)如果此优先级只有一个任务,则SCHED_RR和SCHED_FIFO是相同的,并且(2)SCHED_FIFO任务决不会以这种方式被抢占。

1.1.6 任务ID

每个任务不仅由TCB表示,而且由数字任务ID表示。给定任务ID,RTOS可以找到TCB;给定TCB,RTOS可以找到任务ID。因此它们在功能上是等价的。然而,只有任务ID作为RTOS应用程序接口。

1.1.7 进程VS线程

在较大的系统操作系统(如Windows或Linux)中,您经常会听到名称进程,用于指代由操作系统管理的线程。正如我们到目前为止所讨论的,进程不仅仅是一个线程。进程是托管一个或多个线程的受保护环境。所谓环境,我们指的是OS预留的一组资源,但在进程的受保护环境中,我们具体指的是其地址空间。

为了实现进程的地址空间,CPU必须支持内存管理单元(MMU)。MMU用于实施受保护的过程环境。

然而,NuttX的设计目的是支持资源受限、低端、深度嵌入的MCU。这些MCU很少有MMU,因此永远无法支持Windows和Linux支持的进程。因此,NuttX不支持进程。NuttX将支持MMU,但不会使用MMU来支持进程。NuttX仅在FLAT地址空间中运行。(NuttX将使用MMU控制指令和数据缓存,并支持受保护的内存区域)。

1.1.8 Nuttx任务和任务资源

所有RTOS都支持任务的概念。任务是RTOS的与进程等价的概念。与进程一样,任务是一个线程,其环境与其关联。该环境类似于进程的环境,但不包括私有地址空间。此环境是专用的,对于任务是唯一的。每个任务都有自己的环境

该任务环境由许多资源组成(如TCB)。本次讨论感兴趣的内容如下。请注意,可以在NuttX配置中禁用这些任务资源中的任何一个,以减少NuttX内存占用:

Ø 环境变量。这是变量赋值的集合:例如variable=VALUE

Ø 文件描述符。文件描述符是一个特定于任务句柄,表示打开的资源(例如文件或设备驱动程序)。

Ø socket。套接字描述符类似于文件描述符,与网络相关。

Ø 流。流表示标准C缓冲I/O。流封装文件描述符或套接字,以提供一组新的接口函数来处理标准的C I/O(如fprintf()、fwrite()等)。

在NuttX中,使用界面task_create()创建任务。

1.1.9 任务VS线程

像Linux这样的系统支持POSIX pthread。在Linux环境中,创建进程时有一个线程在其中运行。但通过使用pthread_create()等接口,您可以创建多个运行并共享相同进程资源的线程。

NuttX也支持POSIX pthread,NuttX pthread也支持这种行为。也就是说,NuttX POSIX pthread也共享父任务的资源。然而,由于NuttX不支持进程地址环境,因此差异并不显著。当任务创建pthread时,新创建的pthread将共享父任务的环境变量、文件描述符、套接字和流。

注意:这些任务资源是引用计数的,只要任务组中的线程仍处于活动状态,这些资源就会持续存在。

术语进程ID是标准的(通常缩写为pid),用于标识NuttX中的任务。因此,更严格地说,这个pid是如上所述的任务ID。Pthreads由pthread_t ID描述,在NuttX中,pthread_t ID与任务ID相同。

1.1.10 Nuttx线程类型

NuttX支持三类线程:任务、pthread和内核线程。任务和pthreads都是应用程序线程,通过一些使用语义和它们的层次关系来区分。任务是通过几种不同的机制创建的:task_create()、task_spawn()、execv()、posix_spaven()等。然后,任务可以使用pthread_create()创建pthread。

1.1.10.1 内核线程

内核线程与任务非常相似,只是它们在操作系统内部运行,并以Kernel_thread()启动,该线程在include/nuttx/kthread.h中声明。

与任务的不同之处在于:

(1)在PROTECTED和Kernel模式构建中,它们具有完全的监管者特权。

(2)它们可以完全访问所有内部OS资源。

为了将任务作为一个内核线程构建到操作系统中,您只需:

(1)将内核线程代码放在板级源代码目录中。

(2)在板启动逻辑中使用kernel_thread()启动它。

1.1.10.2 任务

1.1.10.3 Pthread线程

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值