管道:介绍和基本服务
管道:介绍和基本服务
Pipes introduction and basic services
与邮箱或队列相比,它们提供了在任务之间传递简单消息的更灵活的方式。
使用管道
在Nucleus SE中,管道是在构建时配置的。一个应用程序最多可以配置16个管道。如果未配置管道,则应用程序中不会包含与管道相关的数据结构或服务调用代码。
管道仅仅是一组存储位置,每个存储位置都足够大,足以容纳一个用户定义字节长度的数据项,对这些数据项的访问是受控制的,以便可以由多个任务安全地使用它。任务可以重复写入管道,直到所有位置都已满。任务可以从管道中读取,数据通常以先进先出(FIFO)的方式接收。尝试发送到完整管道或从空管道读取可能会导致错误或任务挂起,具体取决于在API调用和Nucleus SE配置中选择的选项。
管道和队列
Nucleus SE还支持队列,管道和队列之间的主要区别是消息大小。队列携带由单个ADDR组成的消息,这些地址通常是指针。管道承载任意字节长的消息;应用程序中每个管道的大小是固定的,并在配置时设置。
配置管道
管道数量
与Nucleus SE的大多数方面一样,管道的配置主要由nuse_config.h中的#define语句控制。键设置是NUSE_PIPE_NUMBER,它确定为应用程序配置了多少个管道。默认设置为0(即没有管道正在使用),您可以将其设置为最大16的任何值。错误的值将导致编译时错误,该错误由nuse_config_check.h中的测试生成(此错误包含在nuse_config.c中,因此使用此模块进行编译),从而导致编译一个#错误语句。
选择非零值是管道的“主启用”。这将导致一些数据结构被相应地定义和调整大小,在下一篇文章中会有更多内容。它还激活API启用设置。
API启用
Nucleus SE中的每个API函数(服务调用)在nuse_config.h中都有一个启用的#define符号。对于管道,包括:
NUSE_PIPE_SEND
NUSE_PIPE_RECEIVE
NUSE_PIPE_JAM
NUSE_PIPE_RESET
NUSE_PIPE_INFORMATION
NUSE_PIPE_COUNT
默认情况下,所有这些都设置为FALSE,从而禁用每个服务调用并禁止包含任何实现代码。要为应用程序配置管道,需要选择要使用的API调用,并将其启用符号设置为TRUE。
下面是从默认nuse_config.h文件中提取的内容。
#define NUSE_PIPE_NUMBER 0 /* Number of pipes in the
system – 0-16 */
/* Service call enablers */
#define
NUSE_PIPE_SEND FALSE
#define
NUSE_PIPE_RECEIVE FALSE
#define
NUSE_PIPE_JAM FALSE
#define
NUSE_PIPE_RESET FALSE
#define
NUSE_PIPE_INFORMATION FALSE
#define
NUSE_PIPE_COUNT FALSE
如果启用了管道API函数而未配置管道(除非始终允许使用NUSE_pipe_Count()),则会导致编译时错误。如果您的代码使用尚未启用的API调用,则会导致链接时间错误,因为应用程序中不会包含任何实现代码。
管道服务电话
Nucleus RTOS支持10个与管道相关的服务调用,它们提供以下功能:
向管道发送消息。由Nucleus SE中的NUSE_Pipe_Send()实现。
从管道接收消息。由Nucleus SE中的NUSE_Pipe_Receive()实现。
在管道前面发个信息。由Nucleus SE中的NUSE_Pipe_Jam()实现。
将管道恢复到未使用状态,不暂停任何任务(重置)。由Nucleus SE中的NUSE_Pipe_Reset()实现。
提供有关指定管道的信息。由Nucleus SE中的NUSE_Pipe_Information()实现。
返回(当前)为应用程序配置的管道数的计数。由Nucleus SE中的NUSE_Pipe_Count()实现。
向应用程序添加新管道(创建)。未在Nucleus SE中实现。
从应用程序中删除管道(删除)。未在Nucleus SE中实现。
返回指向应用程序中所有管道(当前)的指针。未在Nucleus SE中实现。
向管道(广播)上挂起的所有任务发送消息。未在Nucleus SE中实现。
将详细检查每个服务调用的实现。
管道读写服务
可以在管道上执行的基本操作是向管道写入数据(有时称为发送)和从中读取数据(也称为接收)。也可以将数据写入管道前端,这也被称为堵塞。Nucleus RTOS和Nucleus SE各自为这些操作提供了三个基本API调用,这里将对此进行讨论。
写在管道上
Nucleus RTOS API对管道的写入调用非常灵活,允许您无限期地挂起,或者在操作无法立即完成的情况下暂停,也就是说,您尝试写入一个完整的管道。Nucleus SE提供相同的服务,除了task suspend是可选的并且不实现timeout。
Nucleus RTOS还提供了一个向管道广播的功能,但Nucleus
SE不支持这种功能。
Nucleus RTOS API Call for Sending to a Pipe
Service call prototype:
STATUS NU_Send_To_Pipe(NU_PIPE *pipe, VOID *message,
UNSIGNED size, UNSIGNED suspend);
Parameters:
pipe – pointer to the user-supplied pipe control block
message – a pointer to the message to be sent
size – the number of bytes in the message. If the pipe supports variable-length messages, this parameter must be equal to or less than the message size supported by the pipe. If the pipe supports fixed-size messages, this parameter must be exactly the same as the message size supported by the pipe
suspend – specification for task suspend; may be NU_NO_SUSPEND or NU_SUSPEND or a timeout value
Returns:
NU_SUCCESS – the call was completed successfully
NU_INVALID_PIPE – the pipe pointer is invalid
NU_INVALID_POINTER – the message pointer is NULL
NU_INVALID_SIZE – the message size is incompatible with the message size supported by the pipe
NU_INVALID_SUSPEND – suspend was attempted from a non-task thread
NU_PIPEE_FULL – the pipe is full and suspend was not specified
NU_TIMEOUT – the pipe is still full even after suspending for the specified timeout value
NU_PIPE_DELETED – the pipe was deleted while the task was suspended
NU_PIPE_RESET – the pipe was reset while the task was suspended
Nucleus SE API Call for Sending to a Pipe
This API call supports the key functionality of the Nucleus RTOS API.
Service call prototype:
<="" font="" style=“box-sizing: inherit;”>
<="" font="" style=“box-sizing: inherit;”>
STATUS NUSE_Pipe_Send(NUSE_PIPE pipe, U8 *message,
U8 suspend);
Parameters:
pipe – the index (ID) of the pipe to be utilized
message – a pointer to the message to be sent, which is a sequence of bytes as long as the configured message size of the pipe
suspend – specification for task suspend; may be NUSE_NO_SUSPEND or NUSE_SUSPEND
Returns:
NUSE_SUCCESS – the call was completed successfully
NUSE_INVALID_PIPE – the pipe index is invalid
NUSE_INVALID_POINTER – the message pointer is NULL
NUSE_INVALID_SUSPEND – suspend was attempted from a non-task
thread or when blocking API calls were not enabled
NUSE_PIPE_FULL – the pipe is full and suspend was not specified
NUSE_PIPE_WAS_RESET – the pipe was reset while the task was
suspended
管道发送的核SE实现
NUSE_Pipe_Send()–检查API函数是否已启用suspend()的条件编译(取决于u)的API是否已启用。我们将在这里分别研究这两种变体。
如果未启用阻塞,则此API调用的代码非常简单:
if (NUSE_Pipe_Items[pipe] == NUSE_Pipe_Size[pipe]) /* pipe full /{ return_value = NUSE_PIPE_FULL;}else / pipe element available */{ data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Head[pipe]]; for (i=0; i<msgsize; i++) { *data++ = *message++; } NUSE_Pipe_Head[pipe] += msgsize; if (NUSE_Pipe_Head[pipe] == (NUSE_Pipe_Size[pipe] * msgsize)) { NUSE_Pipe_Head[pipe] = 0; } NUSE_Pipe_Items[pipe]++; return_value = NUSE_SUCCESS;}
该函数只检查管道中是否有空间,并使用NUSE_pipe_Head[]索引将消息存储在管道的数据区域中。
启用阻塞后,代码会变得更复杂:
do{ if (NUSE_Pipe_Items[pipe] == NUSE_Pipe_Size[pipe]) /* pipe full / { if (suspend == NUSE_NO_SUSPEND) { return_value = NUSE_PIPE_FULL; } else { / block task / NUSE_Pipe_Blocking_Count[pipe]++; NUSE_Suspend_Task(NUSE_Task_Active, (pipe << 4) | NUSE_PIPE_SUSPEND); return_value = NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value != NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } } } else / pipe element available */ { data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Head[pipe]]; for (i=0; i<msgsize; i++) { *data++ = message++; } NUSE_Pipe_Head[pipe] += msgsize; if (NUSE_Pipe_Head[pipe] == (NUSE_Pipe_Size[pipe] * msgsize)) { NUSE_Pipe_Head[pipe] = 0; } NUSE_Pipe_Items[pipe]++; if (NUSE_Pipe_Blocking_Count[pipe] != 0) { U8 index; / check whether a task is blocked on this pipe */ NUSE_Pipe_Blocking_Count[pipe]–; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_PIPE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == pipe)) { NUSE_Task_Blocking_Return[index] = NUSE_SUCCESS; NUSE_Wake_Task(index); break; } } } return_value = NUSE_SUCCESS; suspend = NUSE_NO_SUSPEND; }} while (suspend == NUSE_SUSPEND);
对代码的一些解释可能有用:
代码包含在do…while循环中,当参数suspend的值为NUSE_suspend时,循环将继续。
如果管道已满,并且suspend设置为NUSE_NO_suspend,则API调用将以NUSE_pipe_full退出。如果suspend设置为NUSE_suspend,则任务将被挂起。返回时(即,当任务被唤醒时),如果返回值为NUSE_SUCCESS,表示任务被唤醒是因为消息已被读取(而不是重置管道),则代码循环返回顶部。
如果管道未满,则使用NUSE_pipe_Head[]索引存储提供的消息,以将消息存储在管道的数据区域中。检查管道上是否有任何任务挂起(等待接收)。如果有任务等待,第一个任务被唤醒。suspend变量被设置为NUSE_NO_suspend,API调用将退出并返回NUSE_SUCCESS。
从管子里读东西
从管道读取的Nucleus RTOS API调用非常灵活,使您能够无限期地挂起,或者在操作无法立即完成的情况下暂停,也就是说,您尝试从空管道中读取。Nucleus SE提供相同的服务,除了task suspend是可选的并且不实现timeout。
ucleus RTOS API Call for Receiving from a Pipe
Service call prototype:
STATUS NU_Receive_From_Pipe(NU_PIPE *pipe, VOID *message, UNSIGNED size, UNSIGNED *actual_size, UNSIGNED suspend);
Parameters:
pipe – pointer to user-supplied pipe control block
message – pointer to storage for the message to be received
size –
the number of bytes in the message. This number must correspond to the message size defined when the pipe was created
suspend – specification for task suspend; may be NU_NO_SUSPEND or NU_SUSPEND or a timeout value
Returns:
NU_SUCCESS – the call was completed successfully
NU_INVALID_PIPE – the pipe pointer is invalid
NU_INVALID_POINTER – the message pointer is NULL
NU_INVALID_SUSPEND – suspend was attempted from a non-task
NU_PIPE_EMPTY – the pipe is empty and suspend was not specified
NU_TIMEOUT – indicates that the pipe is still empty even after suspending for the specified timeout value
NU_PIPE_DELETED –
the pipe was deleted while the task was suspended
NU_PIPE_RESET – the pipe was reset while the task was suspended
Nucleus SE API Call for Receiving from a Pipe
This API call supports the key functionality of the Nucleus RTOS API.
Service call prototype:
STATUS NUSE_Pipe_Receive(NUSE_PIPE pipe, U8 *message,
U8 suspend);
Parameters:
pipe – the index (ID) of the pipe to be utilized
message – a pointer to storage for the message to be received, which is a sequence of bytes as long as the configured message size of the pipe
suspend – specification for task suspend; may be NUSE_NO_SUSPEND or NUSE_SUSPEND
Returns:
NUSE_SUCCESS – the call was completed successfully
NUSE_INVALID_PIPE – the pipe index is invalid
NUSE_INVALID_POINTER – the message pointer is NULL
NUSE_INVALID_SUSPEND – suspend was attempted from a non-task thread or when blocking API calls were not enabled
NUSE_PIPE_EMPTY – the pipe is empty and suspend was not specified
NUSE_PIPE_WAS_RESET – the pipe was reset while the task was suspended
Nucleus SE Implementation of Pipe Receive
管道接收的核SE实现
NUSE_Pipe_Receive()API函数的大部分代码(在参数检查之后)是通过条件编译选择的,这取决于是否启用了对阻塞(任务挂起)API调用的支持。我们将在这里分别研究这两种变体。
如果未启用阻塞,则此API调用的代码非常简单:
if (NUSE_Pipe_Items[pipe] == 0) /* pipe empty /{ return_value = NUSE_PIPE_EMPTY;}else{ / message available */ data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Tail[pipe]]; for (i=0; i<msgsize; i++) { *message++ = *data++; } NUSE_Pipe_Tail[pipe] += msgsize; if (NUSE_Pipe_Tail[pipe] == (NUSE_Pipe_Size[pipe] * msgsize)) { NUSE_Pipe_Tail[pipe] = 0; } NUSE_Pipe_Items[pipe]–; *actual_size = msgsize; return_value = NUSE_SUCCESS;}
只需使用管道中的指针NUSE_Pipe_Tail[]从数据管道中返回数据,并通过管道返回数据。 启用阻塞后,代码会变得更复杂:
do{ if (NUSE_Pipe_Items[pipe] == 0) /* pipe empty / { if (suspend == NUSE_NO_SUSPEND) { return_value = NUSE_PIPE_EMPTY; } else { / block task / NUSE_Pipe_Blocking_Count[pipe]++; NUSE_Suspend_Task(NUSE_Task_Active, (pipe << 4) | NUSE_PIPE_SUSPEND); return_value = NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value != NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } } } else { / message available */ data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Tail[pipe]]; for (i=0; i<msgsize; i++) { *message++ = data++; } NUSE_Pipe_Tail[pipe] += msgsize; if (NUSE_Pipe_Tail[pipe] == (NUSE_Pipe_Size[pipe] * msgsize)) { NUSE_Pipe_Tail[pipe] = 0; } NUSE_Pipe_Items[pipe]–; if (NUSE_Pipe_Blocking_Count[pipe] != 0) { U8 index; / check whether a task is blocked / / on this pipe */ NUSE_Pipe_Blocking_Count[pipe]–; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_PIPE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == pipe)) { NUSE_Task_Blocking_Return[index] = NUSE_SUCCESS; NUSE_Wake_Task(index); break; } } } *actual_size = msgsize; return_value = NUSE_SUCCESS; suspend = NUSE_NO_SUSPEND; }} while (suspend == NUSE_SUSPEND);
对代码的一些解释可能有用:
代码包含在do…while循环中,当参数suspend的值为NUSE_suspend时,循环将继续。
如果管道为空,并且suspend设置为NUSE_NO_suspend,则API调用将以NUSE_pipe_empty退出。如果suspend设置为NUSE_suspend,则任务将被挂起。返回时(即,当任务被唤醒时),如果返回值为NUSE_SUCCESS,表示任务因已发送消息而被唤醒(而不是重置管道),则代码循环返回顶部。
如果管道包含任何消息,则使用NUSE_pipe_Tail[]索引返回存储的消息,以从管道的数据区域获取消息。检查管道上是否有任何任务被挂起(等待发送)。如果有任务等待,第一个任务被唤醒。suspend变量被设置为NUSE_NO_suspend,API调用将退出并返回NUSE_SUCCESS。
写在管道前面
Nucleus RTOS-API调用写入管道的前端非常灵活,允许您无限期地挂起,或者在操作无法立即完成的情况下暂停超时;也就是说,您尝试写入一个完整的管道。Nucleus SE提供相同的服务,除了task suspend是可选的并且不实现timeout。
Nucleus RTOS API Call for Jamming to a Pipe
Service call prototype:
STATUS NU_Send_To_Front_Of_Pipe(NU_PIPE *pipe, VOID *message,
UNSIGNED size, UNSIGNED suspend);
Parameters:
pipe – pointer to a user-supplied pipe control block
message – a pointer to the message to be sent
size – the number of bytes in the message. If the pipe supports variable-length messages, this parameter must be equal to or less than the message size supported by the pipe. If the pipe supports fixed-size messages, this parameter must be exactly the same as the message size supported by the pipe.
suspend – specification for task suspend; may be NU_NO_SUSPEND or NU_SUSPEND or a timeout value
Returns:
NU_SUCCESS – the call was completed successfully
NU_INVALID_PIPE – the pipe pointer is invalid
NU_INVALID_POINTER – the message pointer is NULL
NU_INVALID_SIZE – the message size is incompatible with the message size supported by the pipe
NU_INVALID_SUSPEND – suspend was attempted from a non-task thread
NU_PIPE_FULL – the pipe is full and suspend was not specified
NU_TIMEOUT – the pipe is still full even after suspending for the specified timeout value
NU_PIPE_DELETED – the pipe was deleted while the task was suspended
NU_PIPE_RESET – the pipe was reset while the task was suspended
Nucleus SE API Call for Jamming to a Pipe
This API call supports the key functionality of the Nucleus RTOS API.
Service call prototype:
STATUS NUSE_Pipe_Jam(NUSE_PIPE pipe, ADDR *message,
U8 suspend);
Parameters:
pipe – the index (ID) of the pipe to be utilized
message – a pointer to the message to be sent, which is a sequence of bytes as long as the configured message size of the pipe
suspend – specification for task suspend; may be NUSE_NO_SUSPEND or NUSE_SUSPEND
Returns:
NUSE_SUCCESS – the call was completed successfully
NUSE_INVALID_PIPE – the pipe index is invalid
NUSE_INVALID_POINTER – the message pointer is NULL
NUSE_INVALID_SUSPEND – suspend was attempted from a non-task thread or when blocking API calls were not enabled
NUSE_PIPE_FULL – the pipe is full and suspend was not specified
NUSE_PIPE_WAS_RESET – the pipe was reset while the task was suspended
Nucleus SE Implementation of Jamming to a Pipe
The bulk of the code of the NUSE_Pipe_Jam() API function is very similar to that of NUSE_Pipe_Send() , except that the data is stored using the NUSE_Pipe_Tail[] index,
thus:
if (NUSE_Pipe_Items[pipe] == NUSE_Pipe_Size[pipe]) /* pipe full /{ return_value = NUSE_PIPE_FULL;}else / pipe element available */{ if (NUSE_Pipe_Tail[pipe] == 0) { NUSE_Pipe_Tail[pipe] = (NUSE_Pipe_Size[pipe] - 1) * msgsize; } else { NUSE_Pipe_Tail[pipe] -= msgsize; } data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Tail[pipe]]; for (i=0; i<msgsize; i++) { *data++ = *message++; } NUSE_Pipe_Items[pipe]++; return_value = NUSE_SUCCESS;}
管道:介绍和基本服务相关推荐
- Oracle11g服务详细介绍及哪些服务是必须开启的?
Oracle11g服务详细介绍及哪些服务是必须开启的? Oracle ORCL VSS Writer Service Oracle卷映射拷贝写入服务,VSS(Volume Shadow Copy Se ...
- coverity代码检测工具介绍_微服务测试之静态代码扫描
静态代码扫描为整个发展组织增加价值.无论您在开发组织中发挥的作用如何,静态代码扫描解决方案都具有附加价值,拥有软件开发中所需要的尖端功能,最大限度地提高质量并管理软件产品中的风险. 背景 微服务架构模 ...
- android 各种服务介绍,Android 网络服务介绍
1. 介绍 Android网络服务主要包括如下四个部分 -ConnectivityService: 提供数据连接管理服务,包括移动数据.WIFI.以太网等-NetworkPolicyManagerSe ...
- NFS介绍、NFS服务端配置安装配置、 NFS配置选项、 客户端的配置
NFS介绍 NFS是Network File System的缩写 ,是在网络层面,NFS(Network File System)网络文件系统会经常用到,用于在网络上共享存储.这样讲,你对NFS可能不 ...
- OAuth2.0_环境介绍_授权服务和资源服务_Spring Security OAuth2.0认证授权---springcloud工作笔记138
技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 环境介绍 1.可以看到客户端首先访问/oauth/token 这个路径来请求令牌,这个接口是spr ...
- NFS介绍,NFS服务端安装配置,NFS配置选项
2019独角兽企业重金招聘Python工程师标准>>> NFS介绍: NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网 ...
- NFS(NFS介绍,NFS服务端和客户端配置)
一.NFS服务介绍 NFS是 Network File system的缩写 分为2.3.4三个版本,2和3由sun公司起草开发,4.0开始netapp公司参与并主导开发 NFS数据传输基于RPC协议:
- (14)UVM 史上最全通信管道介绍
UVM通信管道 文章目录 UVM通信管道 一.前言 二.TLM FIFO 三.Analysis Port 四.Analysis TLM FIFO 五.Request & Response 通信 ...
- webService(二) 几种常用的框架介绍及Axis 服务端搭建。
一.框架介绍 1.Apache CXF 是由XFire和 Celtix 两个现有的项目进行了重组而形成的新框架,能够与spring完美衔接.支持WS-Addressing.WS-Policy.WS-R ...
最新文章
- python后端开发工程师做什么-如何面试Python后端工程师?
- LeaFlet学习之GridLayer扩展
- CygWin / 安装软件包的方法
- 用内卷搞垮团队!您可真行
- 技术MBA高科技企业的“宠儿”
- BZOJ2654:tree(最小生成树,二分)
- 转:过度疲劳的27个信号与预防方法
- freeradius+mysql+pptpd+radiusmanager 游戏×××代理站完整实验过程
- perl删除Windows下的图片缓存缩略图(Thumbs.db)
- 使用nssm注册系统服务的详细方法
- 随缘刷题算法学习笔记
- wp下载吧主题模板_内含newzhan2.60无授权版本
- Cors跨域(二):实现跨域Cookie共享的三要素
- 这猪蹄是人类能吃完的?
- Hbuilder 真机运行显示未受信任的解决方法(ios)
- 电脑python如何下载_Python for Windows 32位 v3.7.2下载|Python 3.7.2免费电脑版
- 公司AppleID的申请详细流程
- Mysql聚集索引和非聚集索引(堆组织表和索引组织表)
- 系统无法在消息文件中为 Application 找到消息号为 0x2350 的消息文本。
- 【FXCG】对市场保持敬畏之心
热门文章
- 程序主动进行电话短信报警,自定义电话、短信、钉钉报警通知
- jar包升级部署到服务器详细流程,将服务部署在linux中
- python程序如何执行死刑图片_如何判断对象已死
- 关于C语言中的数组指针、指针数组以及二级指针
- 微机原理—定时计数控制接口
- NLP自然语言处理工具小结
- 彻底解决tensorflow:ImportError: Could not find 'cudart64_90.dll' tensorflow安装
- LeetCode简单题之判断国际象棋棋盘中一个格子的颜色
- Camera ISP技术
- 客快物流大数据项目(十二):Docker的迁移与备份