Сбой при проверке CRC динамического массива байтов | с

Для встроенной системы я пишу код на c для проверки полученного массива байтов на основе предоставленного CRC. Система активна в RTU Modbus.

В моем модульном тесте у меня есть следующий (правильный) массив байтов:

unsigned char frame[7] = { 0x01, 0x04, 0x02, 0x03, 0xFF, 0x80, 0xF9 }

Последние два байта — это предоставленный код CRC, который я хочу проверить.

Мой подход состоит в том, чтобы разделить полученный массив на два массива. Первый массив имеет длину n-2, а второй массив имеет длину 2. После этого создайте свой собственный код CRC на основе первого массива, и, наконец, я хочу проверить, совпадают ли второй массив и мой собственный код CRC.

Это код, который у меня есть прямо сейчас:

bool validateCrc16ModbusFrame(unsigned char frame[])
{
   // A valid response frame consists of at least 6 bytes.
   size_t size = sizeof frame;  
   if (size < 6) {
       return false;
   }

   // Split the frame into the 'bytes to check' and the 'provided CRC.'
   int newSize = size - 2;
   unsigned char* bytesToCheck = (unsigned char*)_malloca(newSize + 1); // Not sure about this line.
   char providedCrc[2];
   memcpy(bytesToCheck, frame, newSize * sizeof(int));
   memcpy(providedCrc, &frame[newSize], 2 * sizeof(int));

   // Calculate the CRC with the bytes to check.
   uint16_t calculatedCrc = calculateCrc16Modbus(bytesToCheck, newSize); // This function calculates the correct CRC code.
   _freea(bytesToCheck); // Not sure about this line.

   // The CRC is provided as two uint8_t bytes. Convered the two uint8_t to one uint16_t.
   uint8_t firstByteProvidedCrc = providedCrc[0];
   uint8_t secondByteProvidedCrc = providedCrc[1];
   uint16_t uint16ProvidedCrc = ((uint16_t)firstByteProvidedCrc << 8) | secondByteProvidedCrc;

   // Compare the provided CRC and the calculated CRC.
   bool result = uint16ProvidedCrc == calculatedCrc;
   return result;
}

Но когда я запускаю тестовый код, он вылетает с сообщением '!! Этот тест, вероятно, РАЗБИЛСЯ !!' Когда я отлаживаю тестовый код, я получаю исключение с сообщением «TestProjectName.exe вызвал точку останова». Я думаю, что проблема возникает из-за создания и/или освобождения памяти для динамического массива байтов.

Кто-нибудь знает, что я делаю неправильно?

Заранее спасибо.

С уважением, Френк


person IAmFrenk    schedule 22.10.2019    source источник


Ответы (1)


Проблема в том, что вызовы memcpy умножают размер newsize на sizeof(int), когда выделены только символы newsize+1. Вероятно, они должны быть:

   memcpy(bytesToCheck, frame, newSize);       /* no sizeof(int) */
   memcpy(providedCrc, &frame[newSize], 2);    /* no sizeof(int) */

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

person rcgldr    schedule 23.10.2019
comment
Это решило мою проблему, большое спасибо! Хотя я не понимаю, как вы вычисляете CRC с исходным массивом. Когда я пытаюсь это сделать, я получаю в результате 0x72E2. - person IAmFrenk; 23.10.2019
comment
Похоже, что CRC хранится в обратном порядке. Я думаю, кадр должен быть {... 0xF9 0x80}. Это приводит к тому, что CRC modbus = 0. Вы можете попробовать это с помощью этого онлайн-калькулятора, щелкните CRC16, затем прокрутите вниз и выберите CRC16_MODBUS, затем скопируйте и вставьте 0x01 0x04 0x02 0x03 0xFF 0xF9 0x80, затем щелкните по вычислению CRC, и в результате получится 0x0. - person rcgldr; 23.10.2019
comment
Ах да, теперь я вижу. Спасибо еще раз! - person IAmFrenk; 23.10.2019