Связывание двух структур сообщений - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть две слегка отличающиеся структуры, которые я хотел бы как-то связать для самых быстрых результатов.

Это две структуры:

/** 
  * @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;

Они являются частью драйверов ST, используемых вВ IAR встроен верстак для ARM, поэтому я не могу их изменить.

Моя функция в основном выполняет фильтрацию, что означает, что все, что я получаю, мне нужно передавать почти сразу.

Функции драйвера (которыеЯ тоже не могу изменить) разрешить только передачу CanTxMsgTypeDef типов.Поэтому каждый раз мне нужно скопировать переменную CanRxMsgTypeDef в переменную CanTxMsgTypeDef, что очень неэффективно.

Я ищу наилучшую практику для получения самых быстрых результатов, например, для передачи CanRxMsgTypeDef данных с минимальным копированием-вставкой.

Обратите внимание, что CanRxMsgTypeDef имеет только дополнительные данные, то есть всю информацию для передачи ужев полученной переменной CanRxMsgTypeDef.

1 Ответ

0 голосов
/ 20 ноября 2018

Используйте 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;
}
...