1553B板卡详解

个人博客地址: https://cxx001.gitee.io

简介

1553b板卡主要应用于航天航空工业领域,它的数据传输结构有点类似集中分布式服务器的设计,分为BC、RT、BM三类部件,BC有且仅有1个,类似我们的master管理服务节点,RT有0~32个,类似我们的各业务服务节点,BM则是监控节点。所以按传统服务器设计结构也很好理解1553B了。

环境安装

  1. 安装驱动,驱动盘里有个imsk的脚本执行一下就好了,需要注意的是驱动版本一定要与板卡一致。

  2. 接线,各通道的线通过耦合器连到一起就可以了。

    在这里插入图片描述

模拟工具

在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有任何疑问欢迎留言交流~~

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值