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