|
CRC16(ModBus) на С для ATmega128, помогите разобраться |
|
|
|
Sep 17 2008, 07:38
|

Участник

Группа: Участник
Сообщений: 35
Регистрация: 30-10-07
Из: Москва
Пользователь №: 31 896

|
Всем доброе время суток! Прошу помочь мне разобраться в С коде.Сам только недавно начал осваивать. нужно реализовать CRC16 для ModBus. Я знаю,что есть куча готовых реализаций.Простым(последовательным) и табличным способом. Но хочу реализовать сам. У меня проблема в том,что для вычисления CRC нужно смотреть на состояние младшого бита. Если "1" - то выполнять XOR,если нет,то крутить дальше. Вот мой код: int crc16 (unsigned char a) // a - 8-bit data for calculation CRC { unsigned int reg, tmp; int i; reg = 0xFFFF; // step1: initial loading of 16-bit register reg ^= (unsigned int)a; // step2: a XOR reg for(i = 0;i<8;i++) //step3: 8-iteration to calculate CRC { reg >>= 1; tmp = reg; tmp <<= 15; if(tmp == 0x8000) reg ^= 0xA001; // checking: if LSB = "1" reg=reg^0xA001 } return reg; } проверку я выолняю поразрядным сдвигом 16-битного reg влево, и, если там "1",то xor. ниже преведена другая реализация CRC16 и она работет корректно!!!!int crc16 (unsigned char a) { unsigned int reg; unsigned char i, tmp; reg = 0xFFFF; reg ^= (unsigned int)a; for(i = 0;i<8;i++) { tmp = (unsigned char)(reg&0x0001); reg >>= 1; if(tmp) reg ^= 0xA001; } return reg; } Поясните,что не так в первой реализачии.
|
|
|
|
|
 |
