IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Lecture du COM2 au fil de l'eau


Sujet :

C

  1. #81
    Candidat au Club
    Inscrit en
    Novembre 2006
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Novembre 2006
    Messages : 54
    Points : 2
    Points
    2
    Par défaut
    La méthode pour tester l'intégrité des données reste à définir.
    Qu'entends tu par cette citation. Est ce que tu veux parler des essais sur la machines pour vérifier le fonctionnement du programmt complet?

  2. #82
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par 202UH
    Qu'entends tu par cette citation. Est ce que tu veux parler des essais sur la machines pour vérifier le fonctionnement du programmt complet?
    Non, ça, c'est l'intégration. On en a pas encore parlé.

    Je parle de ceci :
    Citation Envoyé par conception
    - contrôle des caractères perdus et si caractères perdus, initialisation du tableau et écriture de « 0000 » dans le fichier txt
    Il va falloir expliquer comment on fait ça.

    Ce genre de 'sous-entité fonctionnelle' (pour rester vague, en fait, on dit plutôt 'bloc fonctionnel' ou BF) fait l'objet elle même d'une définition (quoi) et d'une conception (comment). Je rappelle que le processus de définition/conception est récursif et aboutit à une sorte d'arbre dont les feuilles (éléments terminaux) sont les fonctions ou groupes de fonctions (unités fonctionnelles) qu'il ne reste plus qu'à coder (phase 3 : réalisation). Ceci apparait plus clairement lorsqu'on écrit l'algorithme formel.

    Dans les grosses réalisations, il n'est pas rare qu'un bloc fonctionnel devienne une unité d'exécution plus au moins autonome, et qu'il faille donc recourir à la programmation concurrente. (interruptions, processus, threads).

    3 - Réalisation

    L'arbre résultant de la conception va permettre d'organiser le développement en une successions d'unités fonctionnelles (UF) hiérarchisées. Certaines pourront être des composants logiciels déjà codés et validés :
    • bibliothèques standards,
    • bibliothèques d'extension (à éviter, car souvent non portables)
    • tierces (le plus souvent portables, par exemple conformes à POSIX.1)
    • personnelles


    3.1 Dépendances

    Si la conception a été bien faite (arborescence) les dépendances entre les UF ne devraient être qu'à sens unique.
    Par exemple (A, B et C sont des UF) :
    soit un arbre de dépendances
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     A
     /\
    v |
    B |
    | v
    | /
    v
    C
    Si une flèche remonte, c'est soit un problème de conception (UF de niveau bas), soit une réalité (UF de niveau haut, plus proche de l'applicatif) qui doit être traitée par callback ou par messagerie inter processus (ou tâche) selon les cas. Dans le dernier cas, cette UF est probablement un BF qui s'ignore...Ca peut révéler un problème de conception

    On commence donc par réaliser et tester les unités fonctionnelles les plus basses (celles qui ne dépendent pas des autres).

    3.2 Réalisation d'une unité fonctionnelle

    Comme il peut y avoir des dépendances entre les unités fonctionnelles, on commence évidemment par les fondations, c'est à dire par le niveau le plus bas.

    En général, une unité fonctionnelle correspond à un fichier d'implémentation (xxx.c) et son interface (xxx.h). Ne pas oublier non plus le fichier de tests unitaire (txxx.c).

    C'est là que commence véritablement le codage.

    Il faut commencer par établir une liste des unités fonctionnelles et les nommer (en général un nom court de 1 à 4 lettres, car il va servir de préfixe aux fonctions). Rien que cette opération n'est pas évidente...

    Par exemple :
    • xxx : fait ceci
    • yyy : fait cela

    Ensuite, on crée les fichiers correspondants :
    • xxx.h, xxx.c, txxx.c
    • yyy.h, yyy.c, tyyy.c

    Quelques conseils : http://emmanuel-delahaye.developpez.com/codage.htm
    Quelques exemples : http://emmanuel-delahaye.developpez.com/clib.htm

    Ensuite, si on utilise la (très recommandée) méthode dites de 'codage par les tests', on commence par réaliser le jeu de tests unitaire (en se basant sur la définition de l'UF) qui va servir à qualifier la ou les fonctions de l'unité fonctionnelle. C'est le rôle des fichiers txxx.c et tyyy.c. Ce sont des petits programmes complets et autonomes (main() etc.) qui utilisent exclusivement la ou les fonctions à tester et, si nécessaire, des composants externes réputés fiables.

    Ensuite, en gros, on écrit le code des fonctions et des interfaces "jusqu'à qu'à ce que le test sorte 'PASSED'".

    Evidemment, c'est une simplification réductrice, et ça ne veut pas dire qu'il faille écrire n'importe quoi, évidemment. Mais ça permet quand même d'écrire du code de qualité et dont le comportement est défini, si les contraintes du langages ont été respectées.

    Autre avantage, à la moindre modif (amélioration, simplification de l'algo, optimisation etc.) on relance le test unitaire (TU) et on voit tout de suite si le comportement a été modifié ou non.

    Un TU peut aussi comporter des tests de performances permettant de tester réellement l'optimisation. Bref, on travaille dans le sérieux. Fini la bidouille...

    Les UF de la fondation étant qualifiées, on peut ensuite en bâtir d'autres 'par-dessus', à la manière d'un véritable bâtiment.

    Lorsque toutes les 'briques' ont été bâties, testées et assemblées, on a terminé le codage.

    Ne reste plus qu'à le tester de manière autonome, puis dans son environnement réel (ce qu'on appelle l'intégration : phase 4) en terme d'ergonomie, de comportement, de stabilité, tenue aux erreurs, dans les conditions normales, extrêmes, hors normes...

    Puis à vérifier sa conformité au cahier des charges (5-validation) en reprenant et en vérifiant point par point les fonctionnalités exigées. C'est le fameux cahier de recette qui permet au fournisseur de se faire payer si le client le signe. (gros travail: gros cahier de manip, beaucoup de manips, certaines à faire devant le client, aspect juridique : le fournisseur signe le document de recette et engage donc sa responsabilité...).

    Les dernières (et rares en principe) corrections faites, on a alors le produit final conforme aux exigences du client.

  3. #83
    Candidat au Club
    Inscrit en
    Novembre 2006
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Novembre 2006
    Messages : 54
    Points : 2
    Points
    2
    Par défaut
    - contrôle des caractères perdus et si caractères perdus, initialisation du tableau et écriture de « 0000 » dans le fichier txt
    Pour le contrôle des caractères perdus, après avoir enregistré nos 4 caractères dans le tableau résultat:
    - contrôle si le tableau caractère contient 1 ou plusieurs éspaces à la place des caractères :
    - si oui, écriture "0000" dans le fichier txt
    - si non, écriture de la chaîne réceptionnée dans le fichier txt.

    La méthode pour détecter l'absence de EOL reste à spécifier
    - écriture des caractères reçus dans le tableau
    - si indice tableau i>41, alors EOL perdu
    - initialisation tableau
    - ecriture "0000" dans fichier txt

    Est ce que c'est bon?

  4. #84
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par 202UH
    Pour le contrôle des caractères perdus, après avoir enregistré nos 4 caractères dans le tableau résultat:
    - contrôle si le tableau caractère contient 1 ou plusieurs éspaces à la place des caractères :
    - si oui, écriture "0000" dans le fichier txt
    - si non, écriture de la chaîne réceptionnée dans le fichier txt.


    - écriture des caractères reçus dans le tableau
    - si indice tableau i>41, alors EOL perdu
    - initialisation tableau
    - ecriture "0000" dans fichier txt

    Est ce que c'est bon?
    A moins d'être très expérimenté dans ce domaine précis (en gros de l'avoir déjà traité), il est difficile de répondre honnêtement à cette question par oui ou par non.

    Premier réflexe un peu goret : "OK, on va faire comme ça. On verra bien en intégration". Genre, je refile le bébé, je botte en touche...

    Outre que cette attitude est douteuse sur le plan éthique, si ça ne fonctionne pas bien (comportement instable, perte de données inacceptable), le cout de la correction risque d'être prohibitif en temps, notamment.

    C'est là que les méthodes modernes de développement font intervenir une notion un peu nouvelle qui est le 'maquettage'.

    On écrit vite fait bien fait (le contraire du quick'n dirty), un 'snippet' (petit bout de code) qui va chercher à vérifier le comportement suspect par simulation. (Je crois que tu l'avais plus ou moins fait déjà). C'est une démarche qui ressemble à un test unitaire, sauf que là, il ne sert (à priori) qu'à valider une solution.

    On va donc imaginer un certain nombre de scénarios, c'est à dire des séquences de caractères normales, puis altérée , et tester si l'algorithme qu'on a imaginé résiste bien à toutes ces situations.

    Ce travail 'non planifié' qui peut prendre une certain temps, voire un temps certain, peut s'avérer décisif quand à la qualité du produit. En effet, si un problème apparaissait à ce moment là, le cout de la modification resterais très faible. (quelques lignes à modifier ou à ajouter dans le document de conception)

    D'autre part, le travail réalisé n'est pas 'jetable', car, si il a été bien fait, il pourra avantageusement être récupéré en phase de réalisation.

    pour la petite histoire, je travaille comme ça naturellement, et longtemps après, tel Monsieur Jourdain qui ignorait qu'il faisait de la prose, j'ai appris que c'était une pratique conseillée par les méthodes de développement modernes dites 'agiles' (comme eXtrem Programming, par exemple).

  5. #85
    Candidat au Club
    Inscrit en
    Novembre 2006
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Novembre 2006
    Messages : 54
    Points : 2
    Points
    2
    Par défaut
    Premier reflexe un peu goret : "OK, on va faire comme ça. On verra bien en integration". Genre, je refile le bébé, je botte en touche...
    Si tu a une solution meilleure pour les contrôles, explique comment tu vois ça. Je ne peut plus discuter longtemps. Il faut gagner du temps pour que je puisse faire mon rapport car :
    1. mon exam a été avancé au 11/12/06
    2. mon tuteur voudrai absolument voir tourner quelque chose, même si ce n'est pas parfait

  6. #86
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par 202UH
    Si tu a une solution meilleure pour les contrôles, explique comment tu vois ça.
    A moins de faire une étude sérieuse comme je te l'ai suggéré, non, je n'ai pas de meilleure solution pour le moment.
    Je ne peut plus discuter longtemps. Il faut gagner du temps pour que je puisse faire mon rapport car :
    1. mon exam a été avancé au 11/12/06
    2. mon tuteur voudrai absolument voir tourner quelque chose, même si ce n'est pas parfait
    Oui, je comprends, et c'est une bonne chose. Il faut montrer une version stable, en précisant bien, par exemple quel telle ou telle condition de fonctionnement particulière n'a pas été testée.

    Pour le moment, fait ce que tu as prévu.

  7. #87
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    (comme eXterm Programming, par exemple).
    eXtreme Programming. Le Xterm, c'est un type de console

  8. #88
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par DaZumba
    eXtreme Programming. Le Xterm, c'est un type de console
    Déjà fatigué le matin, ça promet...

    Merci, je corrige.

    J'ai constaté que ce thread (quasiment un dialogue) avait l'air d'être très lu ! Si ça peut rendre service à d'autres, tant mieux...

  9. #89
    Candidat au Club
    Inscrit en
    Novembre 2006
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Novembre 2006
    Messages : 54
    Points : 2
    Points
    2
    Par défaut
    J'ai calmé un peut mon tuteur de stage et ses collègues. Je leur ai redonné le sourire en leur fesant un éssais sur leur machine. J'ai juste fais une boucle do dans une boucle infinie while(1); pour lire le port comme et afficher la partie de la trame qui les interesse. Quand ils ont vu apparaître à l'écran 1672, puis1724, puis 1709, ils avaient le sourire jusqu'au oreilles. Je leur ai présisé qu'il n'y avait encore pas de contrôle des caractères reçus et du EOL, et l'écriture dans un fichier txt qui permettra la réception des données avec WinCC, mais que ça allais venir bientôt.
    j'ai eu comme réponse :
    Très bien, mais vite!
    Voilà le programme que j'ai éssayeé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
     
    #include <stdio.h>
    #include <conio.h>
    #include <string.h>
    /****************************/
    /* Registres UART port COM2 */
    /****************************/
     
    #define ESC     0x1b
    #define THR_RBR 0x2F8
    #define IER     0x2F9
    #define IIR     0x2FA
    #define LCR     0x2FB
    #define MCR     0x2FC
    #define LSR     0x2FD
    #define MSR     0x2FE
     
    /****************************/
    /* ParamŠtres de la liaison */
    /****************************/
     
    #define DONNE_8     0x03
    #define STOP_1      0x00
    #define NONE        0x00
    #define DLAB	    0x80
    #define RAZ_DLAB    0x7F
    #define _9600_BAUDS   12
    #define  INTR	    0x23
     
    unsigned char init_liaison;
    int fin;
     
    /************************/
    /* Programme principale */
    /************************/
     
    void main()
      {
        clrscr();
     
    /*****************************************************************/
    /* Init port s‚rie : 8 bits donn‚es, 1 bit stop, parit‚ aucune,  */
    /* 9600 bauds et positionnement de DLAB pour faire la s‚lection  */
    /* de la vitesse de transmission                                 */
    /*****************************************************************/
     
        outportb(IER,0x01);
        init_liaison = DONNE_8|STOP_1|NONE|DLAB;
        outportb(LCR,init_liaison);
     
    /**************************************************************/
    /* Configuration de la vitesse 9600 bauds et RAZ bit 7 du LCR */
    /**************************************************************/
     
        outportb(THR_RBR,_9600_BAUDS);
        init_liaison &= RAZ_DLAB;
     
    /**********************************************************************/
    /* Envoie … nouveau la configuration au LCR avec le bit 7 (DLAB) … 0  */
    /**********************************************************************/
     
        outportb(LCR,init_liaison);
     
    /***********************/
    /* Boucle de r‚ception */
    /***********************/
     
    /* Declaration des variables et de la trame
       mise … 0 de l'indice */
     
        #define EOL 10
        char trame_lue[41];
        int i = 0;
        int c;
     
    /* Boucle infinie */
     
    while (1)
      {
     
    /* boucle de lecture de la trame tant que != EOL */
     
        do
          {
    /* reception caractere */
     
     
    	if (inportb (LSR) & 0x01)
    	 {
    	   c = inportb (THR_RBR);
    	   trame_lue[i] = c;
    	   i++;
    	 }
           }
     
         while (c != EOL);
     
    /* Si EOL atteint */
     
    	if (c == EOL)
    	 {
    	  clrscr();
    /* Traitement de la trame */
     
    	   trame_lue[i-1] = 0;
    	     {
    	      char resultat[6] = "";
    	      strncat (resultat, trame_lue + 11, 4);
    	      printf ("%s", resultat);
    	     }
     
    	   i = 0;
    	   c = 0;
    	 }
     
     
    	if (i > 41)
    	 {
    	   i = 0;
    	 }
      }
     
        return;
    }

  10. #90
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par 202UH
    Voilà le programme que j'ai éssayeé :
    - L'indentation est... améliorable...
    - Ne pas mettre d'accents dans le code souce c'est pas portable.
    - _9600_BAUDS est très laid. Pour être coherent avec les autres identificateurs du même genre (DONNE_8 etc.), BAUDS_9600 ou BDS_9600 serait plus adéquate...
    - INTR n'est pas utilisé
    - L'organisation des constantes est, disons, erratique...
    - La globale fin n'est pas utilisée
    - main() retourne int. Toujours. Il faut donc un return 0; (le fait qu'on soit dans une boucle 'blanche' est provisoire. On devrait pouvoir sortir proprement par une touche clavier genre ESC).
    - c n'est pas initialisé. Il peut être local à la boucle principale...
    - la globale init_liaison n'est pas justifiée. Elle peut être locale. Le type char tout seul n'apporte pas de gain mémoire et ajoute du code pour rien. Préférer unsigned[ int]
    - L'algorithme n'a pas été suivi à la lettre, ce qui rend le code inutilement
    compliqué. CAY MAL ! Si l'algo est faux, il faut le dire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
     
    #include <stdio.h>
    #include <string.h>
     
    #ifdef CODEBLOCKS
    #define outportb(port, data) printf ("[%04X]<-%02X\n", (unsigned) (port), (unsigned) (data))
    #define inportb(port) printf ("[%04X]==%02X\n", (unsigned) (port), (unsigned) 0)
    #else
    #include <dos.h>
    #endif
     
     
    /****************************/
    /* Registres UART port COM2 */
    /****************************/
     
    #define ESC     0x1b
    #define THR_RBR 0x2F8
    #define IER     0x2F9
    #define IIR     0x2FA
    #define LCR     0x2FB
    #define MCR     0x2FC
    #define LSR     0x2FD
    #define MSR     0x2FE
     
    /* bits des registres */
    #define DLAB	    0x80
    #define RAZ_DLAB    (~DLAB)
     
     
    /****************************/
    /* ParamŠtres de la liaison */
    /****************************/
     
    #define DONNE_8     0x03
    #define STOP_1      0x00
    #define NONE        0x00
    #define BDS_9600   12
     
    /************************/
    /* Programme principale */
    /************************/
     
    int main (void)
    {
    /*****************************************************************/
    /* Init port s‚rie : 8 bits donn‚es, 1 bit stop, parit‚ aucune,  */
    /* 9600 bauds et positionnement de DLAB pour faire la s‚lection  */
    /* de la vitesse de transmission                                 */
    /*****************************************************************/
       outportb (IER, 0x01);
       {
          unsigned init_liaison;
          init_liaison = DONNE_8 | STOP_1 | NONE | DLAB;
          outportb (LCR, init_liaison);
     
    /**************************************************************/
    /* Configuration de la vitesse 9600 bauds et RAZ bit 7 du LCR */
    /**************************************************************/
          outportb (THR_RBR, BDS_9600);
          init_liaison &= RAZ_DLAB;
     
    /**********************************************************************/
    /* Envoie … nouveau la configuration au LCR avec le bit 7 (DLAB) … 0  */
    /**********************************************************************/
          outportb (LCR, init_liaison);
       }
     
    /***********************/
    /* Boucle de r‚ception */
    /***********************/
     
    /* Declaration des variables et de la trame
       mise … 0 de l'indice */
     
    #define EOL 10
       char trame_lue[41];
       int i = 0;
     
    /* Boucle infinie */
     
       while (1)
       {
          int c = 0;
    /* reception caractere */
          if (inportb (LSR) & 0x01)
          {
             c = inportb (THR_RBR);
     
             /* Si EOL atteint */
             if (c == EOL)
             {
                /* fermeture de la chaine */
                trame_lue[i] = 0;
     
                /* pret a recevoir une nouvelle trame */
                i = 0;
     
                /* Traitement de la trame */
                {
                   char resultat[6] = "";
                   strncat (resultat, trame_lue + 11, 4);
                   printf ("%s\n", resultat);
                }
             }
             else
             {
                trame_lue[i] = c;
                i++;
     
                /* garde-fou */
                if (i > 41)
                {
                   i = 0;
                }
             }
          }
       }
       return 0;
    }

  11. #91
    Candidat au Club
    Inscrit en
    Novembre 2006
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Novembre 2006
    Messages : 54
    Points : 2
    Points
    2
    Par défaut
    #ifdef CODEBLOCKS
    #define outportb(port, data) printf ("[%04X]<-%02X\n", (unsigned) (port), (unsigned) (data))
    #define inportb(port) printf ("[%04X]==%02X\n", (unsigned) (port), (unsigned) 0)
    #else
    #include <dos.h>
    #endif
    Pourquoi toute ces déclaration? Peut tu m'expliquer!



    Avant de lire entièrement ton dernier message, j'avais corrigé BAUDS_9600 et suprimé le INTR qui n'est pas utilisé. Pour donner un peut plus de clarté au programme, j'ai créé une routine init_com2, mais quand je l'appelle dans le main(), il me donne une err de syntaxe sur init_com2(void);
    Or, j'ai appliquer les cours qu'on nous avait donnés sur la déclaration et l'appelle des routines. Pourquoi l'erreur?


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
     
    #include <stdio.h>
    #include <conio.h>
    #include <string.h>
     
    /*****************************************************************/
    /* Init port s‚rie : 8 bits donn‚es, 1 bit stop, parit‚ aucune,  */
    /* 9600 bauds et positionnement de DLAB pour faire la s‚lection  */
    /* de la vitesse de transmission                                 */
    /*****************************************************************/
     
    void init_com2(void)
       {
        unsigned char init_liaison;
        int fin;
     
    /****************************/
    /* Registres UART port COM2 */
    /****************************/
     
     
        #define ESC     0x1b
        #define THR_RBR 0x2F8
        #define IER     0x2F9
        #define IIR     0x2FA
        #define LCR     0x2FB
        #define MCR     0x2FC
        #define LSR     0x2FD
        #define MSR     0x2FE
     
    /****************************/
    /* ParamŠtres de la liaison */
    /****************************/
     
        #define DONNE_8     0x03
        #define STOP_1      0x00
        #define NONE        0x00
        #define DLAB        0x80
        #define RAZ_DLAB    0x7F
        #define BAUDS_9600    12
     
     
        outportb(IER,0x01);
        init_liaison = DONNE_8|STOP_1|NONE|DLAB;
        outportb(LCR,init_liaison);
     
    /**************************************************************/
    /* Configuration de la vitesse 9600 bauds et RAZ bit 7 du LCR */
    /**************************************************************/
     
        outportb(THR_RBR,BAUDS_9600);
        init_liaison &= RAZ_DLAB;
     
    /**********************************************************************/
    /* Envoie … nouveau la configuration au LCR avec le bit 7 (DLAB) … 0  */
    /**********************************************************************/
     
        outportb(LCR,init_liaison);
     
       }
     
     
    /************************/
    /* Programme principale */
    /************************/
     
    int main()
       {
         init_com2(void);
     
         clrscr();
     
     
     
    /***********************/
    /* Boucle de r‚ception */
    /***********************/
     
    /* Declaration des variables et de la trame
       mise … 0 de l'indice */
     
        #define EOL 10
        char trame_lue[41];
        int i = 0;
        int c;
     
    /* Boucle infinie */
     
    while (1)
      {
     
    /* boucle de lecture de la trame tant que != EOL */
     
        do
          {
    /* reception caractere */
     
     
    	if (inportb (LSR) & 0x01)
    	 {
    	   c = inportb (THR_RBR);
    	   trame_lue[i] = c;
    	   i++;
    	 }
           }
     
         while (c != EOL);
     
    /* Si EOL atteint */
     
    	if (c == EOL)
    	 {
    	   clrscr();
    /* Traitement de la trame */
     
    	   trame_lue[i-1] = 0;
    	     {
    	      char resultat[6] = "";
    	      strncat (resultat, trame_lue + 11, 4);
         //	      printf ("%s", resultat);
     
    /* Enregistrement du resultat dans un fichier */
     
    	      FILE *fichier;
    	      fichier = fopen("C:\\aauser\\data.txt", "w");
     
    	      if (fichier == NULL)
    	       {
    		 printf(" impossible d'‚crire");
    	       }
     
    	      else
    		{
    		   fprintf (fichier, "%s", resultat);
    		   fclose (fichier);
    		}
     
    	     }
     
    	   i = 0;
    	   c = 0;
     
    	 }
     
     
    	if (i > 41)
    	 {
    	   i = 0;
    	 }
      }
     
        return 0;
    }

  12. #92
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Citation Envoyé par 202UH
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #ifdef CODEBLOCKS
    #define outportb(port, data) printf ("[%04X]<-%02X\n", (unsigned) (port), (unsigned) (data))
    #define inportb(port) printf ("[%04X]==%02X\n", (unsigned) (port), (unsigned) 0)
    #else
    #include <dos.h>
    #endif
    Pourquoi toutes ces déclarations ? Peux-tu m'expliquer !
    Comme Emmanuel ne dispose pas de outportb() et intportb() sous Code::Blocks, il a fait des macros qui affichent sur la console les données envoyées avec outportb()...
    Quant à la macro pour inportb(), je pense qu'elle est moins pensée que l'autre, puisqu'elle affiche toujours "[(adresse)]==00" et retourne toujours 11 (valeur de retour de printf())...

  13. #93
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par 202UH
    Pourquoi toute ces déclaration? Peut tu m'expliquer!
    Je suis sous Code::Blocks (un IDE gratuit et performant pour Windows et Linux), alors je n'ai pas <dos.h>, donc je n'ai pas outportb() et inportb(). Alors je simule... (en gros, je remplace par un printf())

    Pour donner un peut plus de clarté au programme, j'ai créé une routine init_com2, mais quand je l'appelle dans le main(), il me donne une err de syntaxe sur init_com2(void);
    Or, j'ai appliquer les cours qu'on nous avait donnés sur la déclaration et l'appelle des routines. Pourquoi l'erreur?
    Quand on appelle une fonction, on ne met pas le type :

  14. #94
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Médinoc
    Comme Emmanuel ne dispose pas de outportb() et intportb() sous Code::Blocks, il a fait des macros qui affichent sur la console les données envoyées avec outportb()...
    Quant à la macro pour inportb(), je pense qu'elle est moins pensée que l'autre, puisqu'elle affiche toujours "[(adresse)]==00" et retourne toujours 11 (valeur de retour de printf())...
    Oui, c'est provisoire. J'avais l'intention de simuler l'UART... Dans un premier temps, je voulais surtout que ça compile, ça m'a permis de simplifier le code...

  15. #95
    Candidat au Club
    Inscrit en
    Novembre 2006
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Novembre 2006
    Messages : 54
    Points : 2
    Points
    2
    Par défaut
    J'ai encore 2 petites questions :
    1. Pourquoi chez moi le programme fonctionne alors que je n'ai pas déclaré la bibliothèque dos?

    2. Comment programmer le contrôle des caractères perdus?

  16. #96
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par 202UH
    J'ai encore 2 petites questions :
    1. Pourquoi chez moi le programme fonctionne alors que je n'ai pas déclaré la bibliothèque dos?
    Gné ? <dos.h> n'est pas une bibliothèque. C'est un fichier d'interface (ou d'en-tête). Il contient le prototype des fonctions. Les fonctions elle-mêmes (implémentations) sont dans un fichier exécutable appelé bibliothèque.

    http://emmanuel-delahaye.developpez.....htm#prototype
    http://emmanuel-delahaye.developpez....m#bibliotheque

    Essaye en mode méchant (de mémoire : settings/compiler/warnings/display all)

    2. Comment programmer le contrôle des caractères perdus?
    En vérifiant la position des caractères connus dans la chaine reçue. A part les 4 caractères indiquant la valeur, les autres devraient toujours être identiques. Avec 1 ou 2 strncmp(), on devrait pouvoir vérifier...

    Si on reçoit autre chose, c'est qu'il y a un problème de transmission et qu'on est décalé... La valeur sera fausse.

  17. #97
    Candidat au Club
    Inscrit en
    Novembre 2006
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Novembre 2006
    Messages : 54
    Points : 2
    Points
    2
    Par défaut
    En vérifiant la position des caractères connus dans la chaine reçue. A part les 4 caractères indiquant la valeur, les autres devraient toujours être identiques. Avec 1 ou 2 strncmp(), on devrait pouvoir vérifier...
    J'ai suivi tes conseilles et j'ai bataillé toute la soirée pour reprendre mon programme. J'ai créé des routines que je rappelle quand il me les fauts et j'ai réussi à rajouter la routine qui s'occupe du contrôle des caractères. Pour essayer le progr. j'ai rempacé toute la partie com2 par de la saisie clavier avec la fonction getch(). Quand je saisi ma trame, le résultat s'écrit correctement dans fichier txt et quand je fais une erreur, il me met bien "0000" dans le fichier.

    Je joints le programme complet pour que tu puisses me dire ce que tu penses de l'ergonomie du programme.
    PS : pourrais tu me rajouter la sortie propre avec ESC, je ne vois pas comment faire. Merci...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
     
    #include <stdio.h>
    #include <conio.h>
    #include <string.h>
    char trame_lue[41];
    char resultat[6] = "";
    char erreur[5] = "0000";
     
    /*****************************************************************/
    /* Init port s‚rie : 8 bits donn‚es, 1 bit stop, parit‚ aucune,  */
    /* 9600 bauds et positionnement de DLAB pour faire la s‚lection  */
    /* de la vitesse de transmission                                 */
    /*****************************************************************/
     
    void init_com2(void)
       {
         /****************************/
         /* Registres UART port COM2 */
         /****************************/
     
         #define ESC     0x1b
         #define THR_RBR 0x2F8
         #define IER     0x2F9
         #define IIR     0x2FA
         #define LCR     0x2FB
         #define MCR     0x2FC
         #define LSR     0x2FD
         #define MSR     0x2FE
     
         /**********************/
         /* Bites de registres */
         /**********************/
     
         #define DLAB	    0x80
         #define RAZ_DLAB    (~DLAB)
     
         /****************************/
         /* ParamŠtres de la liaison */
         /****************************/
     
         #define DONNE_8     0x03
         #define STOP_1      0x00
         #define NONE        0x00
         #define BAUDS_9600    12
     
     
         outportb(IER,0x01);
         unsigned init_liaison;
         init_liaison = DONNE_8|STOP_1|NONE|DLAB;
         outportb(LCR,init_liaison);
     
         /******************************************/
         /* Configuration de la vitesse 9600 bauds */
         /* et RAZ bit 7 du LCR                    */
         /******************************************/
     
         outportb(THR_RBR,BAUDS_9600);
         init_liaison &= RAZ_DLAB;
     
         /********************************************/
         /* Envoie a nouveau la configuration au LCR */
         /* avec le bit 7 (DLAB) a 0                 */
         /********************************************/
     
         outportb(LCR,init_liaison);
       }
     
    /*****************************************************/
    /* Sous programme ecriture de la tame dans 1 fichier */
    /*****************************************************/
     
    void ecriture_fichier(void)
       {
         FILE *fichier;
         fichier = fopen("C:\\aauser\\data.txt", "w");
     
         if (fichier == NULL)
          {
    	printf(" impossible d'‚crire");
          }
     
          else
    	 {
    	   fprintf (fichier, "%s", resultat);
    	   fclose (fichier);
    	 }
     
       }
     
    /**********************************/
    /* Controle des caracteres perdus */
    /**********************************/
     
    void controle_caract(void)
       {
         int compare;
         char trame_ref1[12] = "<16>:(PB): ";
         char trame_ref2[6] = " l/m";
     
         char trame_verif1[12] = "";
         char trame_verif2[6] = "";
     
         strncat (trame_verif1, trame_lue + 0, 11);
         strncat (trame_verif2, trame_lue + 15, 4);
     
         compare = strncmp (trame_verif1, trame_ref1, 12);
         if (compare == 0)
          {
    	compare = strncmp (trame_verif2, trame_ref2, 5);
    	if (compare ==0)
    	 {
    	   ecriture_fichier();
    	 }
     
    	else
    	   {
    	     strcpy (resultat, erreur);
    	     ecriture_fichier();
    	   }
           }
     
         else
    	{
    	  strcpy (resultat, erreur);
    	  ecriture_fichier();
    	}
       }
     
     
    /************************/
    /* Programme principale */
    /************************/
     
     
    int main()
      {
        init_com2();
        clrscr();
     
        /***********************/
        /* Boucle de reception */
        /***********************/
     
        /* Declaration des variables et de la trame
           mise a 0 de l'indice */
     
        #define EOL 10
        int i = 0;
     
        /* Boucle infinie */
        while (1)
    	{
    	  int c;
     
    	  /* Reception caractere */
     
    	  if (inportb (LSR) & 0x01)
    	   {
    	     c = inportb (THR_RBR);
    	     /* Si EOL atteint */
    	     if (c == EOL)
    	      {
    		/* Fermeture de la chaine */
    		trame_lue[i] = 0;
     
    		/* Pres a recevoir une nouvelle trame */
    		i = 0;
     
    		/* Traitement de la trame */
    		strncat (resultat, trame_lue + 11, 4);
    		controle_caract();
    	      }
     
    	     else
    		{
    		  trame_lue[i] = c;
    		  i++;
     
    		  /* Programmation du garde fou */
    		  if (i > 41)
    		   {
    		     i = 0;
    		   }
    		}
    	    }
    	}
      return 0;
    }

  18. #98
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par 202UH
    Je joints le programme complet pour que tu puisses me dire ce que tu penses de l'ergonomie du programme.
    Bonne idée, les fonctions.
    • L'indentation est améliorable. Régler son éditeur de texte pour qu'il remplace les tabulations par N espaces (2 à 4. Chez moi, c'est 3).
    • la définition de ESC n'a rien à faire dans la liste des registres.
    • /* Bites de registres */ Ahem... "bits"
    • outportb (IER, 0x01); Ca fait quoi ça ? IER, c'est le Interrupt Enable Register. Ca fout la trouille !
    • Je suis étonné que tu ais pu définir 'init_liaison' après une instruction. Tu ne serais pas en train de compiler en C++ ? L'extension de ton fichier source est bien .c et non .cpp ni .C ?
    • La fonction de contrôle des caractères est un peu trop compliquée. On a pas besoin de toutes ces recopies. Si j'ai évoqué strncmp() au lieu de strcmp(), c'est précisément parce qu'elle permet de comparer directement avec une portion de la chaine reçue avec une chaine de référence. Je suis un peu effrayé par ta faible connaissance du langage C et de ses fonctions standards...
    • L'algorithme est correct mais un peu redondant. Tu peux 'factoriser' la fin de chaque branche des if, puisqu'elle est identique.
    • Il faut aussi apprendre à automatiser les calculs de taille avec sizeof.
    • Il est bon que les objets invariants (par exemple, ici, les 2 tableaux de char contenant les chaines de référence) soient définis 'const'. Ca aide à l'optimisation du code et le compilateur peut vérifier si on tente de les modifier (ce qui serait une erreur).
    • Lorsqu'une fonction n'a pas de paramètre (main() en l'occurrence), on le précise avec void : int main (void)
    • /* Pres a recevoir une nouvelle trame */ Attention à l'orthographe... Pas d'accents, pour des problèmes de compatibilité, OK. Mais "pret".
    • Pour le moment, on va passer sous silence l'usage abusif de globales, car on a pas le temps de faire un cours de C... Dommage. Il faudra revoir tout ça après ton examen...

    PS : pourrais tu me rajouter la sortie propre avec ESC, je ne vois pas comment faire. Merci...
    Il faut lire le clavier avec getch(), et si la valeur lue est ESC, on quitte la boucle.

    getch() est bloquant. Si on le met dans la boucle, celle-ci s'arrête et le port com n'est plus surveillé.

    L'idée, c'est donc de soumettre la lecture du clavier à la condition "y'a-t-il quelque chose à lire".

    conio fournit précisément la fonction kbhit() permet de savoir si il y a quelque chose dans le clavier (un peu comme le test du flag de réception dans l'UART).

    Je te laisse écrire le code.

  19. #99
    Candidat au Club
    Inscrit en
    Novembre 2006
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Novembre 2006
    Messages : 54
    Points : 2
    Points
    2
    Par défaut
    J'ai constanté un problème avec l'enregistrement dans un fichier. fopen associé à "w" devrait écraser le contenu du fichier pour le remplacer par celui de fprintf. Chez moi il rajoute le nouveau contenu derrière l'ancien. Pourquoi?

  20. #100
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par 202UH
    J'ai constanté un problème avec l'enregistrement dans un fichier. fopen associé à "w" devrait écraser le contenu du fichier pour le remplacer par celui de fprintf. Chez moi il rajoute le nouveau contenu derrière l'ancien. Pourquoi?
    C'est pas possible. Tu ne dois pas regarder le bon fichier. Tu es sûr du répertoire ?

    Je vérifie. Au fait, j'ai écrit un simulateur d'UART à coup de FIFOs, et le code a l'air de fonctionner correctement...
    Avec
    sim_puts ("<16>:(PB): 1234 l/m\n");
    j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    [02FD]==01
    [02F8]==3C '<'
    [02FD]==01
    [02F8]==31 '1'
    [02FD]==01
    [02F8]==36 '6'
    [02FD]==01
    [02F8]==3E '>'
    [02FD]==01
    [02F8]==3A ':'
    [02FD]==01
    [02F8]==28 '('
    [02FD]==01
    [02F8]==50 'P'
    [02FD]==01
    [02F8]==42 'B'
    [02FD]==01
    [02F8]==29 ')'
    [02FD]==01
    [02F8]==3A ':'
    [02FD]==01
    [02F8]==20 ' '
    [02FD]==01
    [02F8]==31 '1'
    [02FD]==01
    [02F8]==32 '2'
    [02FD]==01
    [02F8]==33 '3'
    [02FD]==01
    [02F8]==34 '4'
    [02FD]==01
    [02F8]==20 ' '
    [02FD]==01
    [02F8]==6C 'l'
    [02FD]==01
    [02F8]==2F '/'
    [02FD]==01
    [02F8]==6D 'm'
    [02FD]==01
    [02F8]==0A
    '1234'
    [02FD]==00
    [02FD]==00
    [02FD]==00
    [02FD]==00
    [02FD]==00
    [02FD]==00
    [02FD]==00
    [02FD]==00
    [02FD]==00
    [02FD]==00
     
    Press ENTER to continue.
    Quand au fichier, il est correct :

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Faire une fenêtre de log "au fil de l'eau"
    Par tio dans le forum Zend Framework
    Réponses: 1
    Dernier message: 20/02/2009, 18h54
  2. [AJAX] Affichage d'une variable au fils de l'eau (flux PHP)
    Par Jonathan.b dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 27/10/2007, 13h25
  3. messages à l'utilisateur au fil de l'eau
    Par thmane dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 04/10/2006, 11h51
  4. [VB.Net] Impression fil de l'eau
    Par Silvinho42 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 18/10/2005, 10h43
  5. [IO] downloader au fil de l'eau
    Par Ekros dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 09/06/2005, 09h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo