AUTOSAR COM 如何将Signal 做成Message 发送/接收

本文介绍了解决MBD自解析Message问题的两种方法:一是修改DBC信号类型和长度,二是手动实现数据复制。第一种方法涉及DBC信号结构调整,第二种适用于事件报文,重点在于理解信号处理逻辑和接口调整。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

开发时,可能遇到应用层(MBD)自己解析Message,并不需要Com将Message解析成Signal,这个时候Com以Signal为单位的接口反而会造成困难,下面将介绍如何解决!

两种解决方式

1. 导入DBC后修改Signal的属性

如下图所示,正常的Signal
在这里插入图片描述
修改后的Signal
在这里插入图片描述

这里可以看到,只需要将ComSignalType 修改成UINT8_N,在将SignalLength 修改成这个Message的DLC长度。

1. 实现原理

截取部分代码如下

   if(Type != (uint8)COM_UINT8_N)
    {
        VAR(uint8, AUTOMATIC) SigEndianess;
        SigEndianess = Com_GetValue(GEN,_ENDIANESS,ConstByteValue_u8);

        /* MR12 RULE 11.5 VIOLATION: SignalDataPtr is defined as void pointer in the AUTOSAR specification,
           so suppressing warning "Cast from a pointer to void to a pointer to object". */
        switch(Type)
        {
        case COM_SINT8:
        case COM_UINT8:
            /* Update the Src_Buf with the data i.e typecast the data to uint8*/
            TxNewVal = (Com_SigMaxType)(*(P2CONST(uint8,AUTOMATIC,COM_APPL_DATA))SignalDataPtr);
            break;
        case COM_SINT16:
        case COM_UINT16:
            /* Update the Src_Buf with the data i.e typecast the data to uint16*/
            TxNewVal = (Com_SigMaxType)(*(P2CONST(uint16,AUTOMATIC,COM_APPL_DATA))SignalDataPtr);
            break;
        case COM_BOOLEAN:
            /* Update the Src_Buf with the data i.e typecast the data to the boolean variable*/
            TxNewVal = (Com_SigMaxType)COM_BOOL_TO_UNSIGNED(*(P2CONST(boolean,AUTOMATIC,COM_APPL_DATA))SignalDataPtr);
            break;
        case COM_SINT32:
        case COM_UINT32:
            /* Update the Src_Buf with the data i.e typecast the data to the uint32 variable*/
            TxNewVal = (Com_SigMaxType)(*(P2CONST(uint32, AUTOMATIC, COM_APPL_DATA))SignalDataPtr);
            break;
#ifdef COM_TXSIG_INT64
        case COM_UINT64:
        case COM_SINT64:
            /* Update the Src_Buf with the data i.e typecast the data to the uint64 variable*/
            TxNewVal = *(P2CONST(uint64, AUTOMATIC, COM_APPL_DATA))SignalDataPtr;
            break;
#endif /* #ifdef COM_TXSIG_INT64 */

            /* FC_VariationPoint_START */
#ifdef COM_FLOAT32SUPP
        case COM_FLOAT32:
            /* Convert the float value into 32 bit stream and then pack the value */
            /* MR12 DIR 1.1 VIOLATION: Explicit cast is provided in line with rba_BswSrv_MemCopy() definition.
               But the void pointer is always deferenced to a type, based on the pointers address alignment.
               Hence the alignment warning can safely be ignored. */
            (void)rba_BswSrv_MemCopy( (void *)&TxNewVal, SignalDataPtr, 4 );
            break;
#endif /* #ifdef COM_FLOAT32SUPP */
            /* FC_VariationPoint_END */

        default:
            /**
             * Default case is mandatory in switch syntax. Moreover only AUTOSAR Com defined signal types are allowed
             * to be configured, hence default case is intentionally left empty.
             */
            break;
        }
        /* The signal Endianess is obtained by this macro Com_GetValue(GEN,_ENDIANESS,ConstByteValue_u8)
         * The value of ConstByteValue_u8 must be loaded with TxSigConstPtr->General */
        ConstByteValue_u8 = TxSigConstPtr->General;
        /* FC_VariationPoint_START */
#ifdef COM_TXSIG_FLOAT64SUPP
        if(Type == COM_FLOAT64)
        {
            float64 TxNewVal_f64;

            /* MR12 RULE 11.5 VIOLATION: SignalDataPtr is defined as void pointer in the AUTOSAR specification,
               so suppressing warning "Cast from a pointer to void to a pointer to object". */
            TxNewVal_f64 = *(P2CONST(float64, AUTOMATIC, COM_APPL_DATA))SignalDataPtr;

            /* Convert the float value into 32 bit stream and then pack the value */
/*            Com_PackFloatSignal(TxSigConstPtr->General.Endianess,TxSigConstPtr->Bit_Pos,
                    TxNewVal_f64, TxIPduConstPtr->BuffPtr); */
            Com_PackFloatSignal(SigEndianess, TxSigConstPtr->Bit_Pos, TxNewVal_f64, TxIPduConstPtr->BuffPtr);
        }
        else
#endif /* #ifdef COM_TXSIG_FLOAT64SUPP */
    /* FC_VariationPoint_END */
        {
/*             Com_PackSignal(TxSigConstPtr->General.Endianess,
                    TxSigConstPtr->Bit_Pos, TxSigConstPtr->BitSize,
                    TxNewVal,TxIPduConstPtr->BuffPtr); */
            Com_PackSignal(SigEndianess, TxSigConstPtr->Bit_Pos, TxSigConstPtr->BitSize, TxNewVal,
                           TxIPduConstPtr->BuffPtr);
        }
    }
    else
    {
        /* Find the ByteNo_u8 of the IPDU buffer */
        ByteNo_u8 = (PduLengthType)(TxSigConstPtr->Bit_Pos >> 3u);
        /* The locks inside the function Com_ByteCopy() are removed.
         * Hence locks are used here
         */
        /* MR12 RULE 11.5 VIOLATION: SignalDataPtr is defined as void pointer in the AUTOSAR specification,
           so suppressing warning "Cast from a pointer to void to a pointer to object". */
        Com_ByteCopy((TxIPduConstPtr->BuffPtr + ByteNo_u8),(const uint8*)SignalDataPtr,(uint32)TxSigConstPtr->BitSize);

    }
    SchM_Exit_Com_TxIpduProtArea(SENDSIGNAL);

