DRIVER UART EN POLLING Corrig jcmdlp0105 Driver UART

  • Slides: 57
Download presentation
DRIVER UART EN POLLING Corrigé jc/md/lp-01/05 Driver UART en polling : corrigé 1

DRIVER UART EN POLLING Corrigé jc/md/lp-01/05 Driver UART en polling : corrigé 1

Objectif du chapitre • Fournir le corrigé des exercices proposés dans le chapitre :

Objectif du chapitre • Fournir le corrigé des exercices proposés dans le chapitre : Driver UART en polling : présentation jc/md/lp-01/05 Driver UART en polling : corrigé 2

Driver en polling • À écrire avec la plate-forme z_cible_CEPC • Le driver assure

Driver en polling • À écrire avec la plate-forme z_cible_CEPC • Le driver assure l’interface entre le système et le contrôleur de la liaison série • Côté système il dialogue par des IOCTL, ici réduits à trois pour – Envoyer un caractère – Tester le status en réception puisque nous prévoyons une gestion par polling – Recevoir un caractère • Côté périphérie, le dialogue consiste à écrire dans les registres du contrôleur jc/md/lp-01/05 Driver UART en polling : corrigé 3

Mise en œuvre 1. 2. 3. 4. 5. Préparation du driver Préparation de l’application

Mise en œuvre 1. 2. 3. 4. 5. Préparation du driver Préparation de l’application Téléchargement dans la cible Lancement du driver Exécution de l’application jc/md/lp-01/05 Driver UART en polling : corrigé 4

File → New Project or File Cocher Nommer jc/md/lp-01/05 Driver UART en polling :

File → New Project or File Cocher Nommer jc/md/lp-01/05 Driver UART en polling : corrigé Valider 5

Choix du projet Coc her jc/md/lp-01/05 Valider Driver UART en polling : corrigé 6

Choix du projet Coc her jc/md/lp-01/05 Valider Driver UART en polling : corrigé 6

Projet obtenu jc/md/lp-01/05 Driver UART en polling : corrigé 7

Projet obtenu jc/md/lp-01/05 Driver UART en polling : corrigé 7

Fichiers créés sous la plate-forme jc/md/lp-01/05 Driver UART en polling : corrigé 8

Fichiers créés sous la plate-forme jc/md/lp-01/05 Driver UART en polling : corrigé 8

Fichiers supplémentaires • Pour un projet de Dll, deux fichiers doivent être ajoutés •

Fichiers supplémentaires • Pour un projet de Dll, deux fichiers doivent être ajoutés • Fichier de définition de module. def pour : – Créer une Dll et lui attribuer un nom – Annoncer aux autres programmes les points d’entrée du driver • Fichier d’entête. h dans lequel on prépare des macros utilisables avec le driver pour faciliter l’utilisation des IOCTL jc/md/lp-01/05 Driver UART en polling : corrigé 9

Fichier. def (1) • Fichier texte • Dans le menu principal de Platform Builder

Fichier. def (1) • Fichier texte • Dans le menu principal de Platform Builder : → File → New Project or File • Dans la fenêtre New Project or File → Onglet Files → Choisir Text File → Renseigner le nom de fichier → Cocher Add to Project puis OK jc/md/lp-01/05 Driver UART en polling : corrigé 10

Fichier. def (2) Onglet Files Renseigner Cocher Choisir OK jc/md/lp-01/05 Driver UART en polling

Fichier. def (2) Onglet Files Renseigner Cocher Choisir OK jc/md/lp-01/05 Driver UART en polling : corrigé 11

TTYpoll_DRV. def (1) LIBRARY TTYpoll_DRV EXPORTS TTY_Init TTY_Open TTY_IOControl TTY_Close TTY_Deinit jc/md/lp-01/05 Driver UART

TTYpoll_DRV. def (1) LIBRARY TTYpoll_DRV EXPORTS TTY_Init TTY_Open TTY_IOControl TTY_Close TTY_Deinit jc/md/lp-01/05 Driver UART en polling : corrigé 12

TTYpoll_DRV. def (2) jc/md/lp-01/05 Driver UART en polling : corrigé 13

TTYpoll_DRV. def (2) jc/md/lp-01/05 Driver UART en polling : corrigé 13

Fichier. h (1) • Fichier d’entête habituel • Dans le menu principal de Platform

Fichier. h (1) • Fichier d’entête habituel • Dans le menu principal de Platform Builder : → File → New Project or File • Dans la fenêtre New Project or File → Onglet Files → Choisir C/C++ Header File → Renseigner le nom de fichier → Cocher Add to Project puis OK jc/md/lp-01/05 Driver UART en polling : corrigé 14

