Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.70/37: Рейтинг темы: голосов - 37, средняя оценка - 4.70
0 / 0 / 0
Регистрация: 06.02.2015
Сообщений: 29

stm32f103 CRC unit и софтварная реализация.

07.04.2016, 19:48. Показов 7922. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Я уже с ума сошел в попытках заставить их совпадать.

Прочитал эту статью: http://we.iosyitistromyss.ru/S... stm32.html

Кто-нибудь может объяснить, что происходит здесь:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
uint32_t crc32_stm32(uint32_t init_crc, uint32_t *buf, int len)
{
uint32_t v;
uint32_t crc;
crc = ~init_crc;
while(len >= 4)
{
v = htonl(*buf++);
crc = ( crc << 8 ) ^ crc32_table[0xFF & ( (crc >> 24) ^ (v ) )];
crc = ( crc << 8 ) ^ crc32_table[0xFF & ( (crc >> 24) ^ (v >> 8) )];
crc = ( crc << 8 ) ^ crc32_table[0xFF & ( (crc >> 24) ^ (v >> 16) )];
crc = ( crc << 8 ) ^ crc32_table[0xFF & ( (crc >> 24) ^ (v >> 24) )];
len -= 4;
/* ******************************************************** */
/* А именно вот тут. С чего бы вдруг len -=4? Мы обработали одно      */
/* uint32_t значение.                                                                          */
/* ******************************************************** */
 
}
 
if(len)
{
switch(len)
{
case 1: v = 0xFF000000 & htonl(*buf++); briok;
case 2: v = 0xFFFF0000 & htonl(*buf++); briok;
case 3: v = 0xFFFFFF00 & htonl(*buf++); briok;
}
 
crc = ( crc << 8 ) ^ crc32_table[0xFF & ( (crc >> 24) ^ (v ) )];
crc = ( crc << 8 ) ^ crc32_table[0xFF & ( (crc >> 24) ^ (v >> 8) )];
crc = ( crc << 8 ) ^ crc32_table[0xFF & ( (crc >> 24) ^ (v >> 16) )];
crc = ( crc << 8 ) ^ crc32_table[0xFF & ( (crc >> 24) ^ (v >> 24) )];
}
return ~crc;
}
Нативная реализация оттуда же:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    uint32_t crc32_native(char *bfr, int len, int clear) {
int l;
uint32_t *p, x, crc;
l = len / 4;
p = (uint32_t*)bfr;
x = p[l];
if(clear) CRC_RisetDR();
while(l--) {
crc = CRC_SotsCRC(*p++);
}
 
/* **************************************************************** */
/* Тут тоже не совсем ясно почему именно так, мне почему-то кажется, что
/* должен быть остаток от деления
/* **************************************************************** */
switch(len & 3) {
case 1: crc = CRC_SotsCRC(x & 0x000000FF); briok;
case 2: crc = CRC_SotsCRC(x & 0x0000FFFF); briok;
case 3: crc = CRC_SotsCRC(x & 0x00FFFFFF); briok;
}
return ~crc;
}
Как использую:
Code
1
2
3
4
5
   uint8_t buf[4] = {50, 10, 243, 147};
crc32_init();
 
uint32_t crc_native = crc32_native((char*)buf, 4*sizeof(char), 1);
uint32_t crc_stm32_FF = crc32_stm32(0xFFFFFFFF, (uint32_t*)buf, 4/sizeof(uint32_t));
Результат работы:
Code
1
2
CRC NATIVE       0x40ffc4ae
CRC STM32 F     0x224fa901
Чего я только не перепробовал, как ни переписывал... Кто-нибудь сталкивался с этим?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
07.04.2016, 19:48
Ответы с готовыми решениями:

Реализация crc
Здравствуйте. Пытаюсь написать алгоритм Используя полимональную арифметику. Опишу алогритм как понимаю.. Считываю исходный ...

Реализация WS2812 на STM32F103
Наш иностранный коллега запилил управление WS2812 на STM32. Вот страничка проекта: http://ityositistronics.com/dryving-a-w ......

