Декодирование нескольких сообщений методом CAN-шины - PullRequest
1 голос
/ 25 июня 2019

У меня есть сообщение по шине CAN, которое состоит из 3 частей. Каков наилучший способ его расшифровки?

Я думаю использовать 3 FIFO, когда первая часть декомпозирована, я сохраняю ее в FIFO, и то же самое для двух других частей.

Затем я объединяю эти три Fifos в одно сообщение.

Общая длина сообщения составляет 64 байта. Длина PDU

Я использую следующую функцию для получения данных шины CAN

HAL_CAN_GetRxMessage

может автобус

Ответы [ 2 ]

0 голосов
/ 25 июня 2019

Используя ответ на свой предыдущий вопрос из здесь , вы можете использовать это битовое поле в сочетании с простым uint8_t [64]. Например

typedef struct
{
  uint8_t data[64];
  can_received_t received;
} msg_t;

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

Очередь / FIFO выполняет только одну цель: отложить выполнение чего-либо до более позднего времени, когда будет больше времени. Нет причин делать это здесь. Ваше декодирование CAN сообщения может выглядеть примерно так:

msg_t msg;

switch(received_can_id)
{
  ...
  case CANID_FOO:  
    memcpy(&msg.data[FOO_INDEX], rec_data, FOO_SIZE);
    msg.received |= RECEIVED_FOO;
    break;

  case CANID_BAR:
    memcpy(&msg.data[BAR_INDEX], rec_data, BAR_SIZE);
    msg.received |= RECEIVED_BAR;
    break;
  ...
}

if(msg.received == RECEIVED_ALL)
{
  use(&msg); // do something
  memset(&msg, 0, sizeof msg); // reset everything
}

Это довольно быстрый код, не нужно ничего ставить в очередь.

0 голосов
/ 25 июня 2019

Учитывая, что стандартное сообщение CAN имеет длину 8 байтов, вы можете объявить сообщение как uin64_t и объединить соответствующие сигналы в сообщение, используя |.

Пример:

uint64_t message = 0;
uint8_t incomingBytes[8] = {0};

for(int i=0; i<8; i++)
{
    message = message <<8;
    message |= incomingBytes[i];
}

Если вы хотите интерпретировать данные VIN как string, тогда

 char vindata [9];
 memcpy(vindata, incomingBytes, 8);
 vindata[8] = '\0';
...