Fichier. h (2) jc/md/lp-01/05 Driver UART en polling : corrigé 15

Fichier. h (2) jc/md/lp-01/05 Driver UART en polling : corrigé 15

TTYpoll. h (1) #define IOCTL_PUTC  CTL_CODE(FILE_DEVICE_UNKNOWN, 2048,  METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_GETC

TTYpoll. h (1) #define IOCTL_PUTC CTL_CODE(FILE_DEVICE_UNKNOWN, 2048, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_GETC CTL_CODE(FILE_DEVICE_UNKNOWN, 2049, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_GET_RX_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS) jc/md/lp-01/05 Driver UART en polling : corrigé 16

TTYpoll. h (2) jc/md/lp-01/05 Driver UART en polling : corrigé 17

TTYpoll. h (2) jc/md/lp-01/05 Driver UART en polling : corrigé 17

TTYpoll_DRV. cpp • • • Fichiers d’entêtes Constantes d’adressage des registres du 16550 Constantes

TTYpoll_DRV. cpp • • • Fichiers d’entêtes Constantes d’adressage des registres du 16550 Constantes de définition des bits de status Point d’entrée de la dll Code des points d’entrée du driver Init, Deinit, Open, Close et IOControl Code des IOCTL PUTC, GETC et GET_RX_STATUS jc/md/lp-01/05 Driver UART en polling : corrigé 18

Driver : fichiers d’entêtes #include "stdafx. h" #include <wdm. h> #include <windev. h> #include

Driver : fichiers d’entêtes #include "stdafx. h" #include <wdm. h> #include <windev. h> #include "TTYpoll. h" jc/md/lp-01/05 Driver UART en polling : corrigé 19

Driver : adressage du sérialiseur #define Io. Port. Base ((PUCHAR) 0 x 02 F

Driver : adressage du sérialiseur #define Io. Port. Base ((PUCHAR) 0 x 02 F 8) //Registres du sérialiseur : offset par rapport à Io. Port. Base #define com. Line. Control 3 #define com. Divisor. Low 0 #define com. Divisor. High 1 #define com. FIFOControl 2 #define com. Int. Enable 1 #define com. Modem. Control 4 #define com. Line. Status 5 #define com. Tx. Buffer 0 #define com. Rx. Buffer 0 jc/md/lp-01/05 Driver UART en polling : corrigé 20

Driver : définition des bits de status //Bits de status du sérialiseur #define LS_TSR_EMPTY

Driver : définition des bits de status //Bits de status du sérialiseur #define LS_TSR_EMPTY 0 x 40 #define LS_THR_EMPTY 0 x 20 #define LS_RX_BREAK 0 x 10 #define LS_RX_FRAMING_ERR 0 x 08 #define LS_RX_PARITY_ERR 0 x 04 #define LS_RX_OVERRRUN 0 x 02 #define LS_RX_DATA_READY 0 x 01 #define LS_RX_ERRORS (LS_RX_FRAMING_ERR | LS_RX_PARITY_ERR | LS_RX_OVERRRUN ) jc/md/lp-01/05 Driver UART en polling : corrigé 21