Ответов
(30 - 44)
|
Sep 23 2008, 23:18
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(ReAl @ Sep 23 2008, 20:33)  Вы сами сказали, что оно "эквивалентно" тому, что я написал в качестве аналога Вашего ассемблерного кода Ну, я рад, что все высказали всё, что хотели(:-). Кое-чему и поучиться можно было. Со своей стороны отмечу только, что до поста #16 у меня даже понятия не было о реализации подобным образом, идея возникла спонтанно. И самым сложным для меня было показать, каким образом получить цкс из укороченной таблицы, конечно, надо было обозвать операцию типа crclut, а не crc, что привело к ошибочному пониманию метода. Была ещё одна идея, как посчитать цкс без таблиц, занимает от 16 до 32 тактов, в среднем 24, ну это уже неинтересно.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 29 2008, 19:50
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(=GM= @ Sep 23 2008, 14:51)  Для ваших тестовых строк даёт те же цкс Код .db 0xA5,0xC3 ;CRC=0x0BA4 .db 0xC5,0xA3 ;CRC=0x6С28 .db 0xC3,0xA5 ;CRC=0xA648 (Замечу в скобках, обычно цкс начинают считать с 0xFFFF, а не с 0х0000 как у вас) У вас ошибка CRC. Модбас работать не будет. Д.б. сл. значения .db 0xA5,0xC3 ;CRC=0xB13A .db 0xC5,0xA3 ;CRC=0x9912 .db 0xC3,0xA5 ;CRC=0x3B91
|
|
|
|
|
Sep 30 2008, 15:35
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(defunct @ Sep 30 2008, 12:13)  Я не табличкой считал, а старым дедовским способом, описанным в спецификации на modbus (гарантированно правильным). ReAl от Вас хотел только неравенства всех трех значений, а нужно чтоб кроме неравенства еще и считалось _то_ что надо ReAl считал тремя способами, между прочим, и старым дедовским тоже. И вообще-то, ReAl хотел добиться правды, он её добился, все получили более-менее быстрый алгоритм с таблицей в ВОСЕМЬ раз меньше стандартной таблицы. А я считал по своему алгоритму, и результаты всех четырёх расчётов совпали, вам что, этого мало? Я ж вам сказал, возьмите правильную, нужную таблицу для модбаса, и дело в шляпе. Алгоритм универсальный. А укороченные таблицы вычленяются из штатных.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 30 2008, 16:04
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(=GM= @ Sep 30 2008, 18:35)  Я ж вам сказал, возьмите правильную, нужную таблицу для модбаса, и дело в шляпе. Но ведь это вы "вбросили" сюда неправильную неподходящую таблицу, почему исправлять это недоразумение должны ReAl и defunct? Начали - доводите до конца. И озвучьте характеристики вашего кода (размер/такты), чтобы можно было сравнить.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 30 2008, 16:46
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(=GM= @ Sep 30 2008, 18:35)  Я ж вам сказал, возьмите правильную, нужную таблицу для модбаса, и дело в шляпе. Алгоритм универсальный. А укороченные таблицы вычленяются из штатных. Проблема в том, что не получилось у меня создать таблицу для модбаса (256x16) чтобы работала по вашему алгоритму: Код void crc_update(uint8_t data) { crc ^= crctable2[ data ]; } Хотите верьте, хотите проверьте.. Не работает, неверные результаты дает на уже втором символе. А просто от фонаря взять какой-то полином, слегка изменить алгоритм и сказать, что это тоже CRC это все могут.
|
|
|
|
|
Sep 30 2008, 21:49
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Сергей Борщ @ Sep 30 2008, 15:04)  Но ведь это вы "вбросили" сюда неправильную неподходящую таблицу, почему исправлять это недоразумение должны ReAl и defunct? Начали - доводите до конца. И озвучьте характеристики вашего кода (размер/такты), чтобы можно было сравнить. Во, Сергей Борщ объявился, а мы уж и не ждали (:-)! Это ведь вы заварили всю кашу, как, да что, да опубликуйте код... ReAl ничего не исправлял и не должен, с какой стати? Он посчитал цкс по моей таблице, она совпала с моим расчётом, он и согласился со мной. Теперь о таблице. Если есть таблица для любого полинома, то можно легко получить укороченную таблицу, что я и пытался показать своим первым кодом (по крайней мере, для меня было трудно написать с ходу), но тут все накинулись, не так, не работает, да и озу, ой как жалко, целых 64 байта... Короче, дайте таблицу для модбаса, я её подрихтую. Как я уже говорил, таблица занимает 64 байта озу, программа считает цкс для одного байта в цикле за 22 МЦ, хотя можно уменьшить до 21. Цитата(defunct @ Sep 30 2008, 15:46)  Проблема в том, что не получилось у меня создать таблицу для модбаса (256x16) чтобы работала по вашему алгоритму: crc ^= crctable2[ data ] defunct, это не алгоритм, мой алгоритм приведен в посте #28. А то, что вы привели, мне бы надо переписать как-то так CRCLUT=crctable2[ data ], выше я уже говорил про это. Вот вам код для расчёта по таблице, случайно оказался дома на одном из двд, 100% рабочий, вырвал из моей старой программы 2001 года, работала с очень неудобным таг-ридером, который проектировал один кетаец в юса, отсюда такая таблица Код lcrc=hcrc=0x00FF; for(i=0;i<nbyte;i++) { indx=(datain[i]^hcrc)&0x00FF; crc=crcbuf[indx]; hcrc=((crc>>8)^lcrc)&0xFF; lcrc=crc&0x00FF; } hcrc=hcrc^0x00FF; lcrc=lcrc^0x00FF;
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Oct 2 2008, 15:27
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(defunct @ Sep 29 2008, 18:50)  Mодбас работать не будет. Д.б. сл. значения .db 0xA5,0xC3 ;CRC=0xB13A .db 0xC5,0xA3 ;CRC=0x9912 .db 0xC3,0xA5 ;CRC=0x3B91 defuct, вы уверены, что будут такие цкс для этих строк, если начальное значение цкс равно 0хFFFF?
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Oct 2 2008, 16:37
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(=GM= @ Oct 2 2008, 18:27)  defuct, вы уверены, что будут такие цкс для этих строк, если начальное значение цкс равно 0хFFFF? Выше приводили рабочие версии расчета CRC. Вот еще одна рабочая реализация: Код #define CRC16_DIVISOR (0xA001) #define CRC16_ERROR (0xFFFF)
/*********************************************** * ---> pData - msg to be protected * * ---> size - msg size in bytes * * <--- crc16 * ***********************************************/ U16 CRC16(U8 *pData, U8 size) { U16 retval = CRC16_ERROR; U8 i, tmp; if (!size) return retval;
do { retval ^= *pData++; for( i = 0; i < 8; i++) { tmp = retval & 0x01; retval >>= 1; if (tmp) { retval ^= CRC16_DIVISOR; } } } while (--size); return retval; } Если не сложно подставьте с теми данными.
|
|
|
|
|
Oct 2 2008, 20:41
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(defunct @ Oct 2 2008, 15:37)  Если не сложно подставьте с теми данными Подставлю, конечно, но попозже, на работе запарка в кои-то веки, и не выходит у меня сингулярное разложение матриц, а я хочу взять отпуск на недельку. Ну ладно, не будем о грустном, я почему спрашиваю, нашёл полное описание модбаса, там была таблица, я по ней посчитал вручную, и ответ не сошёлся с вашим. Да, там ещё и алгоритм приведен, как считать, практически один в один с моим по сути, могу показать, если надо, вместе с таблицей.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Oct 3 2008, 08:30
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Проверил ещё раз, получаются другие результаты, но пригляделся - они такие же, только у вас переставлены младший и старший байты. Должно быть так .db 0xA5,0xC3 ;CRC=0x3AB1 .db 0xC5,0xA3 ;CRC=0x1299 .db 0xC3,0xA5 ;CRC=0x913B CODE the splitted crc table for the modbus protocol
/*Table of CRC values for high–order byte*/ static unsigned char auchCRCHi[]= { 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40 }; /*Table of CRC values for low–order byte*/ static char auchCRCLo[]= { 0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4,0x04 0xCC,0x0C,0x0D,0xCD,0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09,0x08,0xC8 0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC 0x14,0xD4,0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3,0x11,0xD1,0xD0,0x10 0xF0,0x30,0x31,0xF1,0x33,0xF3,0xF2,0x32,0x36,0xF6,0xF7,0x37,0xF5,0x35,0x34,0xF4 0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A,0x3B,0xFB,0x39,0xF9,0xF8,0x38 0x28,0xE8,0xE9,0x29,0xEB,0x2B,0x2A,0xEA,0xEE,0x2E,0x2F,0xEF,0x2D,0xED,0xEC,0x2C 0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26,0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0 0xA0,0x60,0x61,0xA1,0x63,0xA3,0xA2,0x62,0x66,0xA6,0xA7,0x67,0xA5,0x65,0x64,0xA4 0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68 0x78,0xB8,0xB9,0x79,0xBB,0x7B,0x7A,0xBA,0xBE,0x7E,0x7F,0xBF,0x7D,0xBD,0xBC,0x7C 0xB4,0x74,0x75,0xB5,0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71,0x70,0xB0 0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54 0x9C,0x5C,0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,0x99,0x59,0x58,0x98 0x88,0x48,0x49,0x89,0x4B,0x8B,0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C 0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40 };
И программа, по которой считается цкс Код /* CRC Generation Function */ unsigned short CRC16(puchMsg, usDataLen) unsigned char *puchMsg; /* message to calculate CRC upon */ unsigned short usDataLen; /* quantity of bytes in message */ { unsigned char uchCRCHi = 0xFF; /* high byte of CRC initialized */ unsigned char uchCRCLo = 0xFF; /* low byte of CRC initialized */ unsigned uIndex; /* will index into CRC lookup table */ while (usDataLen––) /* pass through message buffer */ { uIndex = uchCRCHi ^ *puchMsgg++; /* calculate the CRC */ uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex}; uchCRCLo = auchCRCLo[uIndex]; } return (uchCRCHi << 8 | uchCRCLo); } И таблица, и программа взяты из описания протокола модбас
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Oct 3 2008, 09:23
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(=GM= @ Oct 1 2008, 00:49)  Во, Сергей Борщ объявился, а мы уж и не ждали (:-)! Это ведь вы заварили всю кашу, как, да что, да опубликуйте код... Я и не пропадал. Внимательно смотрю, как вы выкручиваетесь. Не надо перекладывать с одной головы на здоровую. Кашу заварили вы: Цитата(=GM= @ Sep 19 2008, 14:20)  А что если сделать две таблицы на биты <7-4> и <3-0>? Прикинул программулю, получается 20 тактов на байт, размер 47 слов вместе с таблицами. Я лишь попросил вас привести подтверждение этих цифр в виде кода. Алгоритм, который вы, снова не удосужившисть проверить, привели, оказался абсолютно нерабочим, что вам с цифрами в руках доказал ReAl. Вы довели его до ума, но от исходных "20 тактов на байт, размер 47 слов вместе с таблицами" не осталось и следа. И вдруг выясняется, что ваш алгоритм считает совсем другую CRC. И снова виноват кто-то другой: Цитата(=GM= @ Sep 30 2008, 12:26)  А вы это ReAl'у скажите, у меня с ним совпало. Хотя: Цитата(ReAl @ Sep 22 2008, 14:09)  Таблица не для того полинома и направления сдвига, который обсуждается в теме, ну да ладно... Для основной темы это только частичный оффтопик, но тема веников наконец-то будет раскрыта. "Казалось бы, при чем здесь Лужков"? Цитата(=GM= @ Oct 1 2008, 00:49)  ReAl ничего не исправлял и не должен, с какой стати? Он посчитал цкс по моей таблице, она совпала с моим расчётом, он и согласился со мной. Совесть имейте: Цитата(ReAl @ Sep 19 2008, 23:27)  Что-то не пахнет тут CRC. Мне кажется, что это ничем не лучше простой XORки всех байтов сообщения. Независимо от таблицы реакция на последовательность 0xA5 0xC3 будет та же, что и на 0xC3 0xA5 или на 0xC5 0xA3. Итог после всех ваших исправлений "прикинутой программули": уменьшить таблицы можно, но "47 слов вместе с таблицами и 20 тактов", которые были главными козырями, нету и близко. Хотя виноваты, конечно, все, кроме =GM=. Цитата(=GM= @ Oct 3 2008, 11:30)  Проверил ещё раз, получаются другие результаты, но пригляделся - они такие же, только у вас переставлены младший и старший байты. Честно-честно? Проверили? И что, это работало? Цитата Код uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex}; Цитата(=GM= @ Oct 3 2008, 11:30)  И таблица, и программа взяты из описания протокола модбас Ну а где же ваши чудо-таблицы? Что же вы проверяли - описание модбас?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 3 2008, 12:43
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Вот укороченная таблица для модбаса Код ;a short crc table for modbus protocol .db 0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2 .db 0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4,0x04 .db 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41 .db 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40 .db 0x00,0xCC,0xD8,0x14,0xF0,0x3C,0x28,0xE4 .db 0xA0,0x6C,0x78,0xB4,0x50,0x9C,0x88,0x44 .db 0x00,0x01,0x01,0x00,0x01,0x00,0x00,0x01 .db 0x01,0x00,0x00,0x01,0x00,0x01,0x01,0x00 Вот тестовые строки и цкс для каждой строки, как результат работы моей программы с укороченной таблицей. А у Юры явно перепутаны старший и младший байты Код .db 0xA5,0xC3;CRC=0x3AB1 .db 0xC5,0xA3;CRC=0x1299 .db 0xC3,0xA5;CRC=0x913B Как видите, таблица занимает 32 слова в озу, сама программа занимает 16 слов во флеше, в итоге получается 48. Один байт из буфера обсчитывается за 22 такта с учетом организации цикла. Можно сделать за 21 такт, не стал приводить, поскольку сложнее для понимания. Кому надо, легко сделает. Можно также развернуть цикл, будет примерно 96флеш+32озу=128 слов, время выполнения будет 19 тактов на байт. Ещё раз, алгоритм универсальный, работает для ЛЮБОГО полинома, поскольку берёт данные из укороченной таблицы соответствующего полинома. На остальное не отвечаю по понятной причине.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jan 9 2009, 00:07
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(=GM= @ Oct 3 2008, 14:43)  Вот тестовые строки и цкс для каждой строки, как результат работы моей программы с укороченной таблицей. А у Юры явно перепутаны старший и младший байты =GM=, наткнулся на табличную реализацию - точно такую же как Вы привели  У меня все-таки ничего не перепутано, похоже, что пример который Вы нашли сделан для big-endian проца. Для little-endian результат должен быть такой как у меня. Ну и чтоб с приведеными табличками можно было работать на AVR привожу код (для AVR'а надо пользовать little-endian функцию): Код #if (BIG_ENDIAN) // big endian CPU U16 crc16(U16 crc, U8 data) { U8 index; U8 crc_High = crc >> 8; U8 crc_Low = crc & 0xFF;
index = crc_High ^ data; crc_High = crc_Low ^ mb_table_level1[ index ]; crc_Low = mb_table_level2[ index ];
return (crc_High << 8) | crc_Low; } #else // little endian CPU U16 CRC16_Update(U16 crc, U8 data) { U8 index; U8 crc_High = crc >> 8; U8 crc_Low = crc & 0xFF;
index = crc_Low ^ data; crc_Low = crc_High ^ mb_table_level1[ index ]; crc_High = mb_table_level2[ index ];
return (crc_High << 8) | crc_Low; } #endif mb_table_level1 ---> auchCRCHi из поста #42 mb_table_level2 ---> auchCRCLo из поста #42
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|