前言
开发时,可能遇到应用层(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中,对于事件型报文(非周期报文)实际上无法触发发送