
在先前的文章中介绍了问题的概念。 实际上,任务只是一组值,可以将这些值加载到处理器寄存器中(用于要执行的任务),或者可以以准备就绪的状态存储,以便将来在上下文中切换到该任务。 大多数情况下,任务都有自己的堆栈。
当然,使用“运行完成”(RTC)调度程序时,不使用上下文切换,并且可以将任务视为程序计数器(代码入口点)的值。
任务的定义不包括代码本身。 该任务应执行代码,但不属于该代码。 任务可能具有共同的功能。 此外,可以共享多个任务的所有代码。 通用代码几乎应始终根据可重入要求编写。 大多数编译器可以轻松地处理此代码,但是必须小心使用库函数,因为它们可能不适用于多任务应用程序。
这样的定义规定了开发本文中描述的任务和API函数的数据结构时应遵循的某些规则。 我将回顾Nucleus SE中任务的配置,并开始详细介绍适用于Nucleus SE和Nucleus RTOS中任务的服务调用(API调用)。
该系列中的先前文章:
第10条 计划程序:高级功能和上下文保留第9条。 调度程序:实施第8条 Nucleus SE:内部设计和部署第7条 Nucleus SE:简介第6条。 其他RTOS服务第5条 任务交互和同步第4条 任务,上下文切换和中断第3条 任务与计划第2条。 RTOS:结构和实时模式
第1条 RTOS:简介。
任务配置
任务数
在Nucleus SE中,任务配置主要由
nuse_config.h中的
#define指令驱动。 关键参数
NUSE_TASK_NUMBER确定可以在应用程序中配置的任务数。 默认值为1(即执行过程中的一个任务),参数的最大值为16。不正确的值将导致编译错误,这将通过检入
nuse_config_chech.h生成(包含在
nuse_config.c中 ,这意味着使用此模块编译),则将
触发#error指令。 此参数用于确定数据结构;其大小取决于其值。
在Nucleus SE中,除非使用RTC调度程序,否则至少要准备好执行一项任务,这一点很重要。 使用优先级调度程序时,需要确保优先级最低的任务永远不会处于挂起状态,这样的任务应被视为“后台任务”。
与其他一些实时内核不同,Nucleus SE不使用“系统任务”,这意味着所有16个任务都可用于用户应用程序代码或中间件。
API参数
Nucleus SE中的每个API函数(实用程序调用)
都由nuse_config.h中的
#define指令激活。 对于任务,这些参数是:
- NUSE_TASK_SUSPEND
- NUSE_TASK_RESUME
- NUSE_TASK_SLEEP
- NUSE_TASK_RELINQUISH
- NUSE_TASK_CURRENT
- NUSE_TASK_CHECK_STACK
- NUSE_TASK_RESET
- NUSE_TASK_INFORMATION
- NUSE_TASK_COUNT
默认情况下,以上所有参数均设置为
FALSE ,从而停用每个服务调用并防止包含实现它们的任何代码。 要为应用程序配置任务,您需要选择必要的API调用并将相应的字符设置为
TRUE 。
以下是默认
nuse_config.h文件的
片段 。

如果您的代码使用尚未激活的API调用,则在链接过程中将出现错误,因为应用程序中未包含实现代码。
功能参数
Nucleus SE可以添加一些任务功能。 同样,必要的参数位于
nuse_config.h文件中:
NUSE_SUSPEND_ENABLE允许
您暂停任务。 如果未选择此选项,则所有任务都将持续等待计划。 使用优先级调度程序时,需要激活此参数。
NUSE_BLOCKING_ENABLE允许
您将任务挂起到多个函数API调用。 如果激活此选项,
则还必须激活
NUSE_SUSPEND_ENABLE 。
NUSE_INITIAL_TASK_STATE_SUPPORT允许
您设置任务的初始状态。 如果未选择此选项,则所有任务将在创建后立即添加到调度程序中。
实用程序任务调用
Nucleus RTOS支持16个服务调用(API),以处理提供以下功能的任务:
功能说明 | 核RTOS | 核SE |
---|
暂停任务 | NU_Suspend_Task() | NUSE_Task_Suspend() |
恢复任务 | NU_Resume_Task() | NUSE_Task_Resume() |
暂停特定任务 期间 | NU_Sleep() | NUSE_Task_Sleep() |
CPU控制释放 | NU_Relinquish() | NUSE_Task_Relinquish() |
获取当前任务的ID | NU_Current_Task_Pointer() | NUSE_Task_Current() |
检查可用的堆栈大小 | NU_Check_Stack() | NUSE_Task_Check_Stack() |
将任务退回未使用 状态(重置) | NU_Reset_Task() | NUSE_Task_Reset() |
提供有关特定任务的信息 | NU_Task_Information() | NUSE_Task_Information() |
获取计数器 应用程序中的任务(当前) | NU_Established_Tasks() | NUSE_Task_Count() |
向应用程序添加新任务(创建) | NU_Create_Task() | 未实施。 |
从应用程序中删除任务 | NU_Delete_Task() | 未实施。 |
返回所有任务的指针 在应用程序中 | NU_Task_Pointers() | 未实施。 |
变更挤压算法 | NU_Change_Preemption() | 未实施。 |
更改任务优先级 | NU_Change_Priority() | 未实施。 |
更改任务的时间范围 | NU_Change_Time_Slice() | 未实施。 |
任务完成 | NU_Terminate_Task() | 未实施。 |
上述每个服务调用的实现将在下面以及下面有关RTOS的文章中详细讨论。
任务管理服务
任务的基本操作:无限期地暂停任务,继续执行,在特定时间暂停任务,释放处理器。 Nucleus RTOS和Nucleus SE提供了四个基本的API调用来执行这些操作,下面将对此进行介绍。
暂停任务
Nucleus PLUS提供了一个简单的API调用,使您可以无限期地暂停特定任务。 Nucleus SE的办公室电话功能类似。
在Nucleus RTOS中挂起任务服务电话原型:
状态NU_Suspend_Task(NU_TASK *任务);参数:
task-指向已暂停任务的控制单元的指针(可能是当前任务,其ID可以使用
NU_Current_Task_Pointer()获得,在下一篇文章中有更多介绍)。
返回值:
NU_SUCCESS-调用成功完成;
NU_INVALID_TASK-指向任务的无效指针;
NU_INVALID_SUSPEND-指定的任务的状态为
NU_FINISHED或
NU_TERMINATED 。
挑战任务在Nucleus SE中暂停该API调用支持Nucleus PLUS API的核心功能。
服务电话原型:
STATUS NUSE_Task_Suspend(NUSE_TASK任务);参数:
task-暂停的任务的索引(ID)(可以是当前任务,其ID可以使用
NUSE_Task_Current()获得-下一篇文章中有更多信息)。
返回值:
NUSE_SUCCESS-呼叫已成功完成;
NUSE_INVALID_TASK-无效的任务索引。
在Nucleus SE中实施任务暂停API函数的主要功能非常简单:

