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

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

Embed Size (px)

Citation preview

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

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

DRIVER UART EN POLLING

Corrigé

Page 2: Jc/md/lp-01/05Driver 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

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

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

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

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

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

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

File → New Project or File

Cocher

ValiderNommer

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

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

Choix du projet

CocherValider

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

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

Projet obtenu

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

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

Fichiers créés sous la plate-forme

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

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

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

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

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

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

Fichier .def (2)

Onglet Files

Choisir

Renseigner

Cocher

OK

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

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

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

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

TTYpoll_DRV.def (2)

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

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

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

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

Fichier .h (2)

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

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)

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

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

TTYpoll.h (2)

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

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

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

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"

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

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

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

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 )

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

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;

}

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

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);

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

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;}

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

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;

}

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

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;}

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

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;

}

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

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) {

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

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;

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

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;

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

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;

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

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

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

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

Compilation du driver

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

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

Création de l’image

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

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

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

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

File → New Project or File

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

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

Choix du projet

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

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

Projet obtenu

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

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

Platform→Settings

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

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

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

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

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

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

Projet obtenu

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

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

Platform→Settings

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

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

Choix du type d’image

Dérouler

Dérouler

Choisir Choisir

Valider

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

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

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

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

Application : includes

#include "stdafx.h"

#include "../TTYpoll_DRV/TTYpoll.h"

#include <windev.h>

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

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;

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

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);

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

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;

}

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

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

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

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;

}

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

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

Génération de l’application

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

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

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

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

Essai

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

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

Sélection de TTYpoll_APP

Valider

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

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

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

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