OVH Cloud OVH Cloud

[CRC] Pb dans la chaine a transmettre

12 réponses
Avatar
thierryabrard
Bonjour,

Je doit utiliser le calcul d'un CRC16 pour transmettre un fichier
ASCII et aussi pour envoyer des infos à un automate par protocole
JBus... L'algorithme du CRC fonctionne très bien... vérifié sur
plusieurs langages et avec plusieurs algos...

- Pour ce qui est du fichier ASCII, y a pas de soucis, la chaine de
caractère dont on calcul le CRC reste des caractères imprimables...

- Mais pour piloter mon automate Jbus... je dois envoyer des trames du
type : 01/06/00/0C/00/C7... et bien sûr en HEXA !!! Le problème c'est
que quand j'envoi dans ma fonction de calcul la chaine correspondante
: "\x01\x06\x00\x0C\x00\xC7"... Y a un pb au niveau du caractère Nul
0x00. Ma chaine de caractère s'arrete là et le calcul de CRC n'est pas
fait en totalité...

J'aimerais donc savoir qu'elle est la démarche à suivre pour envoyer
et calculer le CRC dans ce cas...

Merci...
TA.

______________________________________________
[RESONNEMENT DE MON PROGRAMME (!!!)]


[Fonction] TrameTx (char * Trame, unsigned int CRC_old)
{
unsigned int CRC_new;

printf ("%s",Trame);
CRC_new = CalculCRC16 ( Trame, CRC_old );
return (CRC_new);
}

[Fonction] CalculCRC16 ( char * Buf, unsigned int CRC)
{
... le calcul...
return (CRC);
}

puis j'utilise les fonctions comme ça :

CRC = TrameTx ("Hello world...",0xFFFF);
CRC = TrameTx ("Hello again !",CRC);
-> Le calcul (CRC final) est OK

CRC = TrameTx ("\x01\x06\x00\x0C...",0xFFFF);
-> PB !!!, CRC arreté à \x01\x06

2 réponses

1 2
Avatar
thierryabrard
Les fonctions traitant des chaines s'arrêtent au premier 0 rencontré. Ca
t'étonne? Ca ne devrait pas.


Pas de pbs lors de la lecture... la chaine s'arrête bien au caractere
mais j'ai été surpris que lors de l'ecriture aussi
("helloworld", le world n'est pas copié !).


Bidouille infâme qui te retombera desssus un jour ou l'autre.


C'est sur !
J'ai mis que c'était pas joli-joli...


unsigned char buf[128];
size_t w = 0;
char *s = "hello world";
unsigned checksum = chk16 (s, strlen (s));


le seul hic, c'est que donc si :

s = "x01x02x03x00x04x05x06";
chk16 (s,7);

le crc est calculé bon jusqu'à x00 puis après il est mal calculé
puisque la chaine n'est pas copiée entière en mémoire (arretée à ,
voir plus haut et mes posts précédents concernant le programme de
Horst K.)


/* MSB */
buf[w] = (checksum >> 8) & 0xFF;
w++;
/* LSB */
buf[w] = checksum & 0xFF;
w++;


ok
... apparament, on place dans les deux premiers emplacements du buf le
MSB puis LSB du CRC...

for (p = s; *p; p++)


pas ok
... p=s : quel est la signification ?
... *p : idem

int p ?
[?] boucle sur tout les caractères de s ?, même ceux après ? (voir
mon pb à ce sujet)

{
buf[w] = *p;
w++;
}


ok
je pense que tu places tout les caracteres de s dans buf

xmit (buf, w);


tu veux dire xdmp (buf,w); ?
c'est pour afficher caracteres par caracteres en code hexa... !?


Mais apparament, je ne peux pas rentrer une chaine complete avec un
à l'intérieur... je dois donc transmettre caracteres par caracteres.

merci pour les infos,
A+

Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', (Thierry Abrard) wrote:

Les fonctions traitant des chaines s'arrêtent au premier 0 rencontré. Ca
t'étonne? Ca ne devrait pas.


Pas de pbs lors de la lecture... la chaine s'arrête bien au caractere
mais j'ai été surpris que lors de l'ecriture aussi
("helloworld", le world n'est pas copié !).


C'est normal. La définition d'une chaine est "tableau de char terminée par un
0". Il n'y a aucun mystère. Le premier 0 rencontré est la fin de chaine.
Point.

unsigned char buf[128];
size_t w = 0;
char *s = "hello world";
unsigned checksum = chk16 (s, strlen (s));


le seul hic, c'est que donc si :

s = "x01x02x03x00x04x05x06";
chk16 (s,7);

le crc est calculé bon jusqu'à x00 puis après il est mal calculé
puisque la chaine n'est pas copiée entière en mémoire (arretée à ,
voir plus haut et mes posts précédents concernant le programme de
Horst K.)


Pas du tout. Rien n'est copié. On se contente de passer l'adresse et la
longueur, et c'est la fonction qui se débrouille. Evidemment, elle ne doit
pas s'arréter au premier 0 rencontré, mais lorsque le nombre de bytes à
traiter est atteint. D'où l'intérer du paramètre 'longueur'.


/* MSB */
buf[w] = (checksum >> 8) & 0xFF;
w++;
/* LSB */
buf[w] = checksum & 0xFF;
w++;


ok
... apparament, on place dans les deux premiers emplacements du buf le
MSB puis LSB du CRC...


<HS>
C'est une convention pour les formats externes (réseau). Mais tu fais ce que
tu veux, du moment que c'est conforme à une spécification écrite.
</>

for (p = s; *p; p++)


pas ok
... p=s : quel est la signification ?


Initialiser un pointeur 'p' avec la valeur d'un autre pointeur 's'.

... *p : idem


Pareil que p[0]. C'est la valeur pointée. C'est du C de base. Si tu ne
maitrises pas ça, je te conseille de reprendre le Kernighan & Ritchie
calmement, et point par point. (Réf. dans la FAQ).

int p ?


J'ai pas écrit ça. Ah, ok, ok, j'ai oublié de le définir, pardon.

char *p;

[?] boucle sur tout les caractères de s ?, même ceux après ? (voir
mon pb à ce sujet)


Non. Ici, je traite une chaine de caractères, donc je fais exprès de
m'arétter au premier 0 rencontré.

{
buf[w] = *p;
w++;
}


ok
je pense que tu places tout les caracteres de s dans buf


C'est ça.

Si on veut la même action, mais avec des données quelquonques (0-255) on
utilise la téchnique 'adresse, longueur', donc, une boucle for() avec un
indice:

unsigned char buf[128];
size_t w = 0;
char s[] = "helloworld";
size const = sizeof s - 1;
unsigned checksum = chk16 (s, size);
size_t i;

/* MSB */
buf[w] = (checksum >> 8) & 0xFF;
w++;
/* LSB */
buf[w] = checksum & 0xFF;
w++;

for (i = 0; i < size; i++)
{
buf[w] = s[i];
w++;
}


xmit (buf, w);


tu veux dire xdmp (buf,w); ?
c'est pour afficher caracteres par caracteres en code hexa... !?


Pourquoi pas, mais je pensais surtout à la fonction d'émission d'un bloc de
bytes. (en jargon de developpeurs telecom, 'xmit' signifie 'transmit', ou
'emettre')

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/


1 2