STM32F103 - CRC

Başlatan z, 14 Mayıs 2014, 17:05:35

z

PC için yazacağım program bir veri dosyasına CRC bilgisi de ekleyecek. Ardından  bu dosya STM32F103 tarafından okunacak ve CRC donanımı kullanılarak verilerde bozukluk olup olmadıgını test edecek.

Daha önce CRC ile hiç uğraşmadım. PC tarafındaki yazılım için yardıma ihtiyacım var.

CRC-32 (Ethernet) polynomial: 0x4C11DB7

X26 + X23 + X22 + X16 + X12 + X11 + X10 +X8 + X7 + X5 + X4 + X2+ X1 +X0
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

#1
O kısmı anladım hocam da bu CRC işinin mantığını anlamam lazım.

İlk 32 bit datayı aldım. CRC bilmiyorum ama diyelimki hesapladım. Şimdi elimde bir CRC var.
İkinci 32 bit datayı aldım. Bu datayı CRC işlemine sokmadan önce daha önce hesapladığım CRC değerimi nerede kullanacağım?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

ErsinErce

#2
paketiniz için CRC hesaplıyorsunuz
paket+CRC şeklinde verinizi hattan transfer ediyorsunuz,
CRC kısmının son x byte olduğunu biliyorsunuz
son x byte' a kadar ki kısım yani gelen paket için CRC hesaplıyorsunuz
ve CRC leri birbiriyle karşılaştırıyorsunuz

aynı ise data bozulmamış
farklı ise data bozulmuştur

olay bu hocam

paket boyutu size kalmış ama ne çok büyük ne de çok küçük yapmaktan kaçınmak lazım

z

Ana felsefeyi anladım da detayları anlamadım.

Bulduğum hazır C kodları muhtemelen optimize kodlar. Optimize kodlardan ne yapıldığını anlamaya çalışmak çok zor oluyor.

Çok acemice daha doğrusu işin mantığını anlatmak için uzun uzun yazılmş kod bulabilsem çok iyi olacak.

-----------------

Diyelimki 2 byte data yollayacağım.

1. datayı aldık CRC hesapladık.
2. datayı aldık CRC hesaplayacağımız fakat ilk hesaplanan CRC işin içine girmeyecekmi?

En son hesaplanan CRC yi iki datanın sonuna ekledik 3 byte paket oluşturduk.

Ama altı çizgili kısım kafamı karıştırıyor.

Bir de bahsettiğim gibi hazır bir C kod varmı?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Erol YILMAZ

CRC her byte için değil her paket için bir kere hesaplanacak.

ErsinErce

paketin ilk byte'ında CRC'nin başlangıç noktası vardır.
paket devam ettikçe elde edilen değer ile hesaplanan CRC değişir
taki paket sonuna kadar

ilk hesaplanan CRC işin içine giriyor yani

CRC'yi en sonda hesaplamaya koyuluyoruz genelde ama her byte alımında da yapılabilir.

tabi dahili CRC hesaplayıcının davranışını iyi bilmek lazım
yoksa her byte için tek CRC hesaplamaya kalkarsa işimize gelmez

www.simplymodbus.ca/crc.xls
modbus için excel örneği net görmenize yardımcı olur hocam

Klein

ilk hesaplanan CRC işin içine girmeyecek hocam.  10 byte veri için 2 byte CRC hesapladınız.  12 yte olarak gönderdiniz. Karşı tarafta 10 byte için hesaplayıp son 2 byte ile karşılaştırdınız.  Aynen kontrol toplamı gibi. Kafanızı karıştıran şey nedir ki?

z

10 byte veri 80 bit. O zaman CRC hesabını 80 bit için bir kereye mahsuz mu yapacağım?

STM32F103 de CRC hesaplaması için 32 bit register var. Buradan anladığım 32 bit datayı yaz 32 bit CRC yi oku.

Tahminimce de bu CRC yi ve yeni datayı okuyup XOR vs işlemine tabii tutup sonucu CRC registerine yaz.
....
....
Böyle böyle devam et. Datalar bittiğinde en son CRC yi registerden oku işte bu bizim aradığımız CRC diye düşünüyorum.


Kafam gerçekten karışık. Bu iş için örnek bir program varmı? Zamanında picprojeye de bazı linkler vermişim ama şimdi o verdiklerimi beğenmiyorum.

-------------

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

magnetron

ST ' nin kendi peripheral library'sinde

( STM32F10x_StdPeriph_Examples ) klasöründe

bunun içinde bir örnek var

ona baktınız mı ?

z

Yok genellikle oralara hiç bakmıyorum ama bu kez bakayım.

