Driver UART en polling : corrigé B-205 CE4.2 DRIVER UART EN POLLING Corrigé jc/md/lp-01/05 Driver UART en polling : corrigé UART_polling_corrigé_V1.0.ppt
Driver UART en polling : corrigé B-205 CE4.2 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é UART_polling_corrigé_V1.0.ppt
Driver UART en polling : corrigé B-205 CE4.2 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é UART_polling_corrigé_V1.0.ppt
Driver UART en polling : corrigé Mise en œuvre 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é
File → New Project or File Cocher Nommer Valider jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé Choix du projet Cocher Valider jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé Projet obtenu jc/md/lp-01/05 Driver UART en polling : corrigé
Fichiers créés sous la plate-forme jc/md/lp-01/05 Driver UART en polling : corrigé
Fichiers supplémentaires B-205 CE4.2 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 Les fichiers .def servent à beaucoup d’autres choses non utilisées ici. La syntaxe est particulière : le nom des points d’entrée prédéfinis (Init, Open, PoxerDown, etc.) doit être précédé d’un préfixe fait avec de trois symboles, ici TTY, et le signe souligné. jc/md/lp-01/05 Driver UART en polling : corrigé UART_polling_corrigé_V1.0.ppt
Driver UART en polling : corrigé 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é
Driver UART en polling : corrigé Fichier .def (2) Onglet Files Renseigner Cocher Choisir OK jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé 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é
Driver UART en polling : corrigé TTYpoll_DRV.def (2) jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé 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é
Driver UART en polling : corrigé Fichier .h (2) jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé B-205 CE4.2 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, \ #define IOCTL_GET_RX_STATUS \ CTL_CODE(FILE_DEVICE_UNKNOWN,2050, \ CTL_CODE est une macro utilisée systématiquement pour obtenir des IOCTL standardisés et uniques dans un système. Les valeurs 2048, 2049 et 2050 sont trois valeurs arbitraires choisies simplement dans les valeurs autorisées pour les OEM (2048 à 4095). jc/md/lp-01/05 Driver UART en polling : corrigé UART_polling_corrigé_V1.0.ppt
Driver UART en polling : corrigé TTYpoll.h (2) jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé 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é
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é
Driver : adressage du sérialiseur #define IoPortBase ((PUCHAR) 0x02F8) //Registres du sérialiseur : offset par rapport à IoPortBase #define comLineControl 3 #define comDivisorLow 0 #define comDivisorHigh 1 #define comFIFOControl 2 #define comIntEnable 1 #define comModemControl 4 #define comLineStatus 5 #define comTxBuffer 0 #define comRxBuffer 0 jc/md/lp-01/05 Driver UART en polling : corrigé
Driver : définition des bits de status //Bits de status du sérialiseur #define LS_TSR_EMPTY 0x40 #define LS_THR_EMPTY 0x20 #define LS_RX_BREAK 0x10 #define LS_RX_FRAMING_ERR 0x08 #define LS_RX_PARITY_ERR 0x04 #define LS_RX_OVERRRUN 0x02 #define LS_RX_DATA_READY 0x01 #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é
Driver : point d’entrée de la dll BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { return TRUE; } jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé B-205 CE4.2 Driver : TTY_Init (1) DWORD TTY_Init(DWORD dwContext) { DWORD dwRet = 1; RETAILMSG(1,(TEXT("SERIAL: TTY_Init\n"))); // 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(IoPortBase+comLineControl,0x80); WRITE_PORT_UCHAR(IoPortBase+comDivisorLow,0x0C); WRITE_PORT_UCHAR(IoPortBase+comDivisorHigh,0x00); DWORD TTY_Init(DWORD dwContext) { // Initialisation : 9600 bauds, 8 bits, pas de parité, pas d'IT, DTR, RTS, pas de FIFO DWORD dwRet = 1; RETAILMSG(1,(TEXT("SERIAL: TTY_Init\n"))); // DLAB=1, réglage BAUD RATE WRITE_PORT_UCHAR(IoPortBase+comLineControl,0x80); WRITE_PORT_UCHAR(IoPortBase+comDivisorLow,0x0C); WRITE_PORT_UCHAR(IoPortBase+comDivisorHigh,0x00); // DLAB=0, réglage 8 bits DATA WRITE_PORT_UCHAR(IoPortBase+comLineControl,0x03); // Pas de FIFO WRITE_PORT_UCHAR(IoPortBase+comFIFOControl,0x00); // Pas d’IT WRITE_PORT_UCHAR(IoPortBase+comIntEnable,0x00); // DTR, RTS WRITE_PORT_UCHAR(IoPortBase+comModemControl,0x03); return dwRet; } jc/md/lp-01/05 Driver UART en polling : corrigé UART_polling_corrigé_V1.0.ppt
Driver UART en polling : corrigé Driver : TTY_Init (2) // DLAB=0, réglage 8 bits DATA WRITE_PORT_UCHAR(IoPortBase+comLineControl,0x03); // Pas de FIFO WRITE_PORT_UCHAR(IoPortBase+comFIFOControl,0x00); // Pas d’IT WRITE_PORT_UCHAR(IoPortBase+comIntEnable,0x00); // DTR, RTS WRITE_PORT_UCHAR(IoPortBase+comModemControl,0x03); return dwRet; } jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé Driver : TTY_Deinit BOOL TTY_Deinit(DWORD hDeviceContext) { BOOL bRet = TRUE; RETAILMSG(1,(TEXT("SERIAL: TTY_Deinit\n"))); return bRet; } jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé B-205 CE4.2 Driver : TTY_Open (1) DWORD TTY_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode) { DWORD dwRet = 1; RETAILMSG(1,(TEXT("SERIAL: TTY_Open\n"))); // Vidage du buffer de réception pour éliminer les // caractères résiduels while((READ_PORT_UCHAR(IoPortBase+comLineStatus) & LS_RX_DATA_READY) ==1) READ_PORT_UCHAR(IoPortBase+comRxBuffer); return dwRet; } jc/md/lp-01/05 Driver UART en polling : corrigé UART_polling_corrigé_V1.0.ppt
Driver UART en polling : corrigé Driver : TTY_Close BOOL TTY_Close(DWORD hOpenContext) { BOOL bRet = TRUE; RETAILMSG(1,(TEXT("SERIAL: TTY_Close\n"))); return bRet; } jc/md/lp-01/05 Driver UART en polling : corrigé
Driver : TTY_IOControl (début) BOOL TTY_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut) { switch(dwCode) jc/md/lp-01/05 Driver UART en polling : corrigé
Driver : TTY_IOControl (IOCTL_PUTC) B-205 CE4.2 Driver : TTY_IOControl (IOCTL_PUTC) case IOCTL_PUTC: // Attente de transmetteur prêt while(!(READ_PORT_UCHAR(IoPortBase +comLineStatus) & LS_THR_EMPTY)) ; // Envoi du caractère WRITE_PORT_UCHAR(IoPortBase+ comTxBuffer,pBufIn[0]); break; jc/md/lp-01/05 Driver UART en polling : corrigé UART_polling_corrigé_V1.0.ppt
Driver : TTY_IOControl (IOCTL_GETC) case IOCTL_GETC: // Lecture du caractère pBufOut[0] = READ_PORT_UCHAR(IoPortBase +comRxBuffer); RETAILMSG(1,(TEXT("TTY caractère lu\n"))); break; jc/md/lp-01/05 Driver UART en polling : corrigé
Driver : TTY_IOControl (..._STATUS) case IOCTL_GET_RX_STATUS: // Lecture du status pBufOut[0] = (READ_PORT_UCHAR( IoPortBase+comLineStatus) & LS_RX_DATA_READY); if(pBufOut[0] == 1) RETAILMSG(1,(TEXT(" TTY RX Ready\n"))); break; jc/md/lp-01/05 Driver UART en polling : corrigé
Driver : TTY_IOControl (fin) } // Fin du switch *pdwActualOut = 1; return TRUE; } // Fin de IOControl jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé Compilation du driver jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé Création de l’image jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé 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 (0x1B) Se terminer après la réception de ESCAPE jc/md/lp-01/05 Driver UART en polling : corrigé
File → New Project or File jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé Choix du projet jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé Projet obtenu jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé Platform→Settings jc/md/lp-01/05 Driver UART en polling : corrigé
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é
Ajout de TTYpoll.h au projet (2) B-205 CE4.2 Ajout de TTYpoll.h au projet (2) Choix du répertoire Choix du fichier Valider On peut aussi copier physiquement le fichier TTYpoll.h pris dans le répertoire …\WINCE420\PUBLIC\z_cible_CEPC\TTYpoll_DRV dans le répertoire …\WINCE420\PUBLIC\z_cible_CEPC\TTYpoll_APP L’inconvénient de ce procédé est qu’il existe deux fichiers TTYpoll.h. Les modifications de l’un ne sont pas automatiquement reportées dans l’autre. Avec la méthode choisie, il n’y a qu’un seul fichier physique placé dans …\WINCE420\PUBLIC\z_cible_CEPC\TTYpoll_DRV. Par contre dans la directive include du fichier TTYpollAPP.cpp il faudra préciser le chemin pour atteindre le fichier. #include "../TTYpoll_DRV/TTYpoll.h" jc/md/lp-01/05 Driver UART en polling : corrigé UART_polling_corrigé_V1.0.ppt
Driver UART en polling : corrigé Projet obtenu jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé Platform→Settings jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé Choix du type d’image Dérouler Choisir Choisir Dérouler Valider jc/md/lp-01/05 Driver UART en polling : corrigé
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é
Application : includes #include "stdafx.h" #include "../TTYpoll_DRV/TTYpoll.h" #include <windev.h> jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé B-205 CE4.2 Application : entrée int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // Déclarations et réservations HANDLE hDevice,hTTY; UCHAR carac[80]; DWORD nb; jc/md/lp-01/05 Driver UART en polling : corrigé UART_polling_corrigé_V1.0.ppt
Application : lancement du driver // Lancement du driver (RegisterDevice) hDevice = RegisterDevice(TEXT("TTY"),1, TEXT("TTYpoll_DRV.dll"),NULL); // Test de Handle correct (Handle !=0) if(hDevice == 0) { MessageBox(NULL,_T("CannotRegisterTTY1"), _T("UartApp"),MB_OK); return 0; } MessageBox(NULL,_T("Register TTY1 OK"), _T("UartApp"),MB_OK); jc/md/lp-01/05 Driver UART en polling : corrigé
Application : ouverture du driver // Ouverture du driver (CreateFile) hTTY = CreateFile(TEXT("TTY1:"),GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,0); // Test de Handle correct (Handle !=0) if(hTTY == INVALID_HANDLE_VALUE) { MessageBox(NULL, _T("Cannot open TTY1"), _T("UartApp"),MB_OK); DeregisterDevice(hDevice); CloseHandle(hDevice); return 0; } jc/md/lp-01/05 Driver UART en polling : corrigé
Application : boucle de réception // Boucle d'émission et de réception d’un caractère carac[0]='$'; while(carac[0]!=0x1B) // Attente du caractère escape { // Envoi d'un caractère DeviceIoControl(hTTY,IOCTL_PUTC,carac,1,carac,1,&nb,NULL); // Lecture du status et attente de récepteur Ready do DeviceIoControl(hTTY,IOCTL_GET_RX_STATUS, carac,1,carac,1,&nb,NULL); while(carac[0]!=1); // Acquisition d'un caractère DeviceIoControl(hTTY,IOCTL_GETC,carac,1,carac,1,&nb,NULL); } // Fin de boucle while jc/md/lp-01/05 Driver UART en polling : corrigé UART_polling_corrigé_V1.0.ppt
Application : fermetures // Fermeture du driver CloseHandle(hTTY); // Déchargement du driver DeregisterDevice(hDevice); CloseHandle(hDevice); return 0; } jc/md/lp-01/05 Driver UART en polling : corrigé
Génération de l’application jc/md/lp-01/05 Driver UART en polling : corrigé
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é
Driver UART en polling : corrigé Essai jc/md/lp-01/05 Driver UART en polling : corrigé
Sélection de TTYpoll_APP Valider jc/md/lp-01/05 Driver UART en polling : corrigé
Driver UART en polling : corrigé B-205 CE4.2 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 On ne peut pas montrer d’image de l’écran obtenu puisque cela se passe sur l’écran de la cible et non sur celui du PC hôte ; on ne peut donc pas faire de capture d’image. jc/md/lp-01/05 Driver UART en polling : corrigé UART_polling_corrigé_V1.0.ppt
Driver UART en polling : corrigé 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é