Página 1 de 2

CRC-16 (x^16 + x^15 + x^2 + 1)

MensagemEnviado: 26 Fev 2007 19:50
por Viktor
Para quem precisa calcular crc e não quer tabelas. Pode ser usado para calcular o crc no protocolo modbus


Entrada : r0 = crc
r1 = dado

Saída : r0 = novo crc


crc_16
eor r1,r0
and r1,#0xff
mov r0,r0, LSR #8
ldr r2,=0x6996
mov r3,r1
and r3,#0x0f
mov r3,r2, LSR r3
mov r4,r1, LSR #4
mov r4,r2, LSR r4
eor r3,r4
ands r3,#1
ldr r4,=0xc001
eorne r0,r4
eor r0,r1, LSL #6
eor r0,r1, LSL #7
bx lr

MensagemEnviado: 26 Fev 2007 22:09
por tcpipchip
Uau

BARREL SHIFTER :)

Tcpipchip

MensagemEnviado: 26 Fev 2007 22:16
por Peters
Em C, geralmente uso a seguinte rotina:


unsigned short CMessage::CalculateCRC16(unsigned int crcLength)
{
unsigned short crc = 0xFFFF;

for (unsigned int i=0; i<crcLength; i++)
{
unsigned short value = Buffer[i];

for (int bit=0; bit<8; bit++)
{
crc ^= (value & 0x01);
crc = ( crc & 0x01 ) ? ( crc >> 1 ) ^ 0x8408 : ( crc >> 1 );
value = value >> 1;
}
}

crc = crc ^ 0xFFFF;

return crc;

}

MensagemEnviado: 27 Fev 2007 06:17
por Viktor
Para usar com C trocar registrador r4 por outro, por exemplo r12. O r4 é usado pelo compilador e deve ser preservado. Essa rotina está escrita em ARM e THUMB2. Posso postar, caso queiram, uma levemente mais curta (consegui fazer uma simplificação) que serve apenas para ARM.

MensagemEnviado: 27 Fev 2007 21:39
por tcpipchip
Tambem evitem usar
unsigned short, isto, teoricamente, fará o programa ficar maior, pq o compilador terá que isolar os 16 bits mais significativos (na geração do código de máquina)

TCPIPCHIP

MensagemEnviado: 28 Fev 2007 08:18
por Viktor
Uma versão levemente mais curta :

eor r1,r0
and r1,#0xff
mov r0,r0, LSR #8
ldr r2,=0x6996
mov r3,r1
and r3,#0x0f
mov r3,r2, LSR r3
mov r8,r1, LSR #4
eor r3,r2, LSR r8
ands r3,#1
ldr r8,=0xc001
eorne r0,r8
eor r0,r1, LSL #6
eor r0,r1, LSL #7
bx lr

Uma versão em tabela é apenas uns 10 ciclos mais rápida e muito maior em tamanho.

MensagemEnviado: 28 Fev 2007 09:31
por Viktor
Pronto pessoal. Esta é mais curta que consigo fazer : 22 ciclos contando o retorno !!!!

eor r1,r0
and r1,#0xff
mov r0,r0, LSR #8
ldr r2,=(0x6996:SHL:16):OR: 0xc001
mov r3,r1
and r3,#0x0f
mov r3,r2, LSL r3
mov r8,r1, LSR #4
eors r3,r2, LSL r8
eormi r0,r2
eor r0,r1, LSL #6
eor r0,r1, LSL #7
bx lr

É apenas 7 ciclos mais lenta que uma por tabela em assembly que fiz !!!!!

MensagemEnviado: 28 Fev 2007 14:25
por tcpipchip
Legal...

Mas bota no lado para o pessoal o que fazem as instruções com BARREL SHIFTER

TCPIPCHIP

MensagemEnviado: 01 Mar 2007 00:41
por jeanfernandes
No caso do Unsigned short
basta definir __THUMB na declaracao da funcao eheheeheh
ai eh mais negocio

Esse trem de Barrel Shifter eh interessante. Acho que perdi essa aula kkkkk pior que encontrei o Prof. hoje.... 10 anos depois eheeheheh (ora 10 eehehehe foi eh mais)

Fuiz....

MensagemEnviado: 01 Mar 2007 00:49
por jeanfernandes
Procurando info sobre barrel shifter
achei esse site que é uma onda...

http://tams-www.informatik.uni-hamburg. ... index.html

MensagemEnviado: 01 Mar 2007 10:32
por Viktor
No caso do Unsigned short basta definir __THUMB na declaracao da funcao



Não entendi o que você quer dizer com isto com respeito à observação dado pelo TCPIPCHIP.

MensagemEnviado: 01 Mar 2007 13:01
por Fábio Pereira
Mas os ARMs têm instruções para manipulação de dados de 8, 16 e 32 bits.

Aliás, eles também possuem instruções para manipulação de dados signed e unsigned ;-)

Até +

MensagemEnviado: 01 Mar 2007 14:34
por tcpipchip
Sim Fábio concordo que tem em assembly.

Mas me refiro aos tipos de dados da linguagem C, por causa do alinhamento de memória do ARM.

Nao faz sentido declarar um tipo de dado de 16 bits.

TCPIPCHIP

MensagemEnviado: 01 Mar 2007 16:15
por Viktor
Nao faz sentido declarar um tipo de dado de 16 bits.


Faz quando você está curto de RAM e nos CORTEX, onde não precisa haver alinhamento em 32 bits.

MensagemEnviado: 01 Mar 2007 16:23
por tcpipchip
Tem razao.