Driver : point d’entrée de la dll BOOL APIENTRY Dll. Main(HANDLE h. Module, DWORD

Driver : point d’entrée de la dll BOOL APIENTRY Dll. Main(HANDLE h. Module, DWORD ul_reason_for_call, LPVOID lp. Reserved) { return TRUE; } jc/md/lp-01/05 Driver UART en polling : corrigé 22

Driver : TTY_Init (1) DWORD TTY_Init(DWORD dw. Context) { DWORD dw. Ret = 1;

Driver : TTY_Init (1) DWORD TTY_Init(DWORD dw. Context) { DWORD dw. Ret = 1; RETAILMSG(1, (TEXT("SERIAL: TTY_Initn"))); // Initialisation du sérialiseur 16550 // 9600 bauds, 8 bits, pas de parité, pas d'IT, DTR, RTS // pas de FIFO // DLAB=1, réglage BAUD RATE WRITE_PORT_UCHAR(Io. Port. Base+com. Line. Control, 0 x 80); WRITE_PORT_UCHAR(Io. Port. Base+com. Divisor. Low, 0 x 0 C); WRITE_PORT_UCHAR(Io. Port. Base+com. Divisor. High, 0 x 00); jc/md/lp-01/05 Driver UART en polling : corrigé 23

Driver : TTY_Init (2) // DLAB=0, réglage 8 bits DATA WRITE_PORT_UCHAR(Io. Port. Base+com. Line.

Driver : TTY_Init (2) // DLAB=0, réglage 8 bits DATA WRITE_PORT_UCHAR(Io. Port. Base+com. Line. Control, 0 x 03); // Pas de FIFO WRITE_PORT_UCHAR(Io. Port. Base+com. FIFOControl, 0 x 00); // Pas d’IT WRITE_PORT_UCHAR(Io. Port. Base+com. Int. Enable, 0 x 00); // DTR, RTS WRITE_PORT_UCHAR(Io. Port. Base+com. Modem. Control, 0 x 03); return dw. Ret; } jc/md/lp-01/05 Driver UART en polling : corrigé 24

Driver : TTY_Deinit BOOL TTY_Deinit(DWORD h. Device. Context) { BOOL b. Ret = TRUE;

Driver : TTY_Deinit BOOL TTY_Deinit(DWORD h. Device. Context) { BOOL b. Ret = TRUE; RETAILMSG(1, (TEXT("SERIAL: TTY_Deinitn"))); return b. Ret; } jc/md/lp-01/05 Driver UART en polling : corrigé 25

Driver : TTY_Open (1) DWORD TTY_Open(DWORD h. Device. Context, DWORD Access. Code, DWORD Share.

Driver : TTY_Open (1) DWORD TTY_Open(DWORD h. Device. Context, DWORD Access. Code, DWORD Share. Mode) { DWORD dw. Ret = 1; RETAILMSG(1, (TEXT("SERIAL: TTY_Openn"))); // Vidage du buffer de réception pour éliminer les // caractères résiduels while((READ_PORT_UCHAR(Io. Port. Base+com. Line. Status) & LS_RX_DATA_READY) ==1) READ_PORT_UCHAR(Io. Port. Base+com. Rx. Buffer); return dw. Ret; } jc/md/lp-01/05 Driver UART en polling : corrigé 26

Driver : TTY_Close BOOL TTY_Close(DWORD h. Open. Context) { BOOL b. Ret = TRUE;

Driver : TTY_Close BOOL TTY_Close(DWORD h. Open. Context) { BOOL b. Ret = TRUE; RETAILMSG(1, (TEXT("SERIAL: TTY_Closen"))); return b. Ret; } jc/md/lp-01/05 Driver UART en polling : corrigé 27

Driver : TTY_IOControl (début) BOOL TTY_IOControl(DWORD h. Open. Context, DWORD dw. Code, PBYTE p.

Driver : TTY_IOControl (début) BOOL TTY_IOControl(DWORD h. Open. Context, DWORD dw. Code, PBYTE p. Buf. In, DWORD dw. Len. In, PBYTE p. Buf. Out, DWORD dw. Len. Out, PDWORD pdw. Actual. Out) { switch(dw. Code) { jc/md/lp-01/05 Driver UART en polling : corrigé 28

Driver : TTY_IOControl (IOCTL_PUTC) case IOCTL_PUTC: // Attente de transmetteur prêt while(!(READ_PORT_UCHAR(Io. Port. Base

Driver : TTY_IOControl (IOCTL_PUTC) case IOCTL_PUTC: // Attente de transmetteur prêt while(!(READ_PORT_UCHAR(Io. Port. Base +com. Line. Status) & LS_THR_EMPTY)) ; // Envoi du caractère WRITE_PORT_UCHAR(Io. Port. Base+ com. Tx. Buffer, p. Buf. In[0]); break; jc/md/lp-01/05 Driver UART en polling : corrigé 29

Driver : TTY_IOControl (IOCTL_GETC) case IOCTL_GETC: // Lecture du caractère p. Buf. Out[0] =

Driver : TTY_IOControl (IOCTL_GETC) case IOCTL_GETC: // Lecture du caractère p. Buf. Out[0] = READ_PORT_UCHAR(Io. Port. Base +com. Rx. Buffer); RETAILMSG(1, (TEXT("TTY caractère lun"))); break; jc/md/lp-01/05 Driver UART en polling : corrigé 30

Driver : TTY_IOControl (. . . _STATUS) case IOCTL_GET_RX_STATUS: // Lecture du status p.

Driver : TTY_IOControl (. . . _STATUS) case IOCTL_GET_RX_STATUS: // Lecture du status p. Buf. Out[0] = (READ_PORT_UCHAR( Io. Port. Base+com. Line. Status) & LS_RX_DATA_READY); if(p. Buf. Out[0] == 1) RETAILMSG(1, (TEXT(" TTY RX Readyn"))); break; jc/md/lp-01/05 Driver UART en polling : corrigé 31

Driver : TTY_IOControl (fin) } // Fin du switch *pdw. Actual. Out = 1;

Driver : TTY_IOControl (fin) } // Fin du switch *pdw. Actual. Out = 1; return TRUE; } // Fin de IOControl jc/md/lp-01/05 Driver UART en polling : corrigé 32

Compilation du driver jc/md/lp-01/05 Driver UART en polling : corrigé 33

Compilation du driver jc/md/lp-01/05 Driver UART en polling : corrigé 33

Création de l’image jc/md/lp-01/05 Driver UART en polling : corrigé 34

Création de l’image jc/md/lp-01/05 Driver UART en polling : corrigé 34

Application • Application qui utilise le driver TTYpoll_DRV • Le programme est très simple,

Application • Application qui utilise le driver TTYpoll_DRV • Le programme est très simple, il doit : – Écrire un $ avec IOCTL_ PUTC – Attendre la réception d’un caractère avec IOCTL_GET_RX_STATUS – Lire le caractère reçu avec IOCTL_GETC – Envoyer l’écho avec IOCTL_PUTC – Boucler jusqu’à la réception du caractère ESCAPE (0 x 1 B) – Se terminer après la réception de ESCAPE jc/md/lp-01/05 Driver UART en polling : corrigé 35

File → New Project or File jc/md/lp-01/05 Driver UART en polling : corrigé 36

File → New Project or File jc/md/lp-01/05 Driver UART en polling : corrigé 36

Choix du projet jc/md/lp-01/05 Driver UART en polling : corrigé 37

Choix du projet jc/md/lp-01/05 Driver UART en polling : corrigé 37

Projet obtenu jc/md/lp-01/05 Driver UART en polling : corrigé 38

Projet obtenu jc/md/lp-01/05 Driver UART en polling : corrigé 38

Platform→Settings jc/md/lp-01/05 Driver UART en polling : corrigé 39

Platform→Settings jc/md/lp-01/05 Driver UART en polling : corrigé 39

Ajout de TTYpoll. h au projet (1) • Ouvrir le répertoire des fichiers du

Ajout de TTYpoll. h au projet (1) • Ouvrir le répertoire des fichiers du projet TTYpoll_APP • Faire un clic droit sur le répertoire des fichiers d’entête Header Files • Dans le menu déroulant, choisir Add Files to Folder • Sélectionner dans la fenêtre qui s’ouvre le répertoire à visiter • Sélectionner le fichier à insérer TTYpoll. h • Valider jc/md/lp-01/05 Driver UART en polling : corrigé 40

Ajout de TTYpoll. h au projet (2) Choix du répertoire Choix du fichier jc/md/lp-01/05

Ajout de TTYpoll. h au projet (2) Choix du répertoire Choix du fichier jc/md/lp-01/05 Driver UART en polling : corrigé Valider 41

Projet obtenu jc/md/lp-01/05 Driver UART en polling : corrigé 42

Projet obtenu jc/md/lp-01/05 Driver UART en polling : corrigé 42

Platform→Settings jc/md/lp-01/05 Driver UART en polling : corrigé 43

Platform→Settings jc/md/lp-01/05 Driver UART en polling : corrigé 43

Choix du type d’image Déroule r Choisir Déroule r Valider jc/md/lp-01/05 Driver UART en

Choix du type d’image Déroule r Choisir Déroule r Valider jc/md/lp-01/05 Driver UART en polling : corrigé 44

Schéma d’utilisation du driver • Pour utiliser notre driver, notre application doit exécuter plusieurs

Schéma d’utilisation du driver • Pour utiliser notre driver, notre application doit exécuter plusieurs phases : – – – Enregistrement du driver dans la registry Ouverture du driver Utilisation des IOControl préparées Fermeture du driver Suppression du driver de la registry • Le driver sera géré par un handle que l’application devrait fermer avant de se terminer jc/md/lp-01/05 Driver UART en polling : corrigé 45

Application : includes #include "stdafx. h" #include ". . /TTYpoll_DRV/TTYpoll. h" #include <windev. h>

Application : includes #include "stdafx. h" #include ". . /TTYpoll_DRV/TTYpoll. h" #include <windev. h> jc/md/lp-01/05 Driver UART en polling : corrigé 46

Application : entrée int WINAPI Win. Main(HINSTANCE h. Instance, HINSTANCE h. Prev. Instance, LPTSTR

Application : entrée int WINAPI Win. Main(HINSTANCE h. Instance, HINSTANCE h. Prev. Instance, LPTSTR lp. Cmd. Line, int n. Cmd. Show) { // Déclarations et réservations HANDLE h. Device, h. TTY; UCHAR carac[80]; DWORD nb; jc/md/lp-01/05 Driver UART en polling : corrigé 47

Application : lancement du driver // Lancement du driver (Register. Device) h. Device =

Application : lancement du driver // Lancement du driver (Register. Device) h. Device = Register. Device(TEXT("TTY"), 1, TEXT("TTYpoll_DRV. dll"), NULL); // Test de Handle correct (Handle !=0) if(h. Device == 0) { Message. Box(NULL, _T("Cannot. Register. TTY 1"), _T("Uart. App"), MB_OK); return 0; } Message. Box(NULL, _T("Register TTY 1 OK"), _T("Uart. App"), MB_OK); jc/md/lp-01/05 Driver UART en polling : corrigé 48

Application : ouverture du driver // Ouverture du driver (Create. File) h. TTY =

Application : ouverture du driver // Ouverture du driver (Create. File) h. TTY = Create. File(TEXT("TTY 1: "), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); // Test de Handle correct (Handle !=0) if(h. TTY == INVALID_HANDLE_VALUE) { Message. Box(NULL, _T("Cannot open TTY 1"), _T("Uart. App"), MB_OK); Deregister. Device(h. Device); Close. Handle(h. Device); return 0; } jc/md/lp-01/05 Driver UART en polling : corrigé 49

Application : boucle de réception // Boucle d'émission et de réception d’un caractère carac[0]='$';

Application : boucle de réception // Boucle d'émission et de réception d’un caractère carac[0]='$'; while(carac[0]!=0 x 1 B) // Attente du caractère escape { // Envoi d'un caractère Device. Io. Control(h. TTY, IOCTL_PUTC, carac, 1, &nb, NULL); // Lecture du status et attente de récepteur Ready do Device. Io. Control(h. TTY, IOCTL_GET_RX_STATUS, carac, 1, &nb, NULL); while(carac[0]!=1); // Acquisition d'un caractère Device. Io. Control(h. TTY, IOCTL_GETC, carac, 1, &nb, NULL); } // Fin de boucle while jc/md/lp-01/05 Driver UART en polling : corrigé 50

Application : fermetures // Fermeture du driver Close. Handle(h. TTY); // Déchargement du driver

Application : fermetures // Fermeture du driver Close. Handle(h. TTY); // Déchargement du driver Deregister. Device(h. Device); Close. Handle(h. Device); return 0; } jc/md/lp-01/05 Driver UART en polling : corrigé 51

Génération de l’application jc/md/lp-01/05 Driver UART en polling : corrigé 52

Génération de l’application jc/md/lp-01/05 Driver UART en polling : corrigé 52

Essai de TTYpoll_APP. exe • Télécharger dans la cible le noyau avec le driver

Essai de TTYpoll_APP. exe • Télécharger dans la cible le noyau avec le driver TTYpoll_DRV. dll qui a été inclus lors du Make Image • Lancement du programme d’application Target → Run Program • Sélection de TTYpoll_APP jc/md/lp-01/05 Driver UART en polling : corrigé 53

Essai jc/md/lp-01/05 Driver UART en polling : corrigé 54

Essai jc/md/lp-01/05 Driver UART en polling : corrigé 54

Sélection de TTYpoll_APP Valider jc/md/lp-01/05 Driver UART en polling : corrigé 55

Sélection de TTYpoll_APP Valider jc/md/lp-01/05 Driver UART en polling : corrigé 55

Cible • On observe un $ sur l’écran, puis l’écho de tous les caractères

Cible • On observe un $ sur l’écran, puis l’écho de tous les caractères tapés • Le programme se termine lorsqu’on tape le caractère ESCAPE jc/md/lp-01/05 Driver UART en polling : corrigé 56

Conclusion • Nous avons : – – – Construit un driver simple Généré une

Conclusion • Nous avons : – – – Construit un driver simple Généré une image de système incluant ce driver Utilisé ce driver dans une application Téléchargé le système dans la cible Téléchargé et exécuté l’application dans la cible • TODO – Saisir une chaîne de caractères jc/md/lp-01/05 Driver UART en polling : corrigé 57