将两个消息结构链接在一起

时间:2018-11-20 08:54:39

标签: c embedded can-bus iar type-punning

我有两个略有不同的结构,我想以某种方式链接以获得最快的结果。

这是两种结构:

/** 
  * @brief  CAN Tx message structure definition  
  */
typedef struct
{
  uint32_t StdId;    /*!< Specifies the standard identifier.
                          This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF */

  uint32_t ExtId;    /*!< Specifies the extended identifier.
                          This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF */

  uint32_t IDE;      /*!< Specifies the type of identifier for the message that will be transmitted.
                          This parameter can be a value of @ref CAN_Identifier_Type */

  uint32_t RTR;      /*!< Specifies the type of frame for the message that will be transmitted.
                          This parameter can be a value of @ref CAN_remote_transmission_request */

  uint32_t DLC;      /*!< Specifies the length of the frame that will be transmitted.
                          This parameter must be a number between Min_Data = 0 and Max_Data = 8 */

  uint8_t Data[8];   /*!< Contains the data to be transmitted.
                          This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */

}CanTxMsgTypeDef;

/**
  * @brief  CAN Rx message structure definition
  */
typedef struct
{
  uint32_t StdId;       /*!< Specifies the standard identifier.
                             This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF */

  uint32_t ExtId;       /*!< Specifies the extended identifier.
                             This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF */

  uint32_t IDE;         /*!< Specifies the type of identifier for the message that will be received.
                             This parameter can be a value of @ref CAN_Identifier_Type */

  uint32_t RTR;         /*!< Specifies the type of frame for the received message.
                             This parameter can be a value of @ref CAN_remote_transmission_request */

  uint32_t DLC;         /*!< Specifies the length of the frame that will be received.
                             This parameter must be a number between Min_Data = 0 and Max_Data = 8 */

  uint8_t Data[8];      /*!< Contains the data to be received.
                             This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */

  uint32_t FMI;         /*!< Specifies the index of the filter the message stored in the mailbox passes through.
                             This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */

  uint32_t FIFONumber;  /*!< Specifies the receive FIFO number.
                             This parameter can be CAN_FIFO0 or CAN_FIFO1 */

}CanRxMsgTypeDef;

它们是ARM的IAR嵌入式工作台上使用的ST驱动程序的一部分,因此我无法更改它们。

我的功能主要是进行过滤,这意味着无论收到什么,我都需要立即发送。

驱动程序功能(我也不能更改)仅允许传输CanTxMsgTypeDef类型。因此,每次我需要将CanRxMsgTypeDef变量复制到CanTxMsgTypeDef变量中时,效率很低。

我正在寻找获得最快结果的最佳做法,即以最少的复制粘贴来传输CanRxMsgTypeDef数据。

请注意,CanRxMsgTypeDef仅具有额外的数据,即已在接收到的CanRxMsgTypeDef变量处传输的所有信息。

1 个答案:

答案 0 :(得分:6)

使用两个union中的struct,您可以按照6.5.2.3p6从公共初始部分访问任何成员:

  

为了简化并集的使用,做出了一项特殊保证:如果并集包含几个共享相同初始序列的结构(请参见下文),并且如果并集对象当前包含这些结构之一,则允许在可以看到联合完成类型的声明的任何地方检查其中任何一个的公共初始部分。如果相应的成员对一个或多个初始成员的序列具有兼容的类型(对于位域,则具有相同的宽度),则两个结构共享一个公共的初始序列。

示例代码:

union common
{
    CanRxMsgTypeDef rx;
    CanTxMsgTypeDef tx;
};

void someFunc(CanTxMsgTypeDef arg)
{
    printf("inside func tx.StdId=%d\n",arg.StdId);
    printf("inside func tx.DLC=%d\n",arg.DLC);
}

int main()
{
    /* Assign RX type to the union */
    union common test = {1,2,3,4,5,{0,0,0,0,0,0,0,0},7,8};

    printf("test.tx.StdId=%d\n",test.tx.StdId);
    printf("test.rx.StdId=%d\n",test.rx.StdId);
    printf("test.tx.DLC=%d\n",test.tx.DLC);
    printf("test.rx.DLC=%d\n",test.rx.DLC);
    printf("test.rx.FMI=%d\n",test.rx.FMI);

    /* Use the union as tx type */
    someFunc(test.tx);
    return 0;
}