Jc/md/lp-01/05TTY_IT : corrigé1 TTY_IT Corrigé. jc/md/lp-01/05TTY_IT : corrigé2 Objectif du...

Preview:

Citation preview

jc/md/lp-01/05 TTY_IT : corrigé 1

TTY_IT

Corrigé

jc/md/lp-01/05 TTY_IT : corrigé 2

Objectif du chapitre

• Proposer une solution pour les exercices suggérés dans le chapitre IT_CE4.2_présentation

• Écrire un programme qui va communiquer avec une liaison série

• La transmission se fera en polling• La réception sera gérée par interruption• On utilisera la deuxième liaison série connectée

sur l’IRQ3

jc/md/lp-01/05 TTY_IT : corrigé 3

Rappel : principe des interruptions

• Deux composants logiciels pour gérer les interruptions– ISR : Interrupt Service Routine

Code très court qui fait le traitement le plus court possible

retourne un numéro logique d’IT– IST : Interrupt Service Thread

Traite l’interruption

jc/md/lp-01/05 TTY_IT : corrigé 4

Rappel : déroulement du traitement

• Une IT physique se produit• Le gestionnaire d’exception lance l’ISR associé

à cette interruption• L’ISR retourne le numéro logique au noyau• Le noyau arme un événement pour déclencher

l’IST associé• L’IST est déclenchée• La commande IOCTL est exécutée

jc/md/lp-01/05 TTY_IT : corrigé 5

Rappel : IST

• Thread en mode user de forte priorité• En attente d’un événement associé à l’IT logique• Réveillé lorsque le Kernel signale l’événement• Traite l’interruption• Acquitte l’interruption

jc/md/lp-01/05 TTY_IT : corrigé 6

Synchronisation IST/DRIVER

• L’ IST va faire l’acquisition du caractère reçu et le stockera dans un buffer ucBufIn

• Pour signaler au driver qu’un caractère a été acquis, nous utiliserons un autre EVENT géré par un handle nommé hMonEvent

• L’IST positionne cet EVENT• Le driver fait le traitement demandé puis

acquitte l’EVENT

jc/md/lp-01/05 TTY_IT : corrigé 7

Gestion du port série en IT

• On utilise le port 2• IT physique 0x3 (IRQ 3)• IT logique (dwSYSINTR_A_Moi)• Adresse du port 0x2F8

jc/md/lp-01/05 TTY_IT : corrigé 8

IOCTL

• On va définir deux IOCTL internes au driver– IOCTL_PUTC envoi de caractère en polling– IOCTL_GETC réception de caractère sous IT

• On va définir un IOCTL pour la communication driver→ISR (envoi du numéro logique de l’IT)– IOCTL_VAL_SYSINTR

jc/md/lp-01/05 TTY_IT : corrigé 9

plate-forme de travail

• Générer une nouvelle plate-forme standard• Nom : z_CEPC_TTY_IT• Retirer de la configuration de base la gestion

des ports série présente par défaut pour éviter des conflits

jc/md/lp-01/05 TTY_IT : corrigé 10

Retirer le port série (1)

• Onglet Features• Dérouler l’arborescence

→Z_CEPC_TTY_IT features

→CEPC: x86

→Devices Drivers

→Serial

• Cliquer à droite pour ouvrir le menu• Cliquer Delete

jc/md/lp-01/05 TTY_IT : corrigé 11

Retirer le port série (2)

Dérouler jusqu’à Serial puis clic droit

Cliquer

jc/md/lp-01/05 TTY_IT : corrigé 12

Configuration obtenue

jc/md/lp-01/05 TTY_IT : corrigé 13

DRIVER

jc/md/lp-01/05 TTY_IT : corrigé 14

Création du driverDans File : Choisir New Project or File

NommerChoisir

Valider

jc/md/lp-01/05 TTY_IT : corrigé 15

Choix du projet

Valider

Choisir

jc/md/lp-01/05 TTY_IT : corrigé 16

Fichier source obtenu

jc/md/lp-01/05 TTY_IT : corrigé 17

Création du fichier .def (1)