可以看到,首先对发送的Signal进行了Type的判断,如果是UINT8_N类型,那么将拷贝指定长度到Buffer中

2. 实现接口

发送Signal接口如下,前面提到通过修改Signal的Type为UINT8_N,就可以填充指定的长度,因此只需要将报文的第一个Signal修改成UINT8_N,并且将该Signal的ComSignalLength修改成报文DLC的长度,最后使用这个Signal的ID直接发送整个报文Buffer的指针
如下所示

void Com_SendMsg_AXX(void *pMessagBuff)
{
	Com_SendSignal(ComSignal_BXX_AXX, pMessagBuff);
}

在这里插入图片描述

注意这里必须使用Message的第一个Signal,也就是Bitpostion为0的Signal,因为数据拷贝的时候是有偏移的
在这里插入图片描述

2. 手动实现

实际上周期报文的发送,都是将Signal的值打包填充到报文的Buffer中,然后Com在该报文的发送Tick计数到之后执行发送动作,将PduInfo传递到CanIf模块,因此也可以手动实现拷贝数据到指定的Buffer中。
在Com_PBCfg文件中,PDUID是直接与发送Buffer相关联的,如下图所示

在这里插入图片描述

总结

第一种方式,需要在导入DBC后调整部分Signal的配置(可以是配置或者直接修改生成的代码)
第二种方式,不需要修改任何配置,但是手动实现的接口只是将数据拷贝到Buffer中,对于事件型报文(非周期报文)实际上无法触发发送

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值