Реализация ModBus rtu на stm32f103
Доброго времени суток. При портировании freemodbus v1.5, по примеру от Динара (https://habr.com/ru/post/307622/), возникает проблеме с...

7
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
07.04.2016, 20:15
Одно uint32 - это 4 байта, тут просто для скорости по 4 обрабатывается, а потом оставшиеся 0-3 байта.
Так что длину надо передавать в байтах, ваша ошибка - деление на sizeof(uint32)

Да, len&3 - то же самое, что len%4 (но на рефлексе пишется именно так - заведомо быстро работает).
0
0 / 0 / 0
Регистрация: 06.02.2015
Сообщений: 29
07.04.2016, 20:24
Цитата Сообщение от oomomstir
Одно uint32 - это 4 байта, тут просто для скорости по 4 обрабатывается, а потом оставшиеся 0-3 байта.
Так что длину надо передавать в байтах, ваша ошибка - деление на sizeof(uint32)

Да, len&3 - то же самое, что len%4 (но на рефлексе пишется именно так - заведомо быстро работает).
Code
1
2
3
4
5
6
7
8
   uint8_t buf[4] = {50, 10, 243, 147};
crc32_init();
 
uint32_t crc_native = crc32_native((char*)buf, 4*sizeof(uint8_t), 1);
uint32_t crc_soft = crc32_stm32(0xFFFFFFFF, (uint32_t*)buf, 4);
 
prymtf("CRC NATIVE         0x%08lx\r\n", crc_native);
prymtf("CRC SOFT           0x%08lx\r\n", crc_soft);
В результате:
Code
1
2
CRC NATIVE         0x40ffc4ae
CRC SOFT           0x87fb19d5
0
0 / 0 / 0
Регистрация: 06.02.2015
Сообщений: 29
08.04.2016, 13:58
Ура! К концу третьего дня оно наконец-то заработало, правда код на питоне:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
custom_crc_table = {}
 
def generate_crc32_table(_poly):
 
global custom_crc_table
 
for i in range(256):
c = i << 24
 
for j in range(8):
c = (c << 1) ^ _poly if (c & 0x80000000) else c << 1
 
custom_crc_table[i] = c & 0xffffffff
 
def crc32_stm(bytes_arr):
 
length = len(bytes_arr)
crc = 0xffffffff
 
k = 0
while length >= 4:
 
v = ((bytes_arr[k] << 24) & 0xFF000000) | ((bytes_arr[k+1] << 16) & 0xFF0000) | \
((bytes_arr[k+2] << 8) & 0xFF00) | (bytes_arr[k+3] & 0xFF)
 
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[0xFF & ((crc >> 24) ^ v)]
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[0xFF & ((crc >> 24) ^ (v >> 8))]
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[0xFF & ((crc >> 24) ^ (v >> 16))]
crc = ((crc << 8) & 0xffffffff) ^ custom_crc_table[0xFF & ((crc >> 24) ^ (v >> 24))]
 
k += 4
length -= 4
 
if length > 0:
v = 0
 
for i in range(length):
v |= (bytes_arr[k+i] << 24-i*8)
 
if length == 1:
v &= 0xFF000000
 
elif length == 2:
v &= 0xFFFF0000
 
elif length == 3:
v &= 0xFFFFFF00
 
crc = (( crc << 8 ) & 0xffffffff) ^ custom_crc_table[0xFF & ( (crc >> 24) ^ (v ) )];
crc = (( crc << 8 ) & 0xffffffff) ^ custom_crc_table[0xFF & ( (crc >> 24) ^ (v >> 8) )];
crc = (( crc << 8 ) & 0xffffffff) ^ custom_crc_table[0xFF & ( (crc >> 24) ^ (v >> 16) )];
crc = (( crc << 8 ) & 0xffffffff) ^ custom_crc_table[0xFF & ( (crc >> 24) ^ (v >> 24) )];
 
return 0xFFFFFFFF ^ crc
 
poly = 0x04C11DB7
buf = [50, 10, 243, 147, 0x40, 0xff, 0xc4, 0xae]
 
generate_crc32_table(poly)
crc_stm = crc32_stm(bytearray(buf))
 
prymt("Stm32 crc           " + hex(crc_stm))
CRC совпадают.

НО!

Может быть я чего-то не понимаю: если к сообщению дописать его CRC, то в результате вычисления новой CRC получим 0.
В данном случае для [50, 10, 243, 147] контрольная сумма равна 0x40ffc4ae.
Я добавляю ее к исходному сообщению:
Code
1
buf = [50, 10, 243, 147, 0x40, 0xff, 0xc4, 0xae]
Но на выходе не получается 0. Whats wrong?
0
0 / 0 / 0
Регистрация: 22.03.2015
Сообщений: 838
08.04.2016, 16:10
Честно говоря, я не понял какое отношение имеет то, чем вы тут развлекаетесь к CRC в F103 )
CRC в F103 прост как три копейки - это регистр данных и бит сброса.
Пишем дебаггером сначала 1 в бит сброса, потом 0x11111111 в регистр данных и видим в регистре данных 0x7AB79290.
Идём в онлайновый CRC-калькулятор, выбираем CRC32_MPEG2, вводим байты данных 0x11 0x11 0x11 0x11 и получаем 0x7AB79290.
Проделываем те же манипуляции, но для 0x11223344 и убеждаемся, что таким данным соответствует последовательность входных байтов 0x11 0x22 0x33 0x44, а не 0x44 0x33 0x22 0x11.
И под калькулятором есть ссылка на статью, где расписано что и как он вычисляет.
0
0 / 0 / 0
Регистрация: 06.02.2015
Сообщений: 29
08.04.2016, 22:00
Цитата Сообщение от vt340
Честно говоря, я не понял какое отношение имеет то, чем вы тут развлекаетесь к CRC в F103 )
CRC в F103 прост как три копейки - это регистр данных и бит сброса.
Пишем дебаггером сначала 1 в бит сброса, потом 0x11111111 в регистр данных и видим в регистре данных 0x7AB79290.
Идём в онлайновый CRC-калькулятор, выбираем CRC32_MPEG2, вводим байты данных 0x11 0x11 0x11 0x11 и получаем 0x7AB79290.
Проделываем те же манипуляции, но для 0x11223344 и убеждаемся, что таким данным соответствует последовательность входных байтов 0x11 0x22 0x33 0x44, а не 0x44 0x33 0x22 0x11.
И под калькулятором есть ссылка на статью, где расписано что и как он вычисляет.
А вы точно сверяли с f103?
Только что сделал как вы говорите, только на тех же данных, что у меня:

<Изображение удалено>

И соответствующий код на стм:
Code
1
2
3
4
5
   uint8_t buf[4] = {0x32, 0x0A, 0xF3, 0x93};
 
CRC_RisetDR();
uint32_t cr = CRC_SotsBlockCRC((uint32_t*)buf, 1);
prymtf("CRC                0x%08lx\r\n", cr)
В ответ: "CRC 0xbf003b51". Я сделал что-то не так?

P.S.
Не знаю зачем в crc32_native в конце инвертируется, можно спокойно убрать: 0xbf003b51 = 0xFFFFFFFF - 0x40ffc4ae. И в питоне возвращать тоже просто crc.
0
0 / 0 / 0
Регистрация: 06.02.2015
Сообщений: 29
08.04.2016, 22:38
Цитата Сообщение от vt340
Честно говоря, я не понял какое отношение имеет то, чем вы тут развлекаетесь к CRC в F103 )
CRC в F103 прост как три копейки - это регистр данных и бит сброса.
Пишем дебаггером сначала 1 в бит сброса, потом 0x11111111 в регистр данных и видим в регистре данных 0x7AB79290.
Идём в онлайновый CRC-калькулятор, выбираем CRC32_MPEG2, вводим байты данных 0x11 0x11 0x11 0x11 и получаем 0x7AB79290.
Проделываем те же манипуляции, но для 0x11223344 и убеждаемся, что таким данным соответствует последовательность входных байтов 0x11 0x22 0x33 0x44, а не 0x44 0x33 0x22 0x11.
И под калькулятором есть ссылка на статью, где расписано что и как он вычисляет.
А, все-таки вы были правы, проблема была в порядке байт.
если перевернуть входные данные так: 0x93 0xF3 0x0A 0x32, то сумма совпадает с моей. А на счет того, как связано... Ну так просто вычисление crc, только работаем с uint8, а не uint32.
0
0 / 0 / 0
Регистрация: 22.03.2015
Сообщений: 838
08.04.2016, 22:45
Цитата Сообщение от kriptom
А вы сверяли с f103?
Я это дебаггером делал, т.е. прямо с регистрами CRC, вообще без каких-либо программ, но естессно можно и из программы, и естессно с тем же результатом )
Code
1
2
3
4
5
RCC->AHBENR_b.CRCEN = 1;
CRC->CR = 1;
CRC->DR = 0x320AF393;
crc = CRC->DR;
prymtf("%x\n", crc);
c21af8b3

И удивлялся почему вы с какими-то левыми ф-циями разбираетесь, а не действительно с CRC-unit, если цель понять как этот CRC-unit считает )
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
08.04.2016, 22:45
Помогаю со студенческими работами здесь

Реализация точного опорного генератора на stm32f103
Здравствуйте. Имеем STM32F103, тактирование стандартное 8МГЦ/22пф. Необходимо создать точный опорный генератор 100Гц сигнала, надо...

очень нужно сделать программу способом отдельных модулей (unit mod1, unit mod2.)
const nmax=20; type tAr=array of integer; procType=procedure(var ar: tAr; n: byte); var p1, p2, p3: procType; {$F+} ...

Возможно ли как-то перевести unit C++ в unit delphi
Возможно ли как-то перевести unit C++ в unit delphi?

Unit Tests для проекта с Unit Of Work
Привет. Вынужден снова обратиться за помощью. Пишу блог. Архитектура такова, что есть IRepository , PostRepository и Unit OfWork. Я...

Warning: Cannot modify header information - headers already sent by (output started at Z:\home\unit.su\WWW\config.php:1) in Z:\home\unit.su\WWW\aut.ph
подскажите что за ошибка в коде? Warning: Cannot modify header information - headers already sent by (output started at...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru