Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

CRC32
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=12557
Страница 1 от 1

Автор:  miro_atc [ Пет Дек 20, 2013 1:42 pm ]
Заглавие:  CRC32

Има различни алгоритми за смятането... Има различни полиноми, зависи дали се смята LSB или MSB данни, зависи от размера на данните и т.н.

В зависимост от размера може да е:
- побитово
- на тедради
- на байтове
- на думи

Разликата е както в скоростта на смятане, така и в размера на функцията и евентуално размера на таблицата. Въпросът е че понякога си трябва скорост, а понякога е важно мястото, щото в един буутстрап е грехота да шибнеш 1к CRC таблица...
Проблемът е, че в нета поне аз не намирам всички варианти на едно място, а не ми се губи време да ги разписвам... Всъщност в Boots има Ц++ шаблони, ама да се вади от тях е кошмар.

Та дайте да съберем на едно място, говоря за стандартно CRC 32 (polinom 0x04C11DB7 / 0xEDB88320) и LSB данни...

Побитово е така (взаимствано от лайнукс):
Код:
#define CRCPOLY_LE 0xedb88320
unsigned int crc32_le(unsigned int crc, unsigned char const *p, unsigned int len)
{
   int i;
   while (len--)
   {
      crc ^= *p++;
      for (i = 0; i < 8; i++)
      {
         crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
      }
   }
   return crc;
}


Вариант за побайтово има тук. Някъде имаше и вариант със смятане на таблицата в RAM... Нещо обаче не намирам варианта с тедради, в ST форумите май имаше, ама с ревърс (MSB) но не ми се свапват битове...

Автор:  ike [ Пет Дек 20, 2013 2:21 pm ]
Заглавие:  Re: CRC32

Ето и мнението на TI CRC Implementation with MSP430
http://www.ti.com/mcu/docs/litabsmultip ... ilyId=1615
Тествано е работи със софтуерен битбанг ethernet.

За да не цапам повече темата допълвам тук.
miro_atc във архива има няколко имплементации на асемблер и на С. С таблици и без таблици.
Ако ти трябва имплементация за msp430 е просто копи/паста. Ако ти трябва за друг контролер С кода сигурно, ще може да се портне за 15 минути.

Автор:  miro_atc [ Пет Дек 20, 2013 2:38 pm ]
Заглавие:  Re: CRC32

идеята беше да съберем на едно място работещ код.... Имам предвид сорс код, а не pdf-и за четене, нито пък асемблери за портване ;-)

Въпросът е да не се губи време за нещо толкова елементарно като CRC, даже аз се изненадах колко време изгубих да се ровя :evil:

Автор:  Nikola Kirov [ Пет Дек 20, 2013 2:42 pm ]
Заглавие:  Re: CRC32

Това е една руска библиотека дето съм я бутнал малко и аз.

Прикачени файлове:
crc.rar [4.23 KiB]
167 пъти

Автор:  miro_atc [ Пет Дек 20, 2013 2:53 pm ]
Заглавие:  Re: CRC32

Nikola Kirov написа:
Това е една руска библиотека дето съм я бутнал малко и аз.


мерси, ама в нея виждам само побитовия и побайтовия вариант... за тях вече дадох код по-горе ;-)

търси се на нибъли ;-)

ето тук има вариации на big/little endian и смятане на байт и на дума, плюс опция за ънролване до 32 байта...

Автор:  Nikola Kirov [ Пет Дек 20, 2013 2:56 pm ]
Заглавие:  Re: CRC32

Тук има и табличния вариант за смятане. Затова я постнах

Автор:  gicho [ Пет Дек 20, 2013 3:49 pm ]
Заглавие:  Re: CRC32

http://www.tty1.net/pycrc/

Автор:  palavrov [ Пет Дек 20, 2013 4:43 pm ]
Заглавие:  Re: CRC32

Това с нибълите не е проблем. Връзката между побитовия и побайтовия вариант е много проста - побайтовата таблица е сметната като побитово за всички 256 числа - 0 .. FF. Може да си сметнеш само за нибъли като повтаряш 4 пъти (за 4 бита) побитово CRC за всички числа от 0 до F. Разбира си има значение и в каква посока ще въртиш битовете - но като цяло е проста работа.

Автор:  palavrov [ Пет Дек 20, 2013 4:55 pm ]
Заглавие:  Re: CRC32

И нещо което е полезно да се знае - CRC е линейна функция - т.е:
Код:
crc(x^y) = crc(x)^crc(y)
crc(x<<4) = crc(x)<<4

в случая оператора е "^" а не "+" или "*" защото този оператор се ползва в самия CRC полином.

Автор:  miro_atc [ Пет Дек 20, 2013 5:02 pm ]
Заглавие:  Re: CRC32

Абе теорията е ясна... ама просто ми трябваше да сравня вариантите и да видя как излизат като код и после да реша кое да ползвам. Че тъпанарите от ST пак са си оставили ръцете, сложили хардуерно црц ама биг ендиан (идиоти :evil: ) така че да не става да се ползва ДМА, сложили го и да бачка само на думи, да се чудиш как да довършваш...

Иначе ето кода за нибъли дето съчиних:

Код:
#define CRCPOLY_LE 0xedb88320
#define g(x)   (CRCPOLY_LE >> x)
const unsigned long g_crc4table[16] =
{
           0,           g(3),           g(2),           g(2)^g(3),
        g(1),      g(1)^g(3),      g(1)^g(2),       g(1)^g(2)^g(3),
   g(0)     , g(0)^     g(3), g(0)^     g(2), g(0)     ^g(2)^g(3),
   g(0)^g(1), g(0)^g(1)^g(3), g(0)^g(1)^g(2), g(0)^g(1)^g(2)^g(3)
};

unsigned int CRC32WideFast2(const unsigned char* buf, unsigned int len)
{
   unsigned long crc = INIT_REFLECTED;

   while (len--)
   {

      crc = crc ^ *buf++;

      crc = (crc >> 4) ^ g_crc4table[(crc<<28) >> 28];
      crc = (crc >> 4) ^ g_crc4table[crc & 0xF];
   }

   return (crc ^= XOROT);
}

Автор:  ike [ Пет Дек 20, 2013 5:57 pm ]
Заглавие:  Re: CRC32

miro_atc написа:
Че тъпанарите от ST пак са си оставили ръцете, сложили хардуерно црц ама биг ендиан (идиоти :evil: )

Ами супер. Значе ще можеш да си битбангваш ethernet и да ползваш това хардуерното црц.

Автор:  bateAz [ Пет Дек 20, 2013 11:55 pm ]
Заглавие:  Re: CRC32

Miro, аз избягвам типа "int" по обясними причини: ползвам и 8, и 16, и 32 битови ядра.
Вместо него добре пасват char, short, long

Автор:  miro_atc [ Съб Дек 21, 2013 2:02 am ]
Заглавие:  Re: CRC32

bate, не гледай типовете... копирал съм квото ми падне ;-)

Иначе аз нямам проблем с int, просто не ползвам 8-бит отдавна...

Относно црц-тата общо взето стигнах до следните заключения:
- Побайтовия вариант дето масово циркулира из нета е тъпо решение за контролери. Не само че яде 1к за таблица, ами е и доста бавничък - при АРМ излиза някъде 10-на клока на сметнат байт. Задължително трябва да се добави оптимизация за смятане на думи, тогава пада под 6 клока/байт.
- Вариантът с нибъли/тетради ползва само 64 байта таблица и ако се добави ънролването на думи е 9.5 клока/байт, демек е по-бързо от стандартното решение и заема къде къде по-малко място.
- Побитовия вариант е поне 20 клока и не подлежи на оптимизация, така че не става. Всъшност 20 е оптимизираната версия с ънролнат цикъл на битовете, абе не става и тва е...
- Вариантът с хардуерната сметалка на ST се оказа по-добър отколкото очаквах, ако се разгъне цикъла да смята на по 32 байта, въпреки ревърсването на битове сметките отиват под 1 клок/байт... или поне се надявам, понеже ST нищо не споменават за waitstates...

Според производителите значи за АРМ-чета може да се обобщи така:
- При Луминари голямата таблица я има на РОМ така че решението побайтовия вариант + оптимизация на думи.
- При ST за големи обеми и ако няма нужда от мултитаскинг най-добре е хардуерната сметачка, оптимизирана на 32 байта плюс падване на тетради
- При Атмел някои имат сметачка и доколкото си спомням тя е ОК, а където няма избора е между тетради и побайтово, според това дали има място за голямата таблица... Естествено и в двата случая си трябва оптимизацията за сметки на думи...

И те така ;-)

Автор:  MYXATA [ Съб Дек 21, 2013 4:30 am ]
Заглавие:  Re: CRC32

ами на мен ми харесват два варианта
http://www.cs.miami.edu/~burt/learning/ ... c/crc-32.c

и този на апле:

http://www.opensource.apple.com/source/ ... rn/crc32.c

:)
като цяло са еднакви :)

Автор:  miro_atc [ Съб Дек 21, 2013 10:42 am ]
Заглавие:  Re: CRC32

@MYXATA, тва си е стандартното црц... само че както казах в тоя си вид не е особено подходящо (яде над 1к флаш и смята един байт за ~10 клока).

Поне тая преработка трябва да се направи:
Код:
   crc = 0xFFFFFFFF;
   while (((word = *(unsigned int *)message) & 0xFF) != 0) {
      crc = crc ^ word;
      crc = (crc >> 8) ^ table[crc & 0xFF];
      crc = (crc >> 8) ^ table[crc & 0xFF];
      crc = (crc >> 8) ^ table[crc & 0xFF];
      crc = (crc >> 8) ^ table[crc & 0xFF];
      message = message + 4;
   }
   return ~crc;


По-горе мисля дадох линк с вариант с цялата функция, т.е. първо смята на цели думи докато дължината е >=4 и после байт по байт в случай че не е кратно на 4. С тая преработка кодът се увеличава съвсем малко - около 30-40 байта, което е нищо на фона от 1К. Обаче бързодействието се вдига с 40% ;-)

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/