个人博客地址: https://cxx001.gitee.io
简介
1553b板卡主要应用于航天航空工业领域,它的数据传输结构有点类似集中分布式服务器的设计,分为BC、RT、BM三类部件,BC有且仅有1个,类似我们的master管理服务节点,RT有0~32个,类似我们的各业务服务节点,BM则是监控节点。所以按传统服务器设计结构也很好理解1553B了。
环境安装
-
安装驱动,驱动盘里有个imsk的脚本执行一下就好了,需要注意的是驱动版本一定要与板卡一致。
-
接线,各通道的线通过耦合器连到一起就可以了。
模拟工具
在windows上提供了一个测试工具,FlightPack-1553B
可以与自己封装的1553B模块对测。
BC设置,我一般用的子帧模式,添加需要的消息,主要是BC有些设置,其它基本没什么要设置的,像RT基本就是使能下就可以了。
模块封装
RT封装倒是比较简单,直接参考示例程序就行了,没什么特别的,主要是BC的封装,有几个点需要注意,它是一个管理类,消息个数是可以动态添加的,而且默认子帧模式,消息有开始和结束形成一个环。还一点特别注意在设置RT->RT消息时,消息块的cmd_wd1
字段只能是接收,cmd_wd2
只能是发送。
1. RT
#include "CtrlSysLibTool.h"
#include "Port_1553B_RT.h"
#ifdef WIN32
#include <windows.h>
#endif
#include "json.hpp"
#include "kl_common_info.h"
#include <stdio.h>
#include <string.h>
struct CAV1553B_RT_INFO {
CAV1553B_RT_INFO(CORE_U16 dev_num, CORE_U32 channel_num, CORE_U16 rt_addr, CORE_U16 sub_addr)
: dev_num_(dev_num), channel_num_(channel_num), rt_addr_(rt_addr), sub_addr_(sub_addr)
{
memset(&rt_sabuf_, 0, sizeof(rt_sabuf_));
rt_sabuf_.legal_wc = 0xFFFFFFFF;
data_size_ = sizeof(rt_sabuf_.data_wds);
}
CORE_RT_SA_BUFFER rt_sabuf_; // rt读写buffer
int data_size_; // data_wds数据的长度,这里会默认32个CORE_U16(unsigned short)
CORE_U16 dev_num_; // 设备号
CORE_U32 channel_num_; // 通道号
CORE_U16 rt_addr_; // RT 地址,取值范围 0~31;
CORE_U16 sub_addr_; // RT 子地址,取值范围 0~31;
std::map<std::pair<CORE_U16, CORE_U32>, bool>
*init_info_1553b_; // 记录通道初始化情况,相同的dev_num及channel_num只初始化一次
std::vector<std::string> vars; // 存储协议字段的类型
};
/***********************************
内部变量初始化
内部变量:rtinfo_
***********************************/
int32_t Block_Port_1553B_RT::initInternalVariable()
{
LOG_INFO("CAV1553BInit start...\n");
// Devnum 由设备编号和 1553 板卡类型组成。其中:
// 1)设备编号:设备编号(从 0 开始编号),取值范围 0~3。
// 2)1553 板卡类型:
// devnum = (0 | PCI_1553_TYPE),代表的是 PCI1553 板卡,设备 0;
// devnum = (1 | PCI_1553_TYPE),代表的是 PCI1553 板卡,设备 1;
// devnum = (0 | USB_1553_TYPE),代表的是 USB1553 板卡,设备 0;
// devnum = (1 | USB_1553_TYPE),代表的是 USB1553 板卡,设备 1。
CORE_U16 dev_num = (CORE_U16)P(devNum) | PCI_1553_TYPE;
CORE_U32 channel_num = P(channelNum);
CORE_U16 rt_addr = P(rtAddr);
CORE_U16 sub_addr = P(subAddr);
rtinfo_ = new CAV1553B_RT_INFO(dev_num, channel_num, rt_addr, sub_addr);
CAV1553B_RT_INFO *rtinfo = static_cast<CAV1553B_RT_INFO *>(rtinfo_);
rtinfo->init_info_1553b_ = GetInitInfo_1553b();
auto iter = rtinfo->init_info_1553b_->find({ dev_num, channel_num });
// 没有找到,或者找到了但是为false,则表示未初始化,那么进行相关初始化操作
if (iter == rtinfo->init_info_1553b_->end()) {
// 该函数用于初始化某一个板卡的通道。三个参数分别为:设备号、通道号、中断队列长度(取值:4,8,16,32,64,128,256。)
// SUCCESS:设备初始化成功;FAILURE:设备初始化失败。
if (FAILURE == CORE_GEN_Full_Init(dev_num, channel_num, 16)) {
return false;
}
LOG_INFO("CORE_GEN_Full_Init finished...\n");
// CORE_RT_Multiple_Is_Supported 用于查看板卡是否支持多 RT 功能。
// 1:支持多 RT;0:不支持多 RT。
int multiple = CORE_RT_Multiple_Is_Supported(dev_num, channel_num);
if (!multiple && rt_addr > 0) {
LOG_ERROR("not support multiple,channel_num = %d\n", (int)channel_num);
return false;
}
LOG_INFO("CORE_RT_Multiple_Is_Supported finished...\n");
// CORE_RT_Init 用于初始化板卡中的 RT 功能,进行 RT 内存分配,在用 RT 功能之前,需要调用此函数。
// SUCCESS:RT 初始化成功;FAILURE:RT 初始化失败。
if (FAILURE == CORE_RT_Init(dev_num, channel_num)) {
LOG_ERROR("Initializing RT Failure,channel_num = %d\n", (int)channel_num);
return false;
}
rtinfo->init_info_1553b_->insert({ { dev_num, channel_num }, true });
LOG_INFO("CORE_RT_Init finished...\n");
}
// CORE_RT_Enable 用来使能某一特定的 RT 地址,使其有效。使用任何 RT 之前都需要使能这个 RT 地址,否则 RT
// 将不工作。
CORE_RT_Enable(dev_num, channel_num, rt_addr);
// CORE_RT_Allocate_SA_Buffers 为特定的 RT 的子地址分配一个或者多个缓冲区,用于存储相关数据
// SUCCESS:RT 缓冲分配成功;FAILURE:RT 缓冲分配失败。
// devnum:见上面注释;
// channel_num:通道编号(从 0 开始编号),取值范围 0~3;
// rt:RT 地址,取值范围 0~31;
// tr:发送还是接收。 1:发送;0:接收;
// sa:RT 子地址,取值范围 0~31;
// num_bufs:要分配多少个缓冲 buffer。
CORE_U16 tr = 0;
if (P(bsend)) {
tr = 1;
}
if (FAILURE == CORE_RT_Allocate_SA_Buffers(dev_num, channel_num, rt_addr, tr, sub_addr, 1)) {
LOG_ERROR("Allocating Failure,channel_num = %d\n", (int)channel_num);
return false;
}
LOG_INFO("CORE_RT_Allocate_SA_Buffers finished...\n");
if (FAILURE == CORE_RT_Write_SA_Buffer(dev_num, channel_num, rt_addr, tr, sub_addr, 0, &rtinfo->rt_sabuf_)) {
return false;
}
// CORE_RT_Start运行已经配置好的 RT 。
CORE_RT_Start(dev_num, channel_num);
/*****************************解析协议json文件, 将协议字段的类型放入数组中***********************/
nlohmann::ordered_json root;
#ifdef _WIN32
std::ifstream(P(filename).c_str()) >> root;
#else
std::string strfilePath = P(filename).c_str();
std::string strfile = "protocol/" + strfilePath.substr(strfilePath.find_last_of("/") + 1);
if (access(strfile.c_str(), F_OK) == -1) {
return false;
}
std::ifstream(strfile.c_str()) >> root;
#endif
nlohmann::ordered_json child = root["Protocol fields"];
for (auto &item : child.items()) {
rtinfo->vars.push_back(item.value()["type"]);
// std::string tp = item.value()["type"];
// LOG_ERROR("type=%s\n", tp.c_str());
}
bool bi = P(bsend) && I(p_dynamic_Input_).size_ != rtinfo->vars.size();
bool bo = !P(bsend) && O(p_dynamic_Output_).size_ != rtinfo->vars.size();
if (bi || bo) {
// 如果动态输入端口的个数与协议字段的个数不一致则有错误
return false;
}
binit_ = true; // 标识已完成初始化
LOG_INFO("CAV1553BInit success...\n");
return true;
}
/**********************************
在此函数中编写自定义代码
输入变量:
输出变量:
参数:bsend, channelNum, devNum, filename, rtAddr, subAddr
状态变量:
示例:O(输出变量) = I(输入变量) + P(参数)
***********************************/
void Block_Port_1553B_RT::runAlgorithm(void *extra)
{
CAV1553B_RT_INFO *rtinfo = static_cast<CAV1553B_RT_INFO *>(rtinfo_);
//memset(&rtinfo->rt_sabuf_, 0, sizeof(rtinfo->rt_sabuf_)); // 清空上次数据
if (P(bsend)) {
// 作为发送模块
size_t offset = 0;
for (size_t i = 0; i < rtinfo->vars.size(); i++) {
if (1 == P(checkType) && i == rtinfo->vars.size() - 1) {
// checkType==1时为crc校验
uint16_t crc = get_crc16((uint8_t *)rtinfo->rt_sabuf_.data_wds, offset);
memcpy(rtinfo->rt_sabuf_.data_wds + offset, &crc, sizeof(uint16_t));
offset += sizeof(uint16_t);
}
size_t var_len = type_len(rtinfo->vars[i]);
convert_var_to_buffer(rtinfo->vars[i], offset, (uint8_t *)rtinfo->rt_sabuf_.data_wds,
I(p_dynamic_Input_).ptr_[i], var_len);
offset += var_len;
}
// 不能超过缓存大小
if (offset <= rtinfo->data_size_) {
if (SUCCESS
== CORE_RT_Write_SA_Buffer(rtinfo->dev_num_, rtinfo->channel_num_, rtinfo->rt_addr_, 1,
rtinfo->sub_addr_, 0, &rtinfo->rt_sabuf_)) { }
}
} else {
// 作为接收模块
if (SUCCESS
== CORE_RT_Read_SA_Buffer(rtinfo->dev_num_, rtinfo->channel_num_, rtinfo->rt_addr_, 0, rtinfo->sub_addr_, 0,
&rtinfo->rt_sabuf_)) {
size_t offset = 0;
for (size_t i = 0; i < rtinfo->vars.size(); i++) {
if (1 == P(checkType) && i == rtinfo->vars.size() - 1) {
// checkType==1时为crc校验
uint16_t crc = get_crc16((uint8_t *)rtinfo->rt_sabuf_.data_wds, offset); // 先计算自己的crc
uint16_t *recv_crc = (uint16_t *)(rtinfo->rt_sabuf_.data_wds + offset); // 解析收到数据包的crc字段
if (crc != *recv_crc) {
// 错误信息
}
offset += sizeof(uint16_t);
}
size_t var_len = type_len(rtinfo->vars[i]);
*O(p_dynamic_Output_).ptr_[i] =
convert_buffer_to_var(rtinfo->vars[i], offset, (uint8_t *)rtinfo->rt_sabuf_.data_wds);
offset += var_len;
}
}
}
}
/**********************************
在此函数中编写自定义积分函数
***********************************/
int32_t Block_Port_1553B_RT::integral(int32_t msg, double t, double *state, double *derivative)
{
return 0;
}
/**********************************
在此函数中释放内部变量资源
内部变量:rtinfo_
***********************************/
void Block_Port_1553B_RT::destroyInternalVariable()
{
// 是否调用了初始化函数,默认为false(控制引擎会出现直接调用destroy的情况,而成员变量si_未初始化被使用会导致崩溃)
if (!binit_) {
return;
}
CAV1553B_RT_INFO *rtinfo = static_cast<CAV1553B_RT_INFO *>(rtinfo_);
CORE_RT_Disable(rtinfo->dev_num_, rtinfo->channel_num_, rtinfo->rt_addr_);
auto iter = rtinfo->init_info_1553b_->find({ rtinfo->dev_num_, rtinfo->channel_num_ });
if (iter == rtinfo->init_info_1553b_->end() || !iter->second) {
CORE_RT_Stop(rtinfo->dev_num_, rtinfo->channel_num_);
}
delete rtinfo;
}
2. BC
#include "CtrlSysLibTool.h"
#include "Port_1553B_BC.h"
#ifdef WIN32
#include <windows.h>
#endif
#include "json.hpp"
#include "kl_common_info.h"
#include <stdio.h>
#include <string.h>
struct CAV1553B_BC_INFO {
CAV1553B_BC_INFO(CORE_U16 dev_num, CORE_U32 channel_num, doubleVector& rt_addr, doubleVector& sub_addr, doubleVector& msg_type)
: dev_num_(dev_num)
, channel_num_(channel_num)
, init_info_1553b_(nullptr)
{
memset(&bc_sabuf_, 0, sizeof(bc_sabuf_));
data_size_ = sizeof(bc_sabuf_.data_wds);
for (int i = 0; i < 32; i++) {
rt_addr_[i] = (CORE_U16)rt_addr[i];
sub_addr_[i] = (CORE_U16)sub_addr[i];
msg_type_[i] = (CORE_U16)msg_type[i];
}
}
CORE_BC_MSG_BUFFER bc_sabuf_; // bc读写buffer
int data_size_; // data_wds数据的长度,这里会默认32个CORE_U16(unsigned short)
CORE_U16 dev_num_; // 设备号
CORE_U32 channel_num_; // 通道号
CORE_U16 rt_addr_[32]; // RT 地址,取值范围 0~31;
CORE_U16 sub_addr_[32]; // RT 子地址,取值范围 0~31;
CORE_U16 msg_type_[32]; // BC消息类型,如rt->bc,bc->rt,rt->rt
std::map<std::pair<CORE_U16, CORE_U32>, bool>* init_info_1553b_; // 记录通道初始化情况,相同的dev_num及channel_num只初始化一次
std::vector<std::vector<std::string>> bc_rt_vars; // 存储bc->rt协议字段的类型
std::vector<std::vector<std::string>> rt_bc_vars; // 存储rt->bc协议字段的类型
std::vector<int> bc_rt_nums; // bc->rt消息个数
std::vector<int> rt_bc_nums; // rt->bc消息个数
};
/***********************************
内部变量初始化
内部变量:bcinfo_
***********************************/
int32_t Block_Port_1553B_BC::initInternalVariable()
{
LOG_INFO("CAV1553B_BC_Init start...\n");
// Devnum 由设备编号和 1553 板卡类型组成。其中:
// 1)设备编号:设备编号(从 0 开始编号),取值范围 0~3。
// 2)1553 板卡类型:
// devnum = (0 | PCI_1553_TYPE),代表的是 PCI1553 板卡,设备 0;
// devnum = (1 | PCI_1553_TYPE),代表的是 PCI1553 板卡,设备 1;
// devnum = (0 | USB_1553_TYPE),代表的是 USB1553 板卡,设备 0;
// devnum = (1 | USB_1553_TYPE),代表的是 USB1553 板卡,设备 1。
CORE_U16 dev_num = (CORE_U16)P(devNum) | PCI_1553_TYPE;
CORE_U32 channel_num = (CORE_U32)P(channelNum);
bcinfo_ = new CAV1553B_BC_INFO(dev_num, channel_num, P(rtAddr), P(subAddr), P(msgType));
CAV1553B_BC_INFO* bcinfo = static_cast<CAV1553B_BC_INFO*>(bcinfo_);
bcinfo->init_info_1553b_ = GetInitInfo_1553b();
size_t block_count = P(msgType).size();
auto iter = bcinfo->init_info_1553b_->find({ dev_num, channel_num });
// 没有找到,或者找到了但是为false,则表示未初始化,那么进行相关初始化操作
if (iter == bcinfo->init_info_1553b_->end() || !iter->second) {
// 该函数用于初始化某一个板卡的通道。三个参数分别为:设备号、通道号、中断队列长度(取值:4,8,16,32,64,128,256。)
// SUCCESS:设备初始化成功;FAILURE:设备初始化失败。
if (FAILURE == CORE_GEN_Full_Init(dev_num, channel_num, 16)) {
return false;
}
LOG_INFO("CORE_GEN_Full_Init finished...\n");
/*
CORE_BC_Is_Supported 查看板卡是否支持 BC 功能。
1:支持 BC;
0:不支持 BC
*/
int surportBC = CORE_BC_Is_Supported(dev_num, channel_num);
if (!surportBC) {
LOG_ERROR("not support BC,channel_num = %d\n", (int)channel_num);
return false;
}
LOG_INFO("CORE_BC_Is_Supported finished...\n");
/*
CORE_BC_Init 用于初始化板卡中的 BC 功能,设置 BC 需要发送的消息个数
devnum:设备号;
channel_num:通道编号(从 0 开始编号),取值范围 0~3;
num_blocks:所需建立的 BC BLOCK 的个数;
frame_us:以 us 为单位的子帧时间间隔,取值范围 40~0xFFFFFFFF;
wTimeout1:无响应时间,单位 us,取值范围 0~31。当 wTimeout1 和 wTimeout2都为 0
时为不设置延时时间,使用系统默认时间); wTimeout2:最迟响应时间,单位 us,取值范围 0~31。(当 wTimeout1 和
wTimeout2都为 0 时为不设置延时时间,使用系统默认时间)
*/
if (CORE_BC_Init(dev_num, channel_num, block_count, 100000, 0, 0) == FAILURE) {
LOG_ERROR("Initializing BC Failure,channel_num = %d\n", (int)channel_num);
return false;
}
LOG_INFO("CORE_BC_Init finished...\n");
} else {
LOG_ERROR("BC is Initializing\n");
return false;
}
CORE_BC_BLOCK bc_block;
for (int i = 0; i < block_count; i++) {
/*
CORE_BC_Allocate_Msg_Buffers 为特定的 BC Block 分配 Message Buffers。
devnum:设备号;
channel_num:通道编号(从 0 开始编号),取值范围 0~3;
msg_num:BC Block 编号(需要为哪个 BLOCK 分配消息);
num_buffs:所需分配的消息的个数,默认值为 1。
*/
if (CORE_BC_Allocate_Msg_Buffers(dev_num, channel_num, i, 1) == FAILURE) {
LOG_ERROR("CORE_BC_Allocate_Msg_Buffers Failure,channel_num = %d\n", (int)channel_num);
return false;
}
memset(&bc_block, 0, sizeof(bc_block));
int bcMsgType = (int)P(msgType)[i];
if (0 == i) {
bc_block.next_msg_num = i + 1;
bc_block.bc_control_wd = bcMsgType | BC_BLOCK_FRAME_BEGIN | BC_BLOCK_FLAG_BUS_A;
} else if (block_count - 1 == i) {
bc_block.next_msg_num = 0;
bc_block.bc_control_wd = bcMsgType | BC_BLOCK_FRAME_END | BC_BLOCK_FLAG_BUS_A;
} else {
bc_block.next_msg_num = i + 1;
bc_block.bc_control_wd = bcMsgType | BC_BLOCK_FLAG_BUS_A;
}
/*
CORE_Set_BC_Command 组合 MIL-STD-1553B BC 的命令字。
devnum:设备号
channel_num:通道编号(从 0 开始编号),取值范围 0~3;
RT:RT 地址,取值范围 0~31;
tr:发送还是接收。1 代表发送,0 代表接收;
data_count:数据字个数,取值范围:0~31(0 代表 32 个字);
如果消息是 ModeCode 类型,data_count 代表的是模式代码。
subaddr:RT 子地址,取值范围 0~31
*/
if (bcMsgType == BC_BLOCK_TYPE_MSG_RTRT) {
// 当消息类型为RT->RT时,接收的RT必须设置到cmd_wd1中,发送的RT设置到cmd_wd2中
if (0 == P(rtType)[i]) {
bc_block.cmd_wd1 = CORE_Set_BC_Command(dev_num, channel_num, P(rtAddr)[i], P(rtType)[i], 0, P(subAddr)[i]);
bc_block.cmd_wd2 = CORE_Set_BC_Command(dev_num, channel_num, P(rtAddr)[i + 1], P(rtType)[i + 1], 0, P(subAddr)[i + 1]);
} else {
bc_block.cmd_wd1 = CORE_Set_BC_Command(dev_num, channel_num, P(rtAddr)[i + 1], P(rtType)[i + 1], 0, P(subAddr)[i + 1]);
bc_block.cmd_wd2 = CORE_Set_BC_Command(dev_num, channel_num, P(rtAddr)[i], P(rtType)[i], 0, P(subAddr)[i]);
}
} else {
bc_block.cmd_wd1 = CORE_Set_BC_Command(dev_num, channel_num, P(rtAddr)[i], P(rtType)[i], 0, P(subAddr)[i]);
}
bc_block.im_gap = 10;
/*
CORE_BC_Write_Block 函数将用户设置好的 BC BLOCK,通过向 API 函数传入结构体的方式写到板卡内存中。
devnum:设备号;
channel_num:通道编号(从 0 开始编号),取值范围 0~3;
msg_num:BC BLOCK 编号(需要为哪个 BLOCK 分配消息);
bc_block:需设置的 BC BLOCK 结构体
*/
if (CORE_BC_Write_Block(dev_num, channel_num, i, &bc_block) == FAILURE) {
LOG_ERROR("CORE_BC_Write_Block Failure,channel_num = %d\n", (int)channel_num);
return false;
}
if (bcMsgType == BC_BLOCK_TYPE_MSG_BCRT) {
/*
CORE_BC_Write_Buffer 函数将用户设置好的 BC BLOCK 对应的消息,通过向API 函数传入结构体的方式写到板卡内存中
devnum:设备号
channel_num:通道编号(从 0 开始编号),取值范围 0~3;
msg_num:BC BLOCK 编号(需要为哪个 BLOCK 分配消息); // 指定分配的通道
buffnum:BC BLOCK 对应的消息编号;
msg_buff:需设置的 CORE_BC_MSG_BUFFER 结构体的指针。
*/
if (CORE_BC_Write_Buffer(dev_num, channel_num, i, 0, &bcinfo->bc_sabuf_) == FAILURE) { // 这里自定义一个编号吧
LOG_ERROR("CORE_BC_Write_Buffer Failure,channel_num = %d\n", (int)channel_num);
return false;
}
bcinfo->bc_rt_nums.push_back(i);
} else if (bcMsgType == BC_BLOCK_TYPE_MSG_RTBC) {
bcinfo->rt_bc_nums.push_back(i);
}
}
// CORE_BC_Start 运行已经配置好的 BC
CORE_BC_Start(dev_num, channel_num, 0);
/*****************************解析协议json文件, 将协议字段的类型放入数组中***********************/
nlohmann::ordered_json root;
#ifdef _WIN32
std::ifstream(P(filename).c_str()) >> root;
#else
std::string strfilePath = P(filename).c_str();
std::string strfile = "protocol/" + strfilePath.substr(strfilePath.find_last_of("/") + 1);
if (access(strfile.c_str(), F_OK) == -1) {
return false;
}
std::ifstream(strfile.c_str()) >> root;
#endif
for (const auto& field : root["Protocol fields"]["bc_rt"]) {
std::vector<std::string> innerVector;
for (const auto& subfield : field) {
innerVector.push_back(subfield["type"]);
}
if (innerVector.size() > 0) {
bcinfo->bc_rt_vars.push_back(innerVector);
}
}
for (const auto& field : root["Protocol fields"]["rt_bc"]) {
std::vector<std::string> innerVector;
for (const auto& subfield : field) {
innerVector.push_back(subfield["type"]);
}
bcinfo->rt_bc_vars.push_back(innerVector);
}
binit_ = true; // 标识已完成初始化
LOG_INFO("CAV1553B_BC_Init success...\n");
return true;
}
/**********************************
在此函数中编写自定义代码
输入变量:
输出变量:
参数:bsend, channelNum, devNum, filename, rtAddr, subAddr
状态变量:
示例:O(输出变量) = I(输入变量) + P(参数)
***********************************/
void Block_Port_1553B_BC::runAlgorithm(void* extra)
{
CAV1553B_BC_INFO* bcinfo = static_cast<CAV1553B_BC_INFO*>(bcinfo_);
// BC->RT
size_t pos = 0;
for (size_t i = 0; i < bcinfo->bc_rt_nums.size(); i++) {
size_t offset = 0;
for (size_t j = 0; j < bcinfo->bc_rt_vars[i].size(); j++) {
size_t var_len = type_len(bcinfo->bc_rt_vars[i][j]);
convert_var_to_buffer(bcinfo->bc_rt_vars[i][j], offset, (uint8_t*)bcinfo->bc_sabuf_.data_wds,
I(p_dynamic_Input_).ptr_[pos], var_len);
offset += var_len;
pos++;
}
// 不能超过缓存大小
int msg_num = bcinfo->bc_rt_nums[i];
if (offset <= bcinfo->data_size_) {
if (SUCCESS == CORE_BC_Write_Buffer(bcinfo->dev_num_, bcinfo->channel_num_, msg_num, 0, &bcinfo->bc_sabuf_)) {
}
}
}
// RT->BC
pos = 0;
for (size_t i = 0; i < bcinfo->rt_bc_nums.size(); i++) {
int msg_num = bcinfo->rt_bc_nums[i];
if (SUCCESS == CORE_BC_Read_Buffer(bcinfo->dev_num_, bcinfo->channel_num_, msg_num, 0, &bcinfo->bc_sabuf_)) {
size_t offset = 0;
for (size_t j = 0; j < bcinfo->rt_bc_vars[i].size(); j++) {
size_t var_len = type_len(bcinfo->rt_bc_vars[i][j]);
*O(p_dynamic_Output_).ptr_[pos] = convert_buffer_to_var(bcinfo->rt_bc_vars[i][j], offset, (uint8_t*)bcinfo->bc_sabuf_.data_wds);
offset += var_len;
pos++;
}
}
}
// memset(&bcinfo->bc_sabuf_, 0, sizeof(bcinfo->bc_sabuf_)); // 清空上次数据
}
/**********************************
在此函数中编写自定义积分函数
***********************************/
int32_t Block_Port_1553B_BC::integral(int32_t msg, double t, double* state, double* derivative)
{
return 0;
}
/**********************************
在此函数中释放内部变量资源
内部变量:bcinfo_
***********************************/
void Block_Port_1553B_BC::destroyInternalVariable()
{
// 是否调用了初始化函数,默认为false(控制引擎会出现直接调用destroy的情况,而成员变量si_未初始化被使用会导致崩溃)
if (!binit_) {
return;
}
CAV1553B_BC_INFO* bcinfo = static_cast<CAV1553B_BC_INFO*>(bcinfo_);
auto iter = bcinfo->init_info_1553b_->find({ bcinfo->dev_num_, bcinfo->channel_num_ });
if (iter == bcinfo->init_info_1553b_->end() || !iter->second) {
CORE_BC_Stop(bcinfo->dev_num_, bcinfo->channel_num_);
}
delete bcinfo;
}
3. 测试
测试场景包含BC->RT, RT->BC, RT->RT,下面是我们产品一个BC对应的设置界面。
这里给BC添加了3条消息,分别是bc->rt, rt->bc, rt->rt。它们是一个数组,一一对应,只有msgType字段少一个是因为rt->rt这1条消息有2个rt,还有需要注意rtType字段的收/发是针对rt来的。
最后,时间匆忙,文章整理得比较粗糙,不过上面的两个示例程序是现场正式环境验证通过了的,封装它们是踩了无数的坑过来的。关于1553B有任何疑问欢迎留言交流~~