Aşağıdaki dokuman sanırım iyi bir şeye benziyor.

http://www.hackersdelight.org/crc.pdf
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

X-Fi

Hesaplanacak veri ramde veya rom da ise başlangıç adresi ve uzunluğunu girerek o dizi için crc elde etmiş olursunuz. Ben bir ara bu konuda çalışma yapmıştım işinize yarayabilir.

http://www.coskunergan.com/bin-dosyalari-icin-crc32-hesaplama-yazilimi-c/
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

Klein

#11
Alıntı yapılan: z - 14 Mayıs 2014, 19:41:08
10 byte veri 80 bit. O zaman CRC hesabını 80 bit için bir kereye mahsuz mu yapacağım?

STM32F103 de CRC hesaplaması için 32 bit register var. Buradan anladığım 32 bit datayı yaz 32 bit CRC yi oku.

Tahminimce de bu CRC yi ve yeni datayı okuyup XOR vs işlemine tabii tutup sonucu CRC registerine yaz.
....
....
Böyle böyle devam et. Datalar bittiğinde en son CRC yi registerden oku işte bu bizim aradığımız CRC diye düşünüyorum.



Kafam gerçekten karışık. Bu iş için örnek bir program varmı? Zamanında picprojeye de bazı linkler vermişim ama şimdi o verdiklerimi beğenmiyorum.

-------------

Yok hocam tam öyle değil.  CRC->DRregisterne her yeni veriyi yazdığınızda, yeni veri ile daha önce hesaplanan CRC kombine ediliyor.  En son veriyi de yazdıktan sonra okuduğunuz değer ihtiyacınız olan CRC.  Yeni bir hesaplama iin CRC donanımını resetleyip, baştan başlıyorsunuz.

siz sadece DR registerini azıyorsunuz. XOR vs.. yok. En son veriden sonra da okuyorsunuz.

z

Evet exor vs yok,  dedigin gibi  bir onceki CRC degeri bir sonraki datalar icin kullaniliyormus. (Donanim tarafindan)

Son verdigim pdfi okumaya baslayinca kafamda bir seyler sekillenmeye basladi.

STMyi falan bir kanara birakip 8 bitlik sayilar icin konusacak olursak;

Yapilan bolme islemi aslinda. Amac kalani bulmak. Kafami kurcalayan mesela 1000 byte yollayacaksam  bu 8000 bitlik bir sayi demektir. 8000 bitlik sayi ornegin bizim 8 bitlik polinoma nasil bolunecek diye kafam karisiyordu ama bolge algoritmasini dusununce taslar oturmaya basladi.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

sadogan

#13
@z hocam
dallasın 8 bit crc hesbı fikir verebilir,
unsigned char crc_bits(int data)
{
  int8 i = (data ^ crc)&0xff;
  crc = 0;

  if(i & 1)   crc ^= 0x5e;
  if(i & 2)   crc ^= 0xbc;
  if(i & 4)   crc ^= 0x61;
  if(i & 8)   crc ^= 0xc2;
  if(i & 0x10)crc ^= 0x9d;
  if(i & 0x20)crc ^= 0x23;
  if(i & 0x40)crc ^= 0x46;
  if(i & 0x80)crc ^= 0x8c;
  return crc;
}


                   crc=0;
                  for(i=0;i<DATA_BOYU-1;i++)
                   {
                      crc=crc_bits(TxTxData[i]);
                   }
   
               TxData[DATA_BOYU]=crc;   

 

z

#14
CRC ile sorunum devam ediyor.

CM3 donanimin  hesapladigi CRC ile PC de delphi ile hesapladigim CRC sonucu birbirini tutmuyor.

CRC_CR den donanimi resetliyorum. Ardindan 32 bitlik verimi CRC_DR registerine yukluyorum. CRC_DR registerini gerisin geri okudugumda CRC degerini elde etmis oluyorum.

Bu sonucu ayni sekilde PC de elde edebilecegim kodu ariyorum.

Asagidaki dongude 7 yerine 31 mi yazmaliyim simdi aklima geldi.

function Crc32(Adres:pinteger):cardinal;
var
i,j, crc,mask:longword;
begin
        crc:= $FFFFFFFF;
        crc:= crc XOR Adres^;
        for j:= 7 downto 0 do
          begin
            mask:= -(crc AND 1);
            crc:= (crc div 2) XOR ($EDB88320 AND mask);
          end;
        result:= crc XOR $FFFFFFFF;
end;

Evet dongu degiskenini 7 yerine 31 yapinca dogru hesaplamaya basladi.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com