• Nous devons créerTTYIT_DRV.def

• Puis l’ajouter au projet• On peut

– Créer directement dans le projet un nouveau fichier de type Text File

– Ajouter un fichier créé à l’avance dans un répertoire

jc/md/lp-01/05 TTY_IT : corrigé 18

Création directe du fichier .def (1)

Onglet Files

Nommer

Cocher

Valider

Choisir

jc/md/lp-01/05 TTY_IT : corrigé 19

TTYIT_DRV.def

LIBRARY TTYIT_DRV

EXPORTS

TTY_Init

TTY_Deinit

TTY_Open

TTY_Close

TTY_IOControl

jc/md/lp-01/05 TTY_IT : corrigé 20

Insertion de TTYIT_DRV.def (1)

• Créer le fichier• Enregistrer ce fichier dans le répertoire

…\WINCE420\PUBLIC\z_CEPC_TTY_IT\TTYIT_DRV

• Ajouter ce fichier au projet– Cliquer à droite sur le répertoire Source Files– Dans le menu choisir Add Files to Folder…– Dans la fenêtre ouverte, choisir le fichier à insérer– Valider

jc/md/lp-01/05 TTY_IT : corrigé 21

Insertion de TTYIT_DRV.def (2)

jc/md/lp-01/05 TTY_IT : corrigé 22

Insertion de TTYIT_DRV.def (3)

jc/md/lp-01/05 TTY_IT : corrigé 23

Structure du driver

jc/md/lp-01/05 TTY_IT : corrigé 24

Entête du driver (1)

// #include nécessaires

#include "stdafx.h"

#include <nkintr.h>

#include <wdm.h>

#include <Pkfuncs.h>

jc/md/lp-01/05 TTY_IT : corrigé 25

Entête du driver (2)

// Définitions et réservations

// Définition des 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

jc/md/lp-01/05 TTY_IT : corrigé 26

Entête du driver (3)

// Définition des offsets des registres du sérialiseur

#define comRxBuffer 0

#define comTxBuffer 0

#define comDivisorLow 0

#define comDivisorHigh 1

#define comIntEnable 1

#define comFIFOControl 2

#define comLineControl 3

#define comModemControl 4

#define comLineStatus 5

jc/md/lp-01/05 TTY_IT : corrigé 27

Entête du driver (4)

// Définition des IOCTL

#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_VAL_SYSINTR \

CTL_CODE(FILE_DEVICE_UNKNOWN,2050,\

METHOD_BUFFERED,FILE_ANY_ACCESS)

jc/md/lp-01/05 TTY_IT : corrigé 28

Entête du driver (5)

// Adresse de base du sérialiseur#define IoPortBase ((PUCHAR) 0x02F8)// Interruptions#define ItPhysique 0x3// Définition de la structure à passer à l’ISTtypedef struct _ISTDATA

{ HANDLE hThread; // IST Handle DWORD sysIntr; // Logical ID HANDLE hEvent; // Handle to the EVENT volatile BOOL bAbort; // Flag de fin

}ISTDATA;

jc/md/lp-01/05 TTY_IT : corrigé 29

Entête du driver (6)

// Prototype de l'IST

DWORD TTYIST(void *);

DWORD dwSYSINTR_A_Moi;

// Réservations diverses

UCHAR ucBufIn;

HANDLE hMonEvent;

ISTDATA TTY_ISTData;

jc/md/lp-01/05 TTY_IT : corrigé 30

Entrée du driver

BOOL APIENTRY DllMain( HANDLE hModule,

DWORD ul_reason_for_call,

LPVOID lpReserved)

{

return TRUE;

}// Fin DllMain

jc/md/lp-01/05 TTY_IT : corrigé 31

TTY_Init (1)

