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

C 将两个消息结构链接在一起,c,embedded,can-bus,iar,type-punning,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

我有两个稍微不同的结构,我想以某种方式链接最快的结果

这是两种结构:

/** 
  * @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;
/**
*@brief CAN-Tx消息结构定义
*/
类型定义结构
{
uint32_t StdId;/*!<指定标准标识符。
此参数必须是介于Min_Data=0和Max_Data=0x7FF之间的数字*/
uint32\u t ExtId;/*!<指定扩展标识符。
此参数必须是介于Min_Data=0和Max_Data=0x1FFFFFF之间的数字*/
uint32_t IDE;/*!<指定要传输的消息的标识符类型。
此参数可以是@ref can\u Identifier\u Type的值*/
uint32_t RTR;/*!<指定要传输的消息的帧类型。
此参数可以是@ref can\u remote\u transmission\u request的值*/
uint32_t DLC;/*!<指定要传输的帧的长度。
此参数必须是介于Min_Data=0和Max_Data=8之间的数字*/
uint8_t Data[8];/*!<包含要传输的数据。
此参数必须是介于Min_Data=0和Max_Data=0xFF之间的数字*/
}CanTxMsgTypeDef;
/**
*@brief CAN接收消息结构定义
*/
类型定义结构
{
uint32_t StdId;/*!<指定标准标识符。
此参数必须是介于Min_Data=0和Max_Data=0x7FF之间的数字*/
uint32\u t ExtId;/*!<指定扩展标识符。
此参数必须是介于Min_Data=0和Max_Data=0x1FFFFFF之间的数字*/
uint32_t IDE;/*!<指定将接收的消息的标识符类型。
此参数可以是@ref can\u Identifier\u Type的值*/
uint32_t RTR;/*!<指定接收消息的帧类型。
此参数可以是@ref can\u remote\u transmission\u request的值*/
uint32_t DLC;/*!<指定将接收的帧的长度。
此参数必须是介于Min_Data=0和Max_Data=8之间的数字*/
uint8_t Data[8];/*!<包含要接收的数据。
此参数必须是介于Min_Data=0和Max_Data=0xFF之间的数字*/
uint32_t FMI;/*!<指定邮箱中存储的邮件通过的过滤器的索引。
此参数必须是介于Min_Data=0和Max_Data=0xFF之间的数字*/
uint32\u t FIFONumber;/*!<指定接收FIFO编号。
此参数可以是can_FIFO0或can_FIFO1*/
}CanRxMsgTypeDef;
它们是IAR embedded workbench for ARM使用的ST驱动程序的一部分,所以我无法更改它们

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

驱动程序功能(我也不能更改)只允许传输
CanTxMsgTypeDef
类型。所以每次我都需要将
CanRxMsgTypeDef
变量复制到
CanTxMsgTypeDef
变量,这是非常低效的

我正在寻找最快结果的最佳实践,即以最少的拷贝粘贴传输
CanRxMsgTypeDef
数据


请注意,
CanRxMsgTypeDef
只有额外的数据,即在接收的
CanRxMsgTypeDef
变量中已经传输的所有信息。

使用两个
struct
union
,您可以根据以下内容从公共初始部分访问任何成员:

为了简化联合的使用,我们提供了一个特殊的保证:如果联合包含多个共享公共初始序列的结构(请参见下文),并且如果联合对象当前包含其中一个结构,允许在任何地方检查任何接头的公共初始部分,以确保接头完整类型的声明是可见的。如果对应的成员对于一个或多个初始成员的序列具有兼容的类型(对于位字段,具有相同的宽度),则两个结构共享一个公共初始序列

示例代码:

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;
}

使用两个
struct
s的
union
,您可以根据以下内容从公共初始部分访问任意成员:

为了简化联合的使用,我们提供了一个特殊的保证:如果联合包含多个共享公共初始序列的结构(请参见下文),并且如果联合对象当前包含其中一个结构,允许在任何地方检查任何接头的公共初始部分,以确保接头完整类型的声明是可见的。如果对应的成员对于一个或多个初始成员的序列具有兼容的类型(对于位字段,具有相同的宽度),则两个结构共享一个公共初始序列

示例代码:

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;
}

是的,这是正确的解决方案。它甚至允许在不同类型之间进行任意类型转换(类型双关)。最好将接头称为
CanMsgTypeDef
,其具有
rx
tx
部件。或者对于那些没有陷入无法理解的游戏的人:union
can\u msg\u t
、struct
can\u txmsg\u t
和struct
can\u rxmsg\u t
@Lundin,关于名称的好建议
CanMsgTypeDef
-CamelCase应该可以,因为此代码打算使用原始ST库代码和使用CamelCase的类型。谢谢!我会很快检查:)是的,这是正确的解决方案。它甚至允许在不同类型之间进行任意类型转换(类型双关)。最好将接头称为
CanMsgTypeDef
,其具有
rx
tx
部件。或者,对于那些没有陷入难以理解的问题的人:union
can\u msg\u t
,使用str