Opération sur des types et appel de fonction

KurpeusLondon Messages postés 11 Date d'inscription lundi 5 janvier 2009 Statut Membre Dernière intervention 12 janvier 2009 - 5 janv. 2009 à 22:50
KurpeusLondon Messages postés 11 Date d'inscription lundi 5 janvier 2009 Statut Membre Dernière intervention 12 janvier 2009 - 6 janv. 2009 à 22:11
Bonsoir,

Je suis en train d'écrire un programme qui génére une trame sur le model MODBUS/JBUS. J'ai une fonction écrite par le groupe de travail qui calcul un CRC mais je n'arrive pas a m'en servir. J'ai pas codé depuis longtemps et mon C est un peu rouillé.

Voici la fonction en question :

unsigned short CRC16 ( puchMsg, usDataLen ) /* The function returns the CRC as a unsigned short type */
unsigned char *puchMsg ; /* message to calculate CRC upon */
unsigned short usDataLen ; /* quantity of bytes in message */

    {
    unsigned char uchCRCHi = 0xFF ; /* high byte of CRC initialized */
    unsigned char uchCRCLo = 0xFF ; /* low byte of CRC initialized */
    unsigned uIndex ; /* will index into CRC lookup table */
    while (usDataLen--) /* pass through message buffer */

        {
        uIndex = uchCRCLo ^ *puchMsg++ ; /* calculate the CRC */
        uchCRCLo = uchCRCHi ^ auchCRCHi[uIndex] ;
        uchCRCHi = auchCRCLo[uIndex] ;
        }
    return (uchCRCHi << 8 | uchCRCLo) ;

Quand j'essaye de m'en servir, j'ai un crash due a une erreure mémoire.

Je dois générer succéssivement des trames et les envoyer sur un port série.

La trame  que je dois générer fait 8 bytes CRC inclut : Slave add 2Hex | Function 2Hex | word  4Hex | data 4Hex | CRC 4 Hex|

j'utilise une structure auquel j'initialise les champs qui composeront ma trame

struct sFrame
{
     unsigned int champ1;
     unsigned int champ2;
     ...
     unsigned int champX
}

struct sFrame * pFrame = (struct *) malloc(sizeof(sFrame));

une fois que j'ai tous mes champs, je dois calculer mon CRC. Pour cela doit assembler ma trame pour l'envoyer a la fonction.

double frameOut * pFrameOut;

J'avais utiliser la fct sprintf( frame, "%x%x%x%x%x",  sFrame->champ1, sFrame->champ2 ..... sFrame->ChampX) mais cela ne semble pas marcher. J'ai donc essayer de faire su shift :

frameOut = sFrame->champ1 << 28 + sFrame->champ2 << 24 +sFrame->champ3<<16;

Or quand je fais cela j'obtient une erreure comme quoi le L-value est de type double

Les opérations sur les types je suis pas très au point. qu'est ce que je pourrais changer pour pouvoir utiliser la fonction CRC qui prend en entrée  :
unsigned char *puchMsg ; /* message to calculate CRC upon */

unsigned short usDataLen ; /* quantity of bytes in message */

sachant que je dois avoir un mot formaté dans le genre 0x050303740002

Eventuellement, je peux découper en deux mon mot hexa avant de l'envoyer a la fonction CRC et du coup faire deux appels a la fonction - byte high order et low order-

J'espère avoir été un minimum clair
Merci

2 réponses

uaip Messages postés 1466 Date d'inscription mardi 20 février 2007 Statut Membre Dernière intervention 7 février 2011
6 janv. 2009 à 21:51
Salut.
Soit j'ai mal compris ton algo, soit il n'est pas correct. Je vois que tu cherches à calculer le CRC-16, je te donne une méthode qui fonctionne pour le calcul de CRC sur une trame Modbus (pas testé pour Jbus, mais c'est pareil je crois).

#include <stdio.h>
#include <string.h>
int crc16(char *trame,int taille) {
    unsigned short i,n,retenue,crc=0xFFFF;
    for(i=0;i < taille;i++) {
        crc^=trame[i];
        for(n=0;n <= 7;n++) {
            retenue=crc & 1;
            crc=crc >> 1;
            if (retenue) crc^=0xA001;
        }
    }
    return crc;
}
Ensuite, tu n'as plus qu'à appeler la fonction dans un programme comme le montre cet exemple :
int main() {
    char trame[]="Salut";
    printf("Le CRC de '%s' est : %d\n",&trame,crc16(trame,strlen(trame)));
    return 0;
}
Par contre il renvoit le CRC de type entier (suffit de le convertir en héxa) et j'ai écrit ça de mémoire, donc j'ai testé le programme, il fonctionne, maintenant reste à savoir s'il retourne bien le CRC-16

Cordialement, uaip.
0
KurpeusLondon Messages postés 11 Date d'inscription lundi 5 janvier 2009 Statut Membre Dernière intervention 12 janvier 2009
6 janv. 2009 à 22:11
Merci pour ta réponse. Concernant l'ago du CRC16 il marche. C'est pas moi qui l'ai écrit c'est les mecs qui ont développé MODBUS. IL fait appelle a deux tableaux de valeurs que j'ai mis dans un .h et que j'avais pas précisé au dessus.

Par contre j'aimerai bien une petite précision sur les pointeurs. Si j'utilise une structure dont les éléments pointent sur d'autres structures comment je dois faire pour faire en sorte que l'adresse mémoire pointée par les éléments de ma super structure soit enregistré :

par exemple :

struct superStruct
{
                 struct sData * champs 1;
                 struct sData * champs 2;
}

struct sData * pData
{
         .......
}
struct superStruct * pSuperStruct = (struct superStruct *) malloc(sizeof(struct superStruct));
struct sData * pData = (struct sData *) malloc(sizeof(struct sData )); // structure crée dynamiquement dans une fonction et avec pData retourné

et j'aimerai avoir un truc  dans le genre

superStruct->pData = pData

Quand il s'agit de structure, je ne sais jamais ou il faut déréférencer.

Enfin quand on retourne un pointeur ( return pData) , renvoie t'il l'adresse du pointeur ou la valeur pointée par celui ci ?

Merci
0
Rejoignez-nous