DWORD TTY_Init(DWORD dwContext){

// Déclarations diverses DWORD Buf_In[1];

DWORD Buf_Out[1];DWORD dwNbBytes;HANDLE hChain,hIstEvent;DWORD dwErrCode;

RETAILMSG(1,(TEXT("TTY: TTY_Init\n")));

jc/md/lp-01/05 TTY_IT : corrigé 32

TTY_INIT (2)

// Initialisation des registres du sérialiseur 16550 // pas d'IT sur Receiver Ready (sera fait dans Open)

// 9600 bauds, 8 bits, pas de parité, DTR, RTS// pas de FIFO

WRITE_PORT_UCHAR(IoPortBase+comLineControl, 0x80);

WRITE_PORT_UCHAR(IoPortBase+comDivisorLow, 0x0C);

WRITE_PORT_UCHAR(IoPortBase+comDivisorHigh, 0x00);

jc/md/lp-01/05 TTY_IT : corrigé 33

TTY_Init (3)

WRITE_PORT_UCHAR(IoPortBase+comLineControl, 0x03);

WRITE_PORT_UCHAR(IoPortBase+comFIFOControl, 0x00);

WRITE_PORT_UCHAR(IoPortBase+comIntEnable,

0x00);

// Mettre OUT2 du 16550 à 1 pour autoriser les IT// globalement

// (pas indiqué dans la documentation du 16550 !)

jc/md/lp-01/05 TTY_IT : corrigé 34

TTY_Init (4)

WRITE_PORT_UCHAR(IoPortBase+ comModemControl, 0x0B);

// Récupération d'un numéro d’IT logiqueBuf_In[0]=3;KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, Buf_In,4,Buf_Out,4,NULL);dwSYSINTR_A_Moi=Buf_Out[0];RETAILMSG(1,(TEXT("dwSYSINTR_A_Moi: %d\n"), dwSYSINTR_A_Moi));// Chaînage de l'ISRhChain=LoadIntChainHandler(_T("TTYISR.dll"), _T("ISRHandler"),ItPhysique);

jc/md/lp-01/05 TTY_IT : corrigé 35

TTY_Init (5)

if(hChain==0)

{

RETAILMSG(1,(TEXT("TTY: erreur %d dans LoadIntChainHandler\n"),GetLastError()));

return FALSE;

}

jc/md/lp-01/05 TTY_IT : corrigé 36

TTY_Init (6)

// Passage du numéro IT Logique à l'ISR

Buf_In[0]=dwSYSINTR_A_Moi;

dwErrCode=KernelLibIoControl(hChain,IOCTL_VAL_ SYSINTR,Buf_In,4,NULL,NULL,&dwNbBytes);

if(dwErrCode==FALSE)

{

RETAILMSG(1,(TEXT("TTY: erreur %d dans KernelLibIoControl\n"),GetLastError()));

return FALSE;

}

jc/md/lp-01/05 TTY_IT : corrigé 37

TTY_Init (7)

// Création de l’événement de lien pour l’ISThIstEvent=CreateEvent(NULL,FALSE,FALSE,NULL);

if(hIstEvent==0)

{

RETAILMSG(1,(TEXT("TTY: erreur %d dans CreateEvent (hIstEvent)\n"),GetLastError()));

return FALSE;

}

jc/md/lp-01/05 TTY_IT : corrigé 38

TTY_Init (8)

// Création de l’événement de synchro IST/driver

// Handle déclaré en variable globale : hMonEvent

hMonEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

if(hMonEvent == 0)

{

RETAILMSG(1,(TEXT("TTY: erreur %d dans CreateEvent (hMonEvent)\n"),GetLastError()));

return 0;

}

jc/md/lp-01/05 TTY_IT : corrigé 39

TTY_Init (9)

// Initialisation de la structure

TTY_ISTData.hEvent=hIstEvent;

TTY_ISTData.sysIntr=dwSYSINTR_A_Moi;

TTY_ISTData.bAbort=FALSE;

// Inhibition (Disable) de l’interruption logique

InterruptDisable(TTY_ISTData.sysIntr);

jc/md/lp-01/05 TTY_IT : corrigé 40

TTY_Init (10)

// Création et démarrage du thread IST

TTY_ISTData.hThread=CreateThread(NULL,0, &TTYIST,&TTY_ISTData,0,NULL);

if(TTY_ISTData.hThread ==0)

{

RETAILMSG(1,(TEXT("TTY: erreur % d dans CreateThread (TTY_ISTData)\n"),GetLastError()));

return 0;

}

jc/md/lp-01/05 TTY_IT : corrigé 41

TTY_Init (11)

// Connexion de l’IT logique avec l’événementdwErrCode=InterruptInitialize(dwSYSINTR_A_Moi, TTY_ISTData.hEvent,NULL,0);

if(dwErrCode==FALSE){

RETAILMSG(1,(TEXT("TTY: erreur %d dans InterruptInitialize\n"),GetLastError()));

return 0;}

jc/md/lp-01/05 TTY_IT : corrigé 42

TTY_Init (12)

// Mise en priorité maximale du thread

dwErrCode=CeSetThreadPriority(TTY_ISTData.hThread ,0);

if(dwErrCode==FALSE)

{

RETAILMSG(1,(TEXT("TTY: erreur %d dans CeSetThreadPriority\n"),GetLastError()));

return 0;

}

jc/md/lp-01/05 TTY_IT : corrigé 43

TTY_Init (13)

RETAILMSG(1,(TEXT("TTY: OK IT Init\n")));

return !0;

}// Fin TTY_Init

jc/md/lp-01/05 TTY_IT : corrigé 44

TTY_Deinit (1)

BOOL TTY_Deinit(DWORD hDeviceContext){

RETAILMSG(1,(TEXT("TTY: TTY_Deinit\n")));// Mise du flag bAbort à TRUE pour arrêter l'ISTTTY_ISTData.bAbort=TRUE;

// Inhibition (Disable) de l’IT logique : InterruptDisableInterruptDisable(TTY_ISTData.sysIntr);

jc/md/lp-01/05 TTY_IT : corrigé 45

TTY_Deinit (2)

// Fermeture des handles

CloseHandle(TTY_ISTData.hEvent);

CloseHandle(TTY_ISTData.hThread);

CloseHandle(hMonEvent);

return TRUE;

}// Fin TTY_Deinit

jc/md/lp-01/05 TTY_IT : corrigé 46

TTY_Open (1)

DWORD TTY_Open(DWORD hDeviceContext,

DWORD AccessCode, DWORD ShareMode)

{

RETAILMSG(1,(TEXT("TTY: TTY_Open\n")));

// Initialisations complémentaires du périphérique

// Vidage du buffer de réception si nécessaire

while((READ_PORT_UCHAR(IoPortBase+ comLineStatus)&LS_RX_DATA_READY)==1)

READ_PORT_UCHAR(IoPortBase+comRxBuffer);

jc/md/lp-01/05 TTY_IT : corrigé 47

TTY_Open (2)

// Autoriser l'IT Receiver Ready

WRITE_PORT_UCHAR(IoPortBase+comIntEnable,

0x01);

return !0;

}// Fin TTY_Open

jc/md/lp-01/05 TTY_IT : corrigé 48

TTY_Close

BOOL TTY_Close(DWORD hOpenContext)

{

RETAILMSG(1,(TEXT("TTY: TTY_Close\n")));

// Inhibition de l'IT Receiver Ready

WRITE_PORT_UCHAR(IoPortBase+comIntEnable,

0x0);

return TRUE;

}// Fin TTY_Close

jc/md/lp-01/05 TTY_IT : corrigé 49

TTY_IOControl (1)

BOOL TTY_IOControl(DWORD hOpenContext,

DWORD dwCode,

PBYTE pBufIn,

DWORD dwLenIn,

PBYTE pBufOut,

DWORD dwLenOut,

PDWORD pdwActualOut)

{

switch(dwCode)

{

jc/md/lp-01/05 TTY_IT : corrigé 50

TTY_IOControl (2)

case IOCTL_PUTC:

// Attente transmetteur Ready

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 TTY_IT : corrigé 51

TTY_IOControl (3)

case IOCTL_GETC:

// Attente de l’Event hMonEvent

WaitForSingleObject(hMonEvent,INFINITE); // Écriture du caractère dans le buffer

// de sortie. Le caractère lu sur IT est dans// ucBufIn, variable globale

pBufOut[0]=ucBufIn;

// Reset de l’EVENT hMonEvent

ResetEvent(hMonEvent);

break;

jc/md/lp-01/05 TTY_IT : corrigé 52

TTY_IOControl (4)

}// Fin switch

// Informe l’application qu’un caractère a été lu

*pdwActualOut=1;

return TRUE;

}// Fin TTY_IOControl

jc/md/lp-01/05 TTY_IT : corrigé 53

IST

jc/md/lp-01/05 TTY_IT : corrigé 54

IST (1)

DWORD TTYIST(void *p){

ISTDATA *pData; pData=(ISTDATA*)p;

// Boucle tant que bAbort = FALSEwhile(!pData->bAbort)

{ // Attente de l’événement associé à l’IT WaitForSingleObject(pData->hEvent,INFINITE);

if(pData->bAbort) break;

RETAILMSG(1,(TEXT("MIRACLE IT\n")));

jc/md/lp-01/05 TTY_IT : corrigé 55

IST (2)

// Traitement de l'interruption

// Lecture du caractère reçu; on le met dans ucBufIn

ucBufIn=READ_PORT_UCHAR(IoPortBase+ comRxBuffer);

// Positionner hMonEvent pour prévenir le driver

SetEvent(hMonEvent);

// Informer l’OS que l’IT est traitée : InterruptDone

InterruptDone(pData->sysIntr);

}// Fin boucle

jc/md/lp-01/05 TTY_IT : corrigé 56

IST (3)

RETAILMSG(1,(TEXT("Fin TTYIST\n")));

return 0;

}// Fin TTYIST

jc/md/lp-01/05 TTY_IT : corrigé 57

Structure de l’ISR

jc/md/lp-01/05 TTY_IT : corrigé 58

Création du projet ISR (1)

NommerValider

Choisir

Choisir

jc/md/lp-01/05 TTY_IT : corrigé 59

Création du projet ISR (2)

ChoisirValider

jc/md/lp-01/05 TTY_IT : corrigé 60

TTYISR.cpp

jc/md/lp-01/05 TTY_IT : corrigé 61

Création de TTYISR.def

• Mettre le fichier TTYISR.def dans le projet par l’une des méthodes déjà rencontrées

– Création d’un nouveau fichier de type texte sous Platform Builder (directement inséré dans le projet)

– Création du fichier sous un éditeur de texte dans le répertoire TTYISR puis addition au projet

jc/md/lp-01/05 TTY_IT : corrigé 62

TTYISR.def

LIBRARY TTYISR

EXPORTS

ISRHandler

IOControl

jc/md/lp-01/05 TTY_IT : corrigé 63

ISR (1)

#include " stdafx.h "

#include <nkintr.h>

#include <wdm.h>

#include <Pkfuncs.h>

// Définition de l’IOCTL de communication driver/ISR

#define IOCTL_val_SYSINTR \

CTL_CODE(FILE_DEVICE_UNKNOWN,2050,\

METHOD_BUFFERED,FILE_ANY_ACCESS)

jc/md/lp-01/05 TTY_IT : corrigé 64

ISR (2)

DWORD dwSYSINTR_A_Moi;

// Entrée de l'ISRBOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){ return TRUE;}// Fin DllMain

jc/md/lp-01/05 TTY_IT : corrigé 65

ISR (3)

BOOL IOControl(

DWORD InstanceIndex,

DWORD IoControlCode,

LPDWORD pInBuf,

DWORD InBufSize,

LPDWORD pOutBuf,

DWORD OutBufSize,

LPDWORD pBytesReturned)

{

switch(IoControlCode)

jc/md/lp-01/05 TTY_IT : corrigé 66

ISR (4)

{case IOCTL_VAL_SYSINTR:

// Récupération de la valeur de // dwSYSINTR_A_Moi

dwSYSINTR_A_Moi=pInBuf[0];break;

}// Fin switch // Informe l’application qu’un caractère a été lu *pBytesReturned = 1; return TRUE;}// Fin IOControl

jc/md/lp-01/05 TTY_IT : corrigé 67

ISR (5)DWORD ISRHandler(DWORD InstanceIndex){//Test que IT bien active,status en 0x2F8 +5, RxRdy bit 0 __asm {

mov dx,02FDhin al,dxand al,01h

jnz it_a_moi}

//it_pas_a_moi: return SYSINTR_CHAIN;

it_a_moi:return dwSYSINTR_A_Moi;

}

jc/md/lp-01/05 TTY_IT : corrigé 68

Application

jc/md/lp-01/05 TTY_IT : corrigé 69

Applicaton

• Application qui utilise le driver TTYIT_DRV• Le programme est très simple, il doit :

– Écrire un $ avec IOCTL_ PUTC– Attendre la réception d’un caractère 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 TTY_IT : corrigé 70

Création de l’application (1)

Choisir New Project or File

Choisir

Nommer

Valider

jc/md/lp-01/05 TTY_IT : corrigé 71

Création de l’application (2)

Valider

Choisir

jc/md/lp-01/05 TTY_IT : corrigé 72

TTYIT_APP.cpp

jc/md/lp-01/05 TTY_IT : corrigé 73

Application (1)

// #include nécessaires#include "stdafx.h"#include <windev.h>

// Définition des IOCTL#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)

jc/md/lp-01/05 TTY_IT : corrigé 74

Application (2)

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){

// Initialisations et réservations HANDLE hDevice,hTTY;

UCHAR carac[4];DWORD dwNb;

jc/md/lp-01/05 TTY_IT : corrigé 75

Application (3)

// Chargement du driver qui retourne un handle hDevicehDevice=RegisterDevice(TEXT("TTY"),1, TEXT("TTYIT_DRV.dll"),NULL);if(hDevice==INVALID_HANDLE_VALUE)

{ MessageBox(NULL,_T("PB Register TTY1:"),

_T("TTYApp"),MB_OK); return 0; }

MessageBox(NULL,_T("Register TTY1 OK:"), _T("TTYApp"),MB_OK);

jc/md/lp-01/05 TTY_IT : corrigé 76

Application (4)

// Ouverture du driver avec retour du HANDLE hTTYhTTY=CreateFile(TEXT("TTY1:"),GENERIC_READ| GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,0);

if(hTTY==INVALID_HANDLE_VALUE) {

MessageBox(NULL,_T("Pb Open TTY1:"), _T("TTYApp"),MB_OK); DeregisterDevice(hDevice); CloseHandle(hDevice);

return 0; }

jc/md/lp-01/05 TTY_IT : corrigé 77

Application (5)

// Envoi d'un caractère $

carac[0]=0x24;

// Appel de IOCTL_PUTC

DeviceIoControl(hTTY,IOCTL_PUTC,carac,1, carac,1,&dwNb,NULL);

jc/md/lp-01/05 TTY_IT : corrigé 78

Application (6)

// Boucle tant que le caractère n'est pas Escape

while(carac[0] != 0x1B)

{

// Appel de IOCTL_GETC

DeviceIoControl(hTTY,IOCTL_GETC,carac,1, carac,1,&dwNb,NULL);

// Appel de IOCTL_PUTC

DeviceIoControl(hTTY,IOCTL_PUTC,carac,1, carac,1,&dwNb,NULL);

}// Fin boucle

jc/md/lp-01/05 TTY_IT : corrigé 79

Application (7)

MessageBox(NULL,_T("OK pour finir"), _T("TTYApp"),MB_OK);

// Déchargement du driver

// Fermeture des handles

CloseHandle(hTTY);

DeregisterDevice(hDevice);

CloseHandle(hDevice);

return 0;

}// WinMain

jc/md/lp-01/05 TTY_IT : corrigé 80

Configuration pour l’application

ChoisirChoisir

Valider

Choisir Settings…

jc/md/lp-01/05 TTY_IT : corrigé 81

Configuration pour l’ISR

ChoisirChoisir

Valider

Choisir Settings…

Vérifier

jc/md/lp-01/05 TTY_IT : corrigé 82

Configuration pour le driver

