реклама на сайте
подробности

 
 
> Вычисление CRC
Danis
сообщение Nov 19 2010, 18:19
Сообщение #1


Twilight Zone
***

Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990



Предлагаю в этой теме обсуждать вопросы разработчиков на STM32.


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Danis
сообщение Nov 20 2010, 15:54
Сообщение #2


Twilight Zone
***

Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990



Привет, коллеги по цеху!

Вот сижу, роюсь в периферийной библиотеке STM32.
Интересует аппаратный расчет CRC16 на STM32. Кто нить это использовал? Сейчас я пока пользуюсь только программным расчетом CRC16. Использую следующие функции:

// BYTE – unsigned char
// WORD – 2байта (unsigned short)

// ---------------- функция расчета СRC16 --------------------------------------------------
WORD GetCRC16(BYTE* Buffer, WORD Size)
{
return(GetCRC16Fragment(Buffer, Size, 0));
}
//************************************************************


//----------------------------------------------------------------------------------------------------------

WORD GetCRC16Fragment(BYTE* Buffer, WORD Size, WORD PrevFragmentCRC)
{
WORD crc, i, j;

crc = PrevFragmentCRC;
for (i=0; i<Size; i++)
{
crc ^= Buffer[i] << 8;

for (j=0; j<8; j++)
{
if ((crc & 0x8000) != 0)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
}
}
return(crc);
}
//************************************************************************

Например, в одном из проектов я по SPI (DMA) принимаю из Ethernet контроллера буфер 1472 байта, это максимальный размер данных UDP пакета. Конечно же, чтоб проверить целостность пакета передаю его в функцию GetCRC16. Последние 2 байта пакета содержат его CRC16. Таким образом, при целостности пакета, функция GetCRC16 должна возвратить 0. Все это здорово работает, за минусом того, что на это дело тратиться 3.8 ms процессорного времени. Поэтому заинтересовался аппаратным расчетом CRC. В примерах из стандартной библиотеки нашел функцию:

/**
* @brief Computes the 32-bit CRC of a given buffer of data word(32-bit).
* @param pBuffer: pointer to the buffer containing the data to be computed
* @param BufferLength: length of the buffer to be computed
* @retval 32-bit CRC
*/
uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength)
{
uint32_t index = 0;

for(index = 0; index < BufferLength; index++)
{
CRC->DR = pBuffer[index];
}
return (CRC->DR);
}

Но это как я понимаю CRC32. Можно ли на STM32 аппаратно вычислить CRC16 по полиному 1021? Кто нить пользовался? Насколько аппаратный расчет CRC быстрее считает чем программный? Хочу услышать Ваши мнения. В понедельник приду на работу, тогда уж на железе погоняю….


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post
Serj78
сообщение Nov 20 2010, 18:39
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 966
Регистрация: 27-05-06
Из: СПб
Пользователь №: 17 499



CRC - это вообще-то остаток от деления. В вашей функции оно сильно неэффективно. (сдвигами). Табличная реализация значительно эффективнее.

