Danis 0 26 ноября, 2010 Опубликовано 26 ноября, 2010 · Жалоба Что значит переделывать? Это же обычный Си. Я не совсем Вас понимаю, как в микроконтроллере, с использованием функции, аппаратно посчитать CRC? Ну это уже из темы ALTERA или XILINX. Маленько уточняю… В STM32 есть аппаратный модуль подсчета CRC32. Если в него передать некий буфер, то в результате он подсчитает CRC32. Например, из ПК в STM32 передаем некий буфер, предположим 20 байт, в которых 16 байт это непосредственно сам информационный буфер, а последние четыре это CRC32 (рассчитывается в ПК). Дальше аппаратно считаем CRC32 в STM32 (для 16-ти байт) и сравниваем. Вот я и просил выложить табличную функцию расчета CRC32 на Си, которая будет возвращать результат такой же как и аппаратный модуль CRC32 STM32. Таковую функцию на Си я написал, но не табличную (выложил выше - STM32_SOFT_CRC32.zip). Если я правильно понял, Danis хочет приспособить имеющийся в STM32 аппаратный модуль подсчёта crc32 (с жёстко заданным полиномом) для подсчёта crc32/crc16 с произвольным полиномом. нет, нет. Это не возможно! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
svl.soft 0 26 ноября, 2010 Опубликовано 26 ноября, 2010 · Жалоба #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, тем самым дополнительно ничего пересчитывать не нужно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 ноября, 2010 Опубликовано 26 ноября, 2010 · Жалоба 2 svl Crc32Table нужно было внутрь функции вставить, была бы локальная таблица констант. Все равно больше нигде не нужна. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Danis 0 26 ноября, 2010 Опубликовано 26 ноября, 2010 · Жалоба ........................ ...................... 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; } svl! Спасибо за отзыв. Приятно когда человек реально хочет поспособствовать, а не отправляет в гугл или Википедию. Похоже, аппаратный модуль CRC32 в STM32 никто не использует, а зря, это ж хороший плюс в скорости расчета, в 5 раз быстрее табличного CRC32. svl, Ваша функция: uint_least32_t Crc32(const unsigned char * buf, size_t len); считает CRC32 точно также, как считает та, что я скинул выше (файл CRC32.rar). Но дело в том, что аппаратный модуль CRC у STM32 считает не так! Например, передаем unsigned char buff[4] = {0,0,0,0}; uint_least32_t My_CRC32 = Crc32( (const unsigned char*)(buff), 4 ) ; получаем результат: 0x2144df1c. Тот же буфет передаю в аппаратный модуль CRC32 у STM32 только виде 32 integer, т.к у него регистр CRC 32-х битный. Получается, передаю всего одну переменную = 0x00000000 получаем результат: 0xc704dd7b Видите, результат разный!!!! Вот почему: 0xc704dd7b если произвести перестановку битов ( bit-reverse( 0xc704dd7b) = 0xdebb20e3), и еще сделать так: 0xdebb20e3 ^ 0xffffffff = 0x2144df1c - вот только теперь получим сходство. Функцию которая считает программно CRC32 с результатом расчетов таким же как и у аппаратного модуля STM32 я уже скидывал (STM32_SOFT_CRC32.zip), но она не табличная. И маленький совет. Если буфер данных загнать в подсчет CRC(любой) вместе с принятой контрольной суммой от отправителя, в вашем случае 20 байт, при совпадении СRC на выходе функции получите просто 0, тем самым дополнительно ничего пересчитывать не нужно. Сначала считаю CRC32 для 16-ти байт, потом приписываю ее в конце буфера так и сяк, о не выходит! unsigned char buff[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,0,0,0}; uint_least32_t My_CRC32 = Crc32( (const unsigned char*)(buff), 16 ) ; My_CRC32: 0xcecee288 unsigned char buff[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0x88,0xe2,0xce,0xce}; uint_least32_t My_CRC32 = Crc32( (const unsigned char*)(buff), 20 ) ; My_CRC32: 0x2144df1c unsigned char buff[20]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0xce,0xce,0xe2, 0x88}; uint_least32_t My_CRC32 = Crc32( (const unsigned char*)(buff), 20 ) ; My_CRC32: 0x08e2e872 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
svl.soft 0 27 ноября, 2010 Опубликовано 27 ноября, 2010 · Жалоба 2 svl Crc32Table нужно было внутрь функции вставить, была бы локальная таблица констант. Все равно больше нигде не нужна. О да! И загоняли бы стек при каждом вызове функции подсчета CRC... Объявление static const uint_least32_t Crc32Table[256] = {... // Размещение массива в памяти программ (flash) Для каждого компилятора, объявления различны. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 27 ноября, 2010 Опубликовано 27 ноября, 2010 · Жалоба Объявление static const Да, конечно и несомненно. Для любого компилятора константный массив следует снабжать словом const. Для любого компилятора при упрятывании никому, кроме данной функции, не нужной глобальной переменной внутрь функции следует снабжать эту переменную словом static. Это что-то вроде минимальных правил хорошего тона. И не зависит от того, во флеше это всё или флеш в системе только для того, чтобы BIOS на старте в DDR3 SDRAM переписать, а программа с диска зачитывается. При размещении всей программы вместе с данными исключительно в ОЗУ всё равно стоит тут таблицу и const объявить, и внутрь функции затолкать. Со static, естественно. А дальше уж в зависимости от. При едином адресном пространстве компилятор сам во флеш затолкает, в других случаях придётся ручками прописывать нужное нестандартное ключевое слово. Но это отдельно, дополнительно и не обязательно (если глобальной таблице такое слово не было нужно, то и статической локальной оно не нужно). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 27 ноября, 2010 Опубликовано 27 ноября, 2010 · Жалоба О да! И загоняли бы стек при каждом вызове функции подсчета CRC... С какого бодуна? :cranky: При выключенной оптимизации? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 27 ноября, 2010 Опубликовано 27 ноября, 2010 · Жалоба О да! И загоняли бы стек при каждом вызове функции подсчета CRC... Объявление static const uint_least32_t Crc32Table[256] = {... // Размещение массива в памяти программ (flash) Для каждого компилятора, объявления различны. Переменные, объявленные как static внутри функции размещаются не в стеке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
svl.soft 0 27 ноября, 2010 Опубликовано 27 ноября, 2010 · Жалоба Переменные, объявленные как static внутри функции размещаются не в стеке. Вот я это и хотел сказать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 27 ноября, 2010 Опубликовано 27 ноября, 2010 · Жалоба Вот я это и хотел сказать. Стало быть, согласны, что нужно было сделать static const и внутрь функции задвинуть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sergey_Aleksandrovi4 2 18 июня, 2012 Опубликовано 18 июня, 2012 · Жалоба Например, передаем unsigned char buff[4] = {0,0,0,0}; uint_least32_t My_CRC32 = Crc32( (const unsigned char*)(buff), 4 ) ; получаем результат: 0x2144df1c. Тот же буфет передаю в аппаратный модуль CRC32 у STM32 только виде 32 integer, т.к у него регистр CRC 32-х битный. Получается, передаю всего одну переменную = 0x00000000 получаем результат: 0xc704dd7b Видите, результат разный!!!! Вот почему: 0xc704dd7b если произвести перестановку битов ( bit-reverse( 0xc704dd7b) = 0xdebb20e3), и еще сделать так: 0xdebb20e3 ^ 0xffffffff = 0x2144df1c - вот только теперь получим сходство. На последовательностях отличных от {0,0,0,0} и {255,255,255,255} всё-равно результаты разные. Вот что удалось найти https://my.st.com/public/STe2ecommunities/m...rrentviews=1996 Продублирую кодом u32 revbit(u32 data) { asm("rbit r0,r0"); return data; }; u32 CalcCRC32(u8 *buffer,u32 size) { u32 i, j; u32 ui32; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC,ENABLE); CRC->CR=1; asm("NOP");asm("NOP");asm("NOP");//delay for hardware ready i = size >> 2; while(i--) { ui32=*((u32 *)buffer); buffer += 4; ui32=revbit(ui32);//reverse the bit order of input data CRC->DR=ui32; } ui32=CRC->DR; ui32=revbit(ui32);//reverse the bit order of output data i = size & 3; while(i--) { ui32 ^= (u32)*buffer++; for(j=0; j<8; j++) if (ui32 & 1) ui32 = (ui32 >> 1) ^ 0xEDB88320; else ui32 >>= 1; } ui32^=0xffffffff;//xor with 0xffffffff return ui32;//now the output is compatible with windows/winzip/winrar }; Не вникал, что к чему, но метод работает. Быстрее классического табличного CRC32 алгоритма (аналогичному коду из википедии) в ~3 раза. И не нужен буфер 1 кБайт под таблицу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vlad_new 1 18 июня, 2012 Опубликовано 18 июня, 2012 · Жалоба В STM32 кривой аппаратный CRC. Я долго пытался понять какому стандарту он соответствует. Оказалось, что у них перевернут регистр сзаду на перед. Так что если нужно вычеслить CRC скажем для Ethrnet, то туда надо заганять перевернутые данные, а затем, после чтения их опять надо перевренуть ( все биты местами менять предется ). Потом мне сказали, что в какой то эррате это было прописано, правда я так и не нашел эту еррату. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sergey_Aleksandrovi4 2 18 июня, 2012 Опубликовано 18 июня, 2012 · Жалоба Да, если бы не необходимость менять порядок следования бит в каждой итерации (благо делается всего одной инструкцией), можно бы было прикрутить расчёт CRC к DMA (в теории). Но тем не менее работает всяко быстрее чисто программных решений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yurmala 0 6 ноября, 2012 Опубликовано 6 ноября, 2012 · Жалоба В коллекцию исходников: Open Source утилитка расчета всевозможных контрольных сумм в основном табличным методом. http://fsumfe.sourceforge.net/ Сами алгоритмы лежат в папке src\fsumfe\digest\algo\ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Алексей Васильевич 0 15 января, 2021 Опубликовано 15 января, 2021 · Жалоба 18.06.2012 в 21:30, vlad_new сказал: В STM32 кривой аппаратный CRC. Я долго пытался понять какому стандарту он соответствует. Оказалось, что у них перевернут регистр сзаду на перед. Так что если нужно вычеслить CRC скажем для Ethrnet, то туда надо заганять перевернутые данные, а затем, после чтения их опять надо перевренуть ( все биты местами менять предется ). Потом мне сказали, что в какой то эррате это было прописано, правда я так и не нашел эту еррату. Есть потребность считать сумму при работе с DMA, микроконтроллер имеет мало памяти и хочется аппаратную контрольную сумму, 1кб для таблицы это для меня много. Какой алгоритм должен быть на стороне сервера ? может есть готовый модуль на С++ ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться