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

Software e Hardware para linha ARM

Moderadores: 51, guest2003, Renie, gpenga

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

Mensagempor Viktor » 26 Fev 2007 19:50

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
Viktor
Byte
 
Mensagens: 281
Registrado em: 12 Out 2006 11:33

Mensagempor tcpipchip » 26 Fev 2007 22:09

Uau

BARREL SHIFTER :)

Tcpipchip
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor Peters » 26 Fev 2007 22:16

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;

}
Avatar do usuário
Peters
Byte
 
Mensagens: 123
Registrado em: 12 Out 2006 11:42
Localização: Canoinhas, SC

Mensagempor Viktor » 27 Fev 2007 06:17

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.
Viktor
Byte
 
Mensagens: 281
Registrado em: 12 Out 2006 11:33

Mensagempor tcpipchip » 27 Fev 2007 21:39

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
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor Viktor » 28 Fev 2007 08:18

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.
Viktor
Byte
 
Mensagens: 281
Registrado em: 12 Out 2006 11:33

Mensagempor Viktor » 28 Fev 2007 09:31

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 !!!!!
Editado pela última vez por Viktor em 28 Fev 2007 18:02, em um total de 2 vezes.
Viktor
Byte
 
Mensagens: 281
Registrado em: 12 Out 2006 11:33

Mensagempor tcpipchip » 28 Fev 2007 14:25

Legal...

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

TCPIPCHIP
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor jeanfernandes » 01 Mar 2007 00:41

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....
Jean P. Fernandes - Eng. Eletrônico - (83) 2102-2116 - APEL - www.apel.com.br - Campina Grande - PB
jeanfernandes
Word
 
Mensagens: 539
Registrado em: 11 Out 2006 15:36
Localização: Campina Grande - PB

Mensagempor jeanfernandes » 01 Mar 2007 00:49

Procurando info sobre barrel shifter
achei esse site que é uma onda...

http://tams-www.informatik.uni-hamburg. ... index.html
Jean P. Fernandes - Eng. Eletrônico - (83) 2102-2116 - APEL - www.apel.com.br - Campina Grande - PB
jeanfernandes
Word
 
Mensagens: 539
Registrado em: 11 Out 2006 15:36
Localização: Campina Grande - PB

Mensagempor Viktor » 01 Mar 2007 10:32

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.
Viktor
Byte
 
Mensagens: 281
Registrado em: 12 Out 2006 11:33

Mensagempor Fábio Pereira » 01 Mar 2007 13:01

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é +
Fábio Pereira
embeddedsystems.io
Avatar do usuário
Fábio Pereira
Word
 
Mensagens: 674
Registrado em: 16 Out 2006 09:07
Localização: Kitchener, ON

Mensagempor tcpipchip » 01 Mar 2007 14:34

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
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor Viktor » 01 Mar 2007 16:15

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.
Viktor
Byte
 
Mensagens: 281
Registrado em: 12 Out 2006 11:33

Mensagempor tcpipchip » 01 Mar 2007 16:23

Tem razao.
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Próximo

Voltar para ARM

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x