ChoisirChoisir

Valider

Choisir Settings…

jc/md/lp-01/05 TTY_IT : corrigé 83

Option pour la génération

• L’ISR doit être généré sans les « C Run Times »• Il faut modifier les options pour l’édition de lien

pendant la génération

jc/md/lp-01/05 TTY_IT : corrigé 84

Configuration de l’édition de liens

Choisir puis click droit

Choisir

jc/md/lp-01/05 TTY_IT : corrigé 85

Options de l’édition de liens

Modifier

Choisir

Valider

jc/md/lp-01/05 TTY_IT : corrigé 86

Project Options pour l’ISR

coredll.libcoredll.lib/nologo/nologo/base:"0x00100000"  /base:"0x00100000"  /stack:0x10000,0x1000/stack:0x10000,0x1000/entry:"DllMain"/entry:"DllMain"/dll/dll/incremental:no/incremental:no/pdb:"CEPC__X86Rel/TTYISR.pdb"/pdb:"CEPC__X86Rel/TTYISR.pdb"/machine:IX86 /nodefaultlib:"OLDNAMES.lib" /nodefaultlib:"$/machine:IX86 /nodefaultlib:"OLDNAMES.lib" /nodefaultlib:"$(CENoDefaultLib)" (CENoDefaultLib)" /def:".\TTYISR.def" /def:".\TTYISR.def" /out:"CEPC__X86Rel/TTYISR.dll" /out:"CEPC__X86Rel/TTYISR.dll" /implib:"CEPC__X86Rel/TTYISR.lib" /implib:"CEPC__X86Rel/TTYISR.lib" /subsystem:$(CESubsystem)/subsystem:$(CESubsystem)

jc/md/lp-01/05 TTY_IT : corrigé 87

Insertion dans le noyau

• Contrairement aux exécutables et aux drivers, l’ISR ne s’exécute pas en mode user mais en mode superviseur

• Il faut empêcher le système d’opérer des translations d’adresse sur les zones de code et de données des ISR

• Pour obtenir ce résultat il faut préciser que l’ISR doit être dans une section « FILES » au lieu d’une section « MODULES » dans les listes du fichier project.bib

jc/md/lp-01/05 TTY_IT : corrigé 88

Insertion de l’ISR dans project.bib

Choisir

Dérouler

Ouvrir (double clic)

Vérifier (clic droit)

jc/md/lp-01/05 TTY_IT : corrigé 89

Ajouter TTYISR.dll

Bloc mémoire Options

Répertoire Nom du fichier

jc/md/lp-01/05 TTY_IT : corrigé 90

Génération

• Il n’y a plus qu’à faire la génération du système avec son driver pour la ligne série et l’application

• Puis tester :– Télécharger dans la cible le noyau et son driver– Exécuter l’application– Observer l’affichage du caractère $– Observer l’écho des frappes sur le clavier– Sortir de l’application par la frappe du caractère

escape

jc/md/lp-01/05 TTY_IT : corrigé 91

Debug

jc/md/lp-01/05 TTY_IT : corrigé 92

Debug

• Mettre le mode Debug et modifier les options – Platform

→Settings

→Build Options

Cocher Enable Event Tracking During Boot Enable Full Kernel Mode Enable Kernel Debugger Enable Profiling

• Vérifier toutes les  options

– Platform Settings (Build avec ou sans image)– Project Settings (Link…)

jc/md/lp-01/05 TTY_IT : corrigé 93

Options de débogage

Mode Debug

Choisir

Cocher les options

Valider

Ouvrir

Choisir

jc/md/lp-01/05 TTY_IT : corrigé 94

Configuration pour l’ISR

Choisir Choisir

Valider

Choisir Settings…

Choisir

jc/md/lp-01/05 TTY_IT : corrigé 95

Configuration pour l’application

ChoisirChoisir

Valider

Choisir Settings…

jc/md/lp-01/05 TTY_IT : corrigé 96

Configuration pour le driver

Choisir

Choisir

Valider

Choisir Settings…

jc/md/lp-01/05 TTY_IT : corrigé 97

Configuration de l’édition de liens

Choisir puis click droit

Choisir

jc/md/lp-01/05 TTY_IT : corrigé 98

Options pour l’édition de liens

Choisir

Choisir

Valider

Choisir

Modifier

jc/md/lp-01/05 TTY_IT : corrigé 99

Project Options pour l’ISR

coredll.libcoredll.lib/nologo/nologo/base:"0x00100000"  /base:"0x00100000"  /stack:0x10000,0x1000/stack:0x10000,0x1000/entry:"DllMain"/entry:"DllMain"/dll/dll/incremental:no/incremental:no/pdb:"CEPC__X86/pdb:"CEPC__X86DbgDbg/TTYISR.pdb« /TTYISR.pdb« 

/debug/debug/machine:IX86 /nodefaultlib:"OLDNAMES.lib" /nodefaultlib:"$/machine:IX86 /nodefaultlib:"OLDNAMES.lib" /nodefaultlib:"$(CENoDefaultLib)" (CENoDefaultLib)" /def:".\TTYISR.def" /def:".\TTYISR.def" /out:"CEPC__X86/out:"CEPC__X86DbgDbg/TTYISR.dll" /TTYISR.dll" /implib:"CEPC__X86/implib:"CEPC__X86DbgDbg/TTYISR.lib" /TTYISR.lib" /subsystem:$(CESubsystem)/subsystem:$(CESubsystem)

jc/md/lp-01/05 TTY_IT : corrigé 100

Kernel Debugger

• Utiliser le Kernel Debugger pour visualiser les interruptions

• Vérifier les numéros de process et de threads• Examiner la chronologie des threads application,

driver, ISR et IST• Mesurer les temps d’exécution

jc/md/lp-01/05 TTY_IT : corrigé 101

Exécution de l’application

Repérer les paramètres

jc/md/lp-01/05 TTY_IT : corrigé 102

Paramètres

• PID TTYIT_APP 43a084fa• TID TTYIT_APP 43a084ca• PID TTYIT_DRV e3ba39e2• TID TTYIT_DRV 43a084ca• dwSYSINTR_A_Moi 16

jc/md/lp-01/05 TTY_IT : corrigé 103

Lancement du Kernel Tracker

Choisir

jc/md/lp-01/05 TTY_IT : corrigé 104

État avant d’entrer un caractère

jc/md/lp-01/05 TTY_IT : corrigé 105

Après frappe sur le clavier (IT)

jc/md/lp-01/05 TTY_IT : corrigé 106

Quand l’IST fonctionne

Repérer les paramètres

jc/md/lp-01/05 TTY_IT : corrigé 107

Paramètres IST

• PID IST eba39e2 • TID IST 839e5f02

jc/md/lp-01/05 TTY_IT : corrigé 108

Recherche de l’IT 16

• Arrêter le défilement avec icône |→• Déplacer le curseur pour trouver une IT 16

active• Adapter la « Zoom Range »

jc/md/lp-01/05 TTY_IT : corrigé 109

IT 16

jc/md/lp-01/05 TTY_IT : corrigé 110

IST : set hMonEvent

Thread IST

jc/md/lp-01/05 TTY_IT : corrigé 111

IST : attente de hMonEvent

jc/md/lp-01/05 TTY_IT : corrigé 112

Application et driverreset de hMonEvent

jc/md/lp-01/05 TTY_IT : corrigé 113

Application et driverattente de hMonEvent

jc/md/lp-01/05 TTY_IT : corrigé 114

Arrivée de l’IT

jc/md/lp-01/05 TTY_IT : corrigé 115

Mesure des temps

• IT → IST : 0,2 ms• Durée IST : 3,2 ms• Durée application : 1,3 ms

jc/md/lp-01/05 TTY_IT : corrigé 116

Conclusion

Nous avons :• Réalisé un ensemble driver/ISR/IST pour gérer

une interruption provenant du sérialiseur• Réalisé une application recevant un caractère

du sérialiseur avec une gestion par IT• Examiné avec le Kernel Debugger les différents

threads et leur chronologie

Recommended