Post on 03-Apr-2015
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é 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é 3
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é 4
Mise en œuvre
1. Préparation du driver
2. Préparation de l’application
3. Téléchargement dans la cible
4. Lancement du driver
5. Exécution de l’application
jc/md/lp-01/05 Driver UART en polling : corrigé 5
File → New Project or File
Cocher
ValiderNommer
jc/md/lp-01/05 Driver UART en polling : corrigé 6
Choix du projet
CocherValider
jc/md/lp-01/05 Driver UART en polling : corrigé 7
Projet obtenu
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é 9
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é 10
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é 11
Fichier .def (2)
Onglet Files
Choisir
Renseigner
Cocher
OK
jc/md/lp-01/05 Driver UART en polling : corrigé 12
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é 13
TTYpoll_DRV.def (2)
jc/md/lp-01/05 Driver UART en polling : corrigé 14
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é 15
Fichier .h (2)
jc/md/lp-01/05 Driver UART en polling : corrigé 16
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é 17
TTYpoll.h (2)
jc/md/lp-01/05 Driver UART en polling : corrigé 18
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é 19
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é 20
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é 21
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é 22
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é 23
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);
jc/md/lp-01/05 Driver UART en polling : corrigé 24
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é 25
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é 26
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é 27
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é 28
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é 29
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é 30
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é 31
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é 32
Driver : TTY_IOControl (fin)
} // Fin du switch
*pdwActualOut = 1;
return TRUE;
} // Fin de IOControl
jc/md/lp-01/05 Driver UART en polling : corrigé 33
Compilation du driver
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é 35
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é 36
File → New Project or File
jc/md/lp-01/05 Driver UART en polling : corrigé 37
Choix du projet
jc/md/lp-01/05 Driver UART en polling : corrigé 38
Projet obtenu
jc/md/lp-01/05 Driver UART en polling : corrigé 39
Platform→Settings
jc/md/lp-01/05 Driver UART en polling : corrigé 40
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é 41
Ajout de TTYpoll.h au projet (2)
Choix du répertoire
Choix du
fichier
Valider
jc/md/lp-01/05 Driver UART en polling : corrigé 42
Projet obtenu
jc/md/lp-01/05 Driver UART en polling : corrigé 43
Platform→Settings
jc/md/lp-01/05 Driver UART en polling : corrigé 44
Choix du type d’image
Dérouler
Dérouler
Choisir Choisir
Valider
jc/md/lp-01/05 Driver UART en polling : corrigé 45
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é 46
Application : includes
#include "stdafx.h"
#include "../TTYpoll_DRV/TTYpoll.h"
#include <windev.h>
jc/md/lp-01/05 Driver UART en polling : corrigé 47
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é 48
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é 49
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é 50
Application : boucle de réception
// Boucle d'émission et de réception d’un caractèrecarac[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é 51
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é 52
Génération de l’application
jc/md/lp-01/05 Driver UART en polling : corrigé 53
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é 54
Essai
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é 56
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é 57
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