(Есть замечательный документ "Ross N. Williams
Элементарное руководство
по CRC алгоритмам
обнаружения ошибок
Все, что Вы хотели бы знать о CRC алгоритмах, но боялись спросить,
опасаясь, что ошибки Ваших знаний могут быть обнаружены" -погуглите. )

В даташите указано, что полином аппаратного блока CRC фиксированный :
Uses CRC-32 (Ethernet) polynomial: 0x4C11DB7
– X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 +X8 + X7 + X5 + X4 + X2+ X +1

и изменить его нельзя, увы sad.gif
А было бы здорово, если бы для полинома был отдельный регистр... smile.gif
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Nov 25 2010, 12:52
Сообщение #4


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(Serj78 @ Nov 20 2010, 21:39) *
CRC - это вообще-то остаток от деления. В вашей функции оно сильно неэффективно. (сдвигами). Табличная реализация значительно эффективнее.

Смотря по какому критерию оценивать эффективность.
(скорость/объём)

Цитата(Danis @ Nov 25 2010, 08:56) *
Эта не табличная реализация, медленная, но считает также как STM32 аппаратно. Табличную реализацию пока еще не написал, может кто напишет и выложит?

А в гугле и википедии вас забанили чтоли?


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Danis
сообщение Nov 25 2010, 13:10
Сообщение #5


Twilight Zone
***

Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990



Цитата(MrYuran @ Nov 25 2010, 15:52) *
вас забанили чтоли?


Вопрос не в том, что забанили или нет. Табличную реализацию CRC32 я выложил в теме выше. Но ее переделывать нужно под STM32, а времени на это нет. Если у Вас есть таковая функция или ссылка на нее, то поместите ее тут.


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post
svl
сообщение Nov 25 2010, 19:04
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 20-12-07
Пользователь №: 33 465



Цитата(Danis @ Nov 25 2010, 16:10) *
... Но ее переделывать нужно под STM32, а времени на это нет. Если у Вас есть таковая функция или ссылка на нее, то поместите ее тут.

Что значит переделывать? Это же обычный Си.
Я не совсем Вас понимаю, как в микроконтроллере, с использованием функции, аппаратно посчитать CRC? Ну это уже из темы ALTERA или XILINX.
Go to the top of the page
 
+Quote Post
Danis
сообщение Nov 26 2010, 06:06
Сообщение #7


Twilight Zone
***

Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990



Цитата(svl @ Nov 25 2010, 23:04) *
Что значит переделывать? Это же обычный Си.
Я не совсем Вас понимаю, как в микроконтроллере, с использованием функции, аппаратно посчитать CRC? Ну это уже из темы ALTERA или XILINX.


Маленько уточняю… В STM32 есть аппаратный модуль подсчета CRC32. Если в него передать некий буфер, то в результате он подсчитает CRC32.
Например, из ПК в STM32 передаем некий буфер, предположим 20 байт, в которых 16 байт это непосредственно сам информационный буфер, а последние четыре это CRC32 (рассчитывается в ПК). Дальше аппаратно считаем CRC32 в STM32 (для 16-ти байт) и сравниваем. Вот я и просил выложить табличную функцию расчета CRC32 на Си, которая будет возвращать результат такой же как и аппаратный модуль CRC32 STM32. Таковую функцию на Си я написал, но не табличную (выложил выше - STM32_SOFT_CRC32.zip).



Цитата(AHTOXA @ Nov 26 2010, 00:00) *
Если я правильно понял, Danis хочет приспособить имеющийся в STM32 аппаратный модуль подсчёта crc32 (с жёстко заданным полиномом) для подсчёта crc32/crc16 с произвольным полиномом.


нет, нет. Это не возможно! biggrin.gif


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post
svl
сообщение Nov 26 2010, 18:31
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 20-12-07
Пользователь №: 33 465



Код
#include <stddef.h>
#include <stdint.h>
/*
  Name  : CRC-32
  Poly  : 0x04C11DB7    x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11
                       + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
  Init  : 0xFFFFFFFF
  Revert: true
  XorOut: 0xFFFFFFFF
  Check : 0xCBF43926 ("123456789")
  MaxLen: 268 435 455 байт (2 147 483 647 бит) - обнаружение
   одинарных, двойных, пакетных и всех нечетных ошибок
*/
const uint_least32_t Crc32Table[256] = {
    0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
    0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
    0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
    0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
    0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
    0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
    0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
    0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
    0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
    0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
    0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
    0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
    0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
    0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
    0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
    0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
    0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
    0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
    0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
    0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
    0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
    0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
    0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
    0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
    0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
    0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
    0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
    0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
    0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
    0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
    0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
    0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
    0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
    0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
    0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
    0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
    0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
    0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
    0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
    0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
    0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
    0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
    0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
    0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
    0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
    0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
    0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
    0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
    0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
    0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
    0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
    0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
    0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
    0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
    0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
    0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
    0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
    0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
    0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
    0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
    0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
    0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
    0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
    0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};

uint_least32_t Crc32(const unsigned char * buf, size_t len)
{
    uint_least32_t crc = 0xFFFFFFFF;
    while (len--)
        crc = (crc >> 8) ^ Crc32Table[(crc ^ *buf++) & 0xFF];
    return crc ^ 0xFFFFFFFF;
}


И маленький совет.
Если буфер данных загнать в подсчет CRC(любой) вместе с принятой контрольной суммой от отправителя, в вашем случае 20 байт, при совпадении СRC на выходе функции получите просто 0, тем самым дополнительно ничего пересчитывать не нужно.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Nov 26 2010, 20:32
Сообщение #9


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



2 svl
Crc32Table нужно было внутрь функции вставить, была бы локальная таблица констант. Все равно больше нигде не нужна.

Go to the top of the page
 
+Quote Post
svl
сообщение Nov 27 2010, 10:04
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 20-12-07
Пользователь №: 33 465



Цитата(ViKo @ Nov 26 2010, 23:32) *
2 svl
Crc32Table нужно было внутрь функции вставить, была бы локальная таблица констант. Все равно больше нигде не нужна.


О да! И загоняли бы стек при каждом вызове функции подсчета CRC...
Объявление static const uint_least32_t Crc32Table[256] = {... // Размещение массива в памяти программ (flash)
Для каждого компилятора, объявления различны.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Nov 27 2010, 11:26
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(svl @ Nov 27 2010, 13:04) *
О да! И загоняли бы стек при каждом вызове функции подсчета CRC...
Объявление static const uint_least32_t Crc32Table[256] = {... // Размещение массива в памяти программ (flash)
Для каждого компилятора, объявления различны.


Переменные, объявленные как static внутри функции размещаются не в стеке.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 19:03
Рейтинг@Mail.ru


Страница сгенерированна за 0.01468 секунд с 7
ELECTRONIX ©2004-2016