2016-04-07 7 views
2

Обновление. См. Конец сообщения для рабочего кодаСделать CRC на соответствие stm32 с помощью программного обеспечения

Я уже злюсь с этим. Как я могу сделать контрольную сумму от блока CRC на stm32f103 в соответствии с реализацией программного обеспечения? Stm имеет полином 0x04C11DB7 и значение сброса 0xFFFFFFFF. Поэтому я попытался вычислить его в python.

Код для STM:

uint32_t crc32_hard_block(uint32_t *buf, uint32_t len) 
{ 
    CRC_ResetDR(); 
    uint32_t crc = CRC_CalcBlockCRC(buf, len); 
    return crc; 
} 

uint32_t buf[4] = {50, 10, 243, 147}; 
uint32_t crc_hard_block = crc32_hard_block(buf, 4); 

Код для питона:

custom_crc_table = {} 

def int_to_bytes(i): 
    return [(i >> 24) & 0xFF, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF] 

def reverse_int(i, w): 
    b = '{:0{width}b}'.format(i, width=w) 
    return int(b[::-1], 2) 


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 


def custom_crc32(buf, _poly): 

    global custom_crc_table 
    crc = 0xFFFFFFFF 

    for integer in buf: 
     b = int_to_bytes(integer) 

     for byte in b: 
      top = (crc >> 24) & 0xFF 
      crc = (crc << 8) | byte 
      crc = crc^custom_crc_table[top] 

    return crc, reverse_int(crc, 32) 

poly = 0x04C11DB7 
buf = [50, 10, 243, 147] 

generate_crc32_table(poly) 
custom_crc, rev = custom_crc32(buf, poly) 

print("Custom rev src  " + hex(rev)) 
print("Custom crc   " + hex(custom_crc)) 

Тестирование на массив [50, 10, 243, 147] дает мне выход:

В питона:

Custom rev src  0x344a9514f010200020100010100020301000203 
Custom crc   0x3010002030100020200020100010203ca2a548b #reversed 

Это определенно что-то не так с моим crc.

в СТМ:

0x491b3bf3 

UPDATE

Вот рабочий код для программного обеспечения стс, как на stm32f103 и код для stm32f103.

Python:

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 crc 

poly = 0x04C11DB7 
buf = [50, 10, 243, 147] 

generate_crc32_table(poly) 
crc_stm = crc32_stm(bytearray(buf)) 

Stm32f103:

#include <stm32f10x_crc.h>  

uint32_t crc32_native(char *bfr, int len, int clear) { 

    uint32_t crc; 
    int l = len/4; 
    uint32_t *p = (uint32_t*)bfr; 
    uint32_t x = p[l]; 

    if(clear) 
    { 
     CRC_ResetDR(); 
    } 

    while(l--) 
    { 
     crc = CRC_CalcCRC(*p++); 
    } 

    switch(len & 3) 
    { 
     case 1: crc = CRC_CalcCRC(x & 0x000000FF); break; 
     case 2: crc = CRC_CalcCRC(x & 0x0000FFFF); break; 
     case 3: crc = CRC_CalcCRC(x & 0x00FFFFFF); break; 
    } 

    return crc; 
} 
+0

Этот обновленный код для питона работ как шарм, но это довольно медленно. У вас есть идея ускорить его? – KyluAce

ответ

3
custom_crc_table = {} 

def int_to_bytes(i): 
    return [(i >> 24) & 0xFF, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF] 


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 custom_crc32(buf): 

    global custom_crc_table 
    crc = 0xffffffff 

    for integer in buf: 
     b = int_to_bytes(integer) 

     for byte in b: 
      crc = ((crc << 8) & 0xffffffff)^custom_crc_table[(crc >> 24)^byte] 

    return crc 

poly = 0x04C11DB7 
buf = [50, 10, 243, 147] 

generate_crc32_table(poly) 
custom_crc = custom_crc32(buf) 

print("Custom crc   " + hex(custom_crc)) 
+0

Спасибо! Не могли бы вы объяснить, почему 'custom_crc_table [(crc >> 24)^byte]'? Я только что прочитал Ross n Williams «Безболезненный, ориентированный на CRC», и там он использует самый значительный байт crc в качестве индекса. –

+0

Вы должны посмотреть на следующий раздел: «10. Немного запутанная реализация с таблицами». Это делает это, что является исключительным или входным байтом с высоким байтом CRC, чтобы получить индекс таблицы. Начало этого раздела говорит, почему. –