实际上,在此实现中,使用“无条件停止”参数(
NUSE_PURE_SUSPEND )调用了
NUSE_Suspend_Task()调度程序函数。 如果暂停的任务正在进行,则此函数调用调度程序。
恢复任务
Nucleus RTOS提供了一个简单的API调用,使您可以恢复以前无限期暂停的任务。 Nucleus SE的办公室电话功能类似。
Nucleus RTOS中的挑战恢复任务服务电话原型:
状态NU_Resume_Task(NU_TASK *任务);参数:
任务 -指向更新任务的控制单元的指针。
返回值:
NUSE_SUCCESS-呼叫已成功完成;
NUSE_INVALID_TASK-指向任务的无效指针;
NUSE_INVALID_RESUME-任务没有被无条件地挂起。
Nucleus SE中的挑战简历任务该API调用支持Nucleus RTOS API的核心功能。
服务电话原型:
STATUS NUSE_Task_Resume(NUSE_TASK任务);参数:
任务 -更新任务的索引(ID)。
返回值:
NUSE_SUCCESS-呼叫已成功完成;
NUSE_INVALID_TASK-无效的任务索引;
NUSE_INVALID_RESUME-任务没有被无条件地挂起。
在Nucleus SE中实施简历任务API函数的主要功能非常简单:

实际上,此实现中调用了
NUSE_Wake_Task()调度程序函数。 如果使用了优先级调度程序,则此函数调用调度程序,并且更新的任务具有比当前任务更高的优先级。
暂停任务一段时间
Nucleus RTOS提供了一个简单的API调用,以在特定时间段内暂停当前任务。 Nucleus SE的办公室电话功能类似。
在特定时间段内调用挂起任务Nucleus RTOS服务电话原型:
VOID NU_Sleep(未签名的滴答声);参数:
ticks-任务应暂停的时间段(实时时钟
ticks )。
返回值:
不行
挑战特定时间段的任务暂停Nucleus SE该API调用支持Nucleus RTOS API的核心功能。
服务电话原型:
NUSE_Task_Sleep无效(U16刻度);参数:
ticks-任务应暂停的时间段(实时时钟
ticks )。
返回值:
不行
在Nucleus SE中在特定时间段内暂停任务API函数的主要功能非常简单:

此代码将延迟值加载到
NUSE_Task_Timeout_Counter []中的当前任务参数中。 之后,使用具有暂停时间段(
NUSE_SLEEP_SUSPEND )的
NUSE_Suspend_Task()暂停任务。
超时值由实时时钟中断处理程序使用。 该代码如下所示,并将在以后的文章中详细讨论。

CPU释放
Nucleus PLUS提供了一个简单的API调用,以基于Round Robin算法将处理器控制权转移到具有相同优先级的任何准备执行的任务。 Nucleus SE的办公室电话功能非常相似。 但是,它不能与优先级调度程序一起使用,因为不支持具有相同优先级的多个任务。 尝试通过优先级调度程序使用此API调用将导致错误。 实用程序调用与Round Robin和Time Slice调度程序一起使用;对于Run To Completion调度程序,此API调用效率很低。
Nucleus RTOS处理器发布电话该API调用支持Nucleus PLUS API的核心功能。
服务电话原型:
VOID NU_Relinquish(VOID);参数:
缺席。
返回值:
不行
Nucleus SE处理器发布电话该API调用支持Nucleus PLUS API的核心功能。
服务电话原型:
NUSE_Task_Relinquish(无效);参数:
缺席。
返回值:
不行
Nucleus SE处理器发布实施API函数的主要功能:

本质上,此实现调用
NUSE_Reschedule()调度程序函数。 该功能只是告诉调度程序完成下一个任务。
接下来的两篇文章将继续使用Nucleus RTOS和Nucleus SE示例回顾与任务相关的RTOS实用程序调用。
关于作者: Colin Walls在电子行业工作了30多年,大部分时间用于固件。 他现在是Mentor Embedded(Mentor Graphics的一个部门)的固件工程师。 Colin Walls经常在会议和研讨会上发表演讲,他撰写了许多技术文章并撰写了两本有关固件的书。 居住在英国。
Colin的专业
博客 ,电子邮件:colin_walls@mentor.com。
关于翻译:尽管尽管在某些地方已经描述了过时的方法,但该系列文章似乎很有趣,作者以一种非常易于理解的语言向未受过良好培训的读者介绍了实时OS的功能。 我本人属于
俄罗斯RTOS的创建者团队,我们
打算免费提供它 ,我希望这一周期对新手开发人员有用。