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?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?La méthode pour tester l'intégrité des données reste à définir.
Non, ça, c'est l'intégration. On en a pas encore parlé.Envoyé par 202UH
Je parle de ceci :
Il va falloir expliquer comment on fait ça.Envoyé par conception
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 A>B>C A>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
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8A /\ v | B | | v | / v C
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.
Pour le contrôle des caractères perdus, après avoir enregistré nos 4 caractères dans le tableau résultat:- contrôle des caractères perdus et si caractères perdus, initialisation du tableau et écriture de « 0000 » dans le fichier txt
- 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 tableauLa méthode pour détecter l'absence de EOL reste à spécifier
- 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.Envoyé par 202UH
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).
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 :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...
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
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.Envoyé par 202UH
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.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
Pour le moment, fait ce que tu as prévu.
eXtreme Programming. Le Xterm, c'est un type de consoleEnvoyé par Emmanuel Delahaye
Déjà fatigué le matin, ça promet...Envoyé par DaZumba
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...
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 :
Voilà le programme que j'ai éssayeé :Très bien, mais vite!
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 /****************************/ /* Paramtres 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 srie : 8 bits donnes, 1 bit stop, parit aucune, */ /* 9600 bauds et positionnement de DLAB pour faire la slection */ /* 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 rception */ /***********************/ /* 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; }
- L'indentation est... améliorable...Envoyé par 202UH
- 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) /****************************/ /* Paramtres 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 srie : 8 bits donnes, 1 bit stop, parit aucune, */ /* 9600 bauds et positionnement de DLAB pour faire la slection */ /* 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 rception */ /***********************/ /* 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; }
Pourquoi toute ces déclaration? Peut tu m'expliquer!#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
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 srie : 8 bits donnes, 1 bit stop, parit aucune, */ /* 9600 bauds et positionnement de DLAB pour faire la slection */ /* 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 /****************************/ /* Paramtres 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 rception */ /***********************/ /* 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; }
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()...Envoyé par 202UH
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())...
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())Envoyé par 202UH
Quand on appelle une fonction, on ne met pas le type :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 init_com2();
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...Envoyé par Médinoc
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?
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.Envoyé par 202UH
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)
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...2. Comment programmer le contrôle des caractères perdus?
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.
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.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...
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 srie : 8 bits donnes, 1 bit stop, parit aucune, */ /* 9600 bauds et positionnement de DLAB pour faire la slection */ /* 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) /****************************/ /* Paramtres 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; }
Bonne idée, les fonctions.Envoyé par 202UH
- 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...
Il faut lire le clavier avec getch(), et si la valeur lue est ESC, on quitte la boucle.PS : pourrais tu me rajouter la sortie propre avec ESC, je ne vois pas comment faire. Merci...
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.
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 ?Envoyé par 202UH
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 :
Quand au fichier, il est correct :
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.
Code : Sélectionner tout - Visualiser dans une fenêtre à part 1234
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager