570 likes | 715 Views
DRIVER UART EN POLLING. Corrigé. Objectif du chapitre. Fournir le corrigé des exercices proposés dans le chapitre : Driver UART en polling : présentation. Driver en polling. À écrire avec la plate-forme z_cible_CEPC
E N D
DRIVER UART EN POLLING Corrigé Driver UART en polling : corrigé
Objectif du chapitre • Fournir le corrigé des exercices proposés dans le chapitre : Driver UART en polling : présentation Driver UART en polling : corrigé
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 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 Driver UART en polling : corrigé
File → New Project or File Cocher Nommer Valider Driver UART en polling : corrigé
Choix du projet Cocher Valider Driver UART en polling : corrigé
Projet obtenu Driver UART en polling : corrigé
Fichiers créés sous la plate-forme Driver UART en polling : corrigé
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 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 Driver UART en polling : corrigé
Fichier .def (2) Onglet Files Renseigner Cocher Choisir OK Driver UART en polling : corrigé
TTYpoll_DRV.def (1) LIBRARY TTYpoll_DRV EXPORTS TTY_Init TTY_Open TTY_IOControl TTY_Close TTY_Deinit Driver UART en polling : corrigé
TTYpoll_DRV.def (2) 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 Driver UART en polling : corrigé
Fichier .h (2) Driver UART en polling : corrigé
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) Driver UART en polling : corrigé
TTYpoll.h (2) 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 Driver UART en polling : corrigé
Driver : fichiers d’entêtes #include "stdafx.h" #include <wdm.h> #include <windev.h> #include "TTYpoll.h" 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 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 ) 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; } Driver UART en polling : corrigé
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); 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; } 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; } Driver UART en polling : corrigé
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; } 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; } 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) { Driver UART en polling : corrigé
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; Driver UART en polling : corrigé
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; 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; Driver UART en polling : corrigé
Driver : TTY_IOControl (fin) } // Fin du switch *pdwActualOut = 1; return TRUE; } // Fin de IOControl Driver UART en polling : corrigé
Compilation du driver Driver UART en polling : corrigé
Création de l’image 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 Driver UART en polling : corrigé
File → New Project or File Driver UART en polling : corrigé
Choix du projet Driver UART en polling : corrigé
Projet obtenu Driver UART en polling : corrigé
Platform→Settings 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 Driver UART en polling : corrigé
Ajout de TTYpoll.h au projet (2) Choix du répertoire Choix du fichier Valider Driver UART en polling : corrigé
Projet obtenu Driver UART en polling : corrigé
Platform→Settings Driver UART en polling : corrigé
Choix du type d’image Dérouler Choisir Choisir Dérouler Valider 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 Driver UART en polling : corrigé
Application : includes #include "stdafx.h" #include "../TTYpoll_DRV/TTYpoll.h" #include <windev.h> Driver UART en polling : corrigé
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; Driver UART en polling : corrigé
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); 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; } 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 Driver UART en polling : corrigé