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

Preview:

Citation preview

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

Recommended