4. 使用采样端口通信
任务目标
在VxWorks ARINC653环境中,通过采样端口(Sampling Port)实现两个分区间的周期性数据通信。本案例将配置一个采样端口对:发送分区周期性地写入消息,接收分区周期性地读取消息,验证数据在分区间的正确传递。
环境依赖
本案例基于VxWorks 7 + ARINC653板级支持包(BSP),需要以下组件:
- VxWorks 7 集成开发环境(Workbench)
- ARINC653内核模块(已启用分区调度)
- 支持ARINC653的BSP(如x86或PowerPC架构)
核心实现
以下代码展示了采样端口通信的完整实现,包含发送分区和接收分区两个独立模块。采样端口采用单生产者单消费者模式,端口方向在创建时确定。
/* 采样端口通信实现 - 发送分区 (Partition1) */
#include <vxWorks.h>
#include <arinc653.h>
/* 采样端口配置参数 */
#define SAMP_PORT_NAME "SAMPLE_PORT_1"
#define SAMP_PORT_MESSAGE_SIZE 32
#define SAMP_PORT_PERIOD_MS 100 /* 发送周期 */
/* 发送分区主函数 */
void Partition1Main(void)
{
STATUS status;
SAMPLING_PORT_ID portId;
SAMPLE_PORT_STATUS portStatus;
char sendBuffer[SAMP_PORT_MESSAGE_SIZE];
int msgCount = 0;
/* 创建采样端口(发送方向) */
status = CREATE_SAMPLING_PORT(
SAMP_PORT_NAME,
SAMP_PORT_MESSAGE_SIZE,
DESTINATION,
SAMP_PORT_PERIOD_MS,
&portId);
if (status != OK) {
printf("P1: 采样端口创建失败, status=%d\n", status);
return;
}
printf("P1: 采样端口创建成功, ID=%d\n", portId);
/* 周期性发送数据 */
while (1) {
/* 构造消息内容 */
snprintf(sendBuffer, sizeof(sendBuffer),
"P1-Msg-%d", msgCount++);
/* 写入采样端口 */
status = WRITE_SAMPLING_MESSAGE(portId,
sendBuffer,
strlen(sendBuffer) + 1);
if (status != OK) {
printf("P1: 写入失败, status=%d\n", status);
} else {
printf("P1: 已发送: %s\n", sendBuffer);
}
/* 周期延时 */
PERIODIC_WAIT(1); /* 等待下一个周期 */
}
}
/* 接收分区主函数 (Partition2) */
void Partition2Main(void)
{
STATUS status;
SAMPLING_PORT_ID portId;
SAMPLE_PORT_STATUS portStatus;
char recvBuffer[SAMP_PORT_MESSAGE_SIZE];
int msgCount = 0;
/* 创建采样端口(接收方向) */
status = CREATE_SAMPLING_PORT(
SAMP_PORT_NAME,
SAMP_PORT_MESSAGE_SIZE,
SOURCE,
SAMP_PORT_PERIOD_MS,
&portId);
if (status != OK) {
printf("P2: 采样端口创建失败, status=%d\n", status);
return;
}
printf("P2: 采样端口创建成功, ID=%d\n", portId);
/* 周期性接收数据 */
while (1) {
/* 读取采样端口消息 */
status = READ_SAMPLING_MESSAGE(portId,
recvBuffer,
sizeof(recvBuffer));
if (status == OK) {
printf("P2: 收到消息: %s\n", recvBuffer);
msgCount++;
} else {
printf("P2: 读取超时或无新数据\n");
}
/* 周期延时 */
PERIODIC_WAIT(1);
}
}
配置说明
在VxWorks的ARINC653分区配置文件中(通常为XML格式),需要为两个分区分配采样端口资源:
<!-- 分区配置文件片段 (arinc653_config.xml) -->
<!-- 采样端口定义 -->
<Sampling_Port>
<Port_Name>SAMPLE_PORT_1</Port_Name>
<Port_Direction>DESTINATION</Port_Direction>
<Max_Message_Size>32</Max_Message_Size>
<Port_Period>100</Port_Period>
</Sampling_Port>
<!-- 分区1 (发送) -->
<Partition>
<Name>Partition1</Name>
<Sampling_Port_Ref>SAMPLE_PORT_1</Sampling_Port_Ref>
</Partition>
<!-- 分区2 (接收) -->
<Partition>
<Name>Partition2</Name>
<Sampling_Port_Ref>SAMPLE_PORT_1</Sampling_Port_Ref>
</Partition>
运行与验证
编译与部署:
- 在Workbench中创建两个分区工程,分别包含Partition1Main和Partition2Main代码
- 编译生成分区可执行文件(.out)
- 配置ARINC653模块系统镜像,加载分区配置文件和两个分区可执行文件
- 启动VxWorks目标机系统
验证方法:
- 观察串口或控制台输出,应看到P1和P2的启动日志
- 确认P1周期性打印"已发送: P1-Msg-N"(N递增)
- 确认P2周期性打印"收到消息: P1-Msg-N",且消息内容与P1发送的序号一致
- 通过条件:P2接收到的消息序号连续递增,无乱序或丢失(在采样端口语义下,允许覆盖旧数据,但不应出现错误内容)
预期输出示例:
P1: 采样端口创建成功, ID=0
P2: 采样端口创建成功, ID=0
P1: 已发送: P1-Msg-0
P2: 收到消息: P1-Msg-0
P1: 已发送: P1-Msg-1
P2: 收到消息: P1-Msg-1
P1: 已发送: P1-Msg-2
P2: 收到消息: P1-Msg-2
...
关键要点
- 采样端口创建时需指定方向:
SOURCE(接收)或DESTINATION(发送),同一端口名在两个分区中方向必须匹配 PERIODIC_WAIT(1)依赖ARINC653分区周期调度,需在分区配置中设置正确的周期值- 采样端口消息大小固定,写入超过端口容量的数据会返回错误
- 接收方使用
READ_SAMPLING_MESSAGE时,若端口无新数据且超时时间到,返回错误码,需根据实际需求处理