OAL OEM Adaptation Layer Original Equipment Manufacturer jcmdlp0105







































![WRITE_PORT_UCHAR VOID WRITE_PORT_UCHAR( PUCHAR Port, UCHAR Value); Parameters Port [in] Pointer to the port WRITE_PORT_UCHAR VOID WRITE_PORT_UCHAR( PUCHAR Port, UCHAR Value); Parameters Port [in] Pointer to the port](https://slidetodoc.com/presentation_image_h/11de980106f7102cf12fecf7c4aa9aa1/image-40.jpg)
![READ_PORT_UCHAR( PUCHAR Port ); Parameters Port [in] Pointer to the port that must be READ_PORT_UCHAR( PUCHAR Port ); Parameters Port [in] Pointer to the port that must be](https://slidetodoc.com/presentation_image_h/11de980106f7102cf12fecf7c4aa9aa1/image-41.jpg)




































- Slides: 77
OAL OEM Adaptation Layer (Original Equipment Manufacturer) jc/md/lp-01/05 OAL x 86 1
Objectif du chapitre • Présentation de la couche OAL • Survol de l’initialisation de la plate-forme • Fonctionnement des interruptions dans une architecture PC classique à base de x 86 • Interruptions dans Windows CE • Étude de l’exemple de la liaison série – Contrôleur de ligne série 16550 – Contrôleur d’interruption 8259 – Programmes d’initialisation du 16550 et du 8259 jc/md/lp-01/05 OAL x 86 2
OAL (1) • Couche logicielle d’adaptation entre le noyau Windows CE standard et le hardware spécifique utilisé dans une application • L’OAL assure l’initialisation de la plate-forme lors du lancement du système à partir du boot loader ou à partir d’une réinitialisation physique « reset » jc/md/lp-01/05 OAL x 86 3
OAL (2) • En particulier initialisation des mécanismes nécessaires immédiatement : • Debugging (série, parallèle, Ethernet) • Interruptions • Real Time Clock • Timers • Outils de diagnostic jc/md/lp-01/05 OAL x 86 4
Interruptions x 86 • 2 entrées d’interruptions sur les CPU x 86 – NMI non masquable – INT classique • Nécessité d’un contrôleur externe pour disposer d’un plus grand nombre d’interruptions • Contrôleur Intel 8259 A (PIC) « norme » PC • Gestion par une table de vecteurs jc/md/lp-01/05 OAL x 86 5
PIC • Gère 8 IT (cascadable jusqu’à 64 IT) • Gère les priorités • 2 PICs dans les CEPC (15 lignes d’IT) – Un maître qui transmet la demande au CPU – Un esclave connecté sur l’IRQ 2 du maître jc/md/lp-01/05 OAL x 86 6
OAL • Cette couche étant spécifique au hardware réalisé, c’est au concepteur du hardware d’écrire les routines nécessaires • Nous prendrons comme exemple les routines d’initialisation de la ligne série et du contrôleur d’interruption PIC jc/md/lp-01/05 OAL x 86 7
Configuration de base PC • Dans l’architecture classique d’un PC, on trouve autour d’un CPU x 86 au moins les éléments suivants : • Contrôleur de ligne série : 16650 • Contrôleur d’IT : 8259 • Timer : 8254 • Horloge temps réel RTC : 146818 • Contrôleur de DMA : 8237 jc/md/lp-01/05 OAL x 86 8
OAL Architecture jc/md/lp-01/05 OAL x 86 9
Démarrage de CE • Point d’entrée : procédure _Startup • Startup appelle Kernel. Initialize • Kernel. Initialize appelle : – OEMInit. Debug. Serial – OEMInit – OEMGet. Extension. DRAM • Kernel. Initialize lance le noyau jc/md/lp-01/05 OAL x 86 10
Startup • Initialisation du CPU – Mode superviseur – Little endian – Disable interrupts – Inhibit du cache et du MMU – Configuration du contrôleur mémoire – Configuration des LEDs – … • Saut à Kernel. Initialize jc/md/lp-01/05 OAL x 86 11
Initialisation du port de Debug • OEMInit. Debug. Serial() – Configuration de la ligne série • OEMRead. Debug. Byte() – Lecture d’un byte • OEMWrite. Debug. Byte() – Écriture d’un byte • OEMWrite. Debug. String() – Écriture d’une chaîne de caractères jc/md/lp-01/05 OAL x 86 12
OEMInit • • Initialisation du hardware non faite dans Start. Up Mapping des interruptions Initialisation des PICs Fonctions de gestion des interruptions Initialisation des timers Initialisation du port parallèle Initialisation du debug Ethernet Initialisation du bus PCI jc/md/lp-01/05 OAL x 86 13
OEMGet. Extension. DRAM • La fonction provoque le parcours de la mémoire en faisant des cycles écriture/lecture pour détecter la fin réelle de la zone mémoire. • La valeur par défaut située dans Config. bib sera ajustée • Un mécanisme plus complexe remplace cette fonction lorsqu’on veut gérer plus de deux sections de mémoire jc/md/lp-01/05 OAL x 86 14
Mapping des interruptions (1) • Un système x 86 dispose de 16 niveaux d’interruption (dont un sert au chaînage) • Afin qu’un même niveau physique puisse être partagé par plusieurs périphériques, le système utilise un numéro logique SYSINTR_XXXXX • Il faut donc créer des tables de correspondance – Numéro logique → numéro physique – Numéro physique → numéro logique jc/md/lp-01/05 OAL x 86 15
Mapping des interruptions (2) • Il y a 40 numéros logiques possibles • Les numéros logiques 0 à 15 sont réservés par Microsoft • Le numéro logique 16 porte le nom de SYSINTR_FIRMWARE • Un certain nombre de numéros logiques sont affectés lors du mapping initial • Un utilisateur qui lance un driver sous IT, non mappé au départ doit obtenir un numéro logique par la fonction Kernel. Io. Control jc/md/lp-01/05 OAL x 86 16
Mapping des interruptions (3) • Au départ les deux tables de correspondance sont initialisées à 0 x. FF • Une macro assure le remplissage des deux tables SETUP_INTERRUPT_MAP(Sys. Intr, Irq) • Une fonction de Debug est utilisée pour s’assurer qu’au départ la correspondance entre l’IT physique et l’IT logique est bien unique jc/md/lp-01/05 OAL x 86 17
Mapping des interruptions (4) • Après lancement du système, d’autres utilisateurs pourront venir ajouter leur programme d’interruption – Sur un niveau physique libre – Sur un niveau physique déjà utilisé en établissant un chaînage jc/md/lp-01/05 OAL x 86 18
Mapping des interruptions (5) Void Set. Up. Interrupt. Map() { // Initialisation des 2 tables de correspondance // Dans les fonctions prononcer le 2 à l’anglaise : « to » ! memset(g_Sysintr 2 Intr. Map, 0 x. FF, sizeof(g_Sysintr 2 Intr. Map)); memset(g_Intr 2 Sysintr. Map, 0 x. FF, sizeof(g_Intr 2 Sysintr. Map)); //MACRO #define SETUP_INTERRUPT_MAP(Sys. Intr, Irq) { DEBUGCHK(g_Sysintr 2 Intr. Map[Sys. Intr] == INTR_UNDEFINED); DEBUGCHK(g_Intr 2 Sysintr. Map[Irq] == SYSINTR_UNDEFINED); g_Sysintr 2 Intr. Map[Sys. Intr] = Irq; g_Intr 2 Sysintr. Map[Irq] = Sys. Intr; } jc/md/lp-01/05 OAL x 86 19
Mapping des interruptions (6) // IRQ 0 is timer 0, the scheduler tick SETUP_INTERRUPT_MAP(SYSINTR_RESCHED, INTR_TIMER 0); SETUP_INTERRUPT_MAP(SYSINTR_KEYBOARD, 1); // IRQ 2 is the cascade interrupt for the second PIC SETUP_INTERRUPT_MAP(SYSINTR_FIRMWARE+3, 3); SETUP_INTERRUPT_MAP(SYSINTR_FIRMWARE+4, 4); SETUP_INTERRUPT_MAP(SYSINTR_FIRMWARE+5, 5); // IRQ 6 is normally the floppy controller. // IRQ 7 is LPT 1, It can be used for parallel port driver. SETUP_INTERRUPT_MAP(SYSINTR_FIRMWARE+7, 7); // IRQ 8 is the real time clock. jc/md/lp-01/05 OAL x 86 20
Mapping des interruptions (7) SETUP_INTERRUPT_MAP(SYSINTR_FIRMWARE+9, 9); SETUP_INTERRUPT_MAP(SYSINTR_FIRMWARE+10, 10); SETUP_INTERRUPT_MAP(SYSINTR_FIRMWARE+11, 11); SETUP_INTERRUPT_MAP(SYSINTR_TOUCH, 12); // IRQ 13 is normally the coprocessor // IRQ 14 is normally the hard disk controller. SETUP_INTERRUPT_MAP(SYSINTR_FIRMWARE+14, 14); SETUP_INTERRUPT_MAP(SYSINTR_FIRMWARE+15, 15); #undef SETUP_INTERRUPT_MAP } jc/md/lp-01/05 OAL x 86 21
Fonctions de gestion des interruptions • OEMInterrupt. Enable • OEMInterrupt. Disable • OEMInterrupt. Done • Ces fonctions sont appelées par le noyau pour compléter l’action des fonctions système: – Interrupt. Initialize – Interruptdisable – Interrupt. Done jc/md/lp-01/05 OAL x 86 22
Fonctions de gestion de consommation • OEMIdle • OEMPower. Off jc/md/lp-01/05 OAL x 86 23
Fonctions de gestion du temps • • OEMGet. Real. Time OEMSet. Alarm. Time SC_Get. Tick. Count jc/md/lp-01/05 OAL x 86 24
Fonctions de gestion port parallèle • OEMParallel. Port. Get. Byte • OEMParallel. Port. Send. Byte • OEMParallel. Port. Get. Status jc/md/lp-01/05 OAL x 86 25
Fonctions de gestion ethernet • • OEMEth. Init OEMEth. Enable. Ints OEMEth. Disable. Ints OEMEth. ISR OEMEth. Get. Frame OEMEth. Send. Frame OEMEth. Query. Client. Info OEMEth. Get. Secs jc/md/lp-01/05 OAL x 86 26
Liaison série 16550 jc/md/lp-01/05 OAL x 86 27
16550 • UART asynchrone jusqu’à 1, 5 Mbauds • Gestion des signaux MODEM • 12 registres internes sélectionnés par 3 signaux d’adresse, les signaux Read et Write et le bit 7 (DLAB) du registre LCR (Line Control Register) • Mode avec FIFO : 16 bytes en émission et en réception • Mode sans FIFO : double buffer en émission et en réception jc/md/lp-01/05 OAL x 86 28
Registres du 16550 DLAB A 2 A 1 A 0 R/W Register 0 0 R RBR : Receiver Buffer Register 0 0 W THR : Transmitter Holding Register 0 0 0 1 R/W IER : Interrupt Enable Register x 0 1 0 R IIR : Interrupt Identification Register (status) x 0 1 0 W FCR : FIFO Control Register x 0 1 1 R/W LCR : Line Control Register x 1 0 0 R/W MCR : MODEM Control Register x 1 0 1 R/W LSR : Line Status Register x 1 1 0 R/W MSR : MODEM Status Regster x 1 1 1 R/W SCR : Scratch Register 1 0 0 0 R/W DLL : Divisor Latch least (Baud Rate low) 1 0 0 1 R/W DLM : Divisor Latch most (Baud Rate high) jc/md/lp-01/05 OAL x 86 29
Interrupt Enable Register • • Bit 0 : autorisation IT récepteur ready Bit 1 : autorisation IT transmetteur vide Bit 2 : autorisation IT erreur en réception Bit 3 : autorisation IT MODEM status Bit 4 : 0 Bit 5 : 0 Bit 6 : 0 Bit 7 : 0 jc/md/lp-01/05 OAL x 86 30
Interrupt Identification Register • • Bit 0 : 0 si IT pending Bit 1 : codage de la source de l’ IT (bit 0) Bit 2 : codage de la source de l’ IT (bit 1) Bit 3 : codage de la source de l’ IT (bit 2) Bit 4 : 0 Bit 5 : 0 Bit 6 : 1 si FIFO en service Bit 7 : 1 si FIFO en service Ø Exemple : un codage de l’ IT = 4 correspond à une interruption du Receiver pour « caractère disponible » jc/md/lp-01/05 OAL x 86 31
FIFO Control Register • • Bit 0 : 1 autorise la FIFO Bit 1 : 1 reset de la Receive FIFO Bit 2 : 1 reset de la Transmit FIFO Bit 3 : DMA Mode Bit 4 : réservé Bit 5 : réservé Bit 6 : seuil de déclenchement IT FIFO ( LSB) Bit 7 : seuil de déclenchement IT FIFO ( MSB) jc/md/lp-01/05 OAL x 86 32
Line Control Register • • Bit 0 : codage nombre de bits de data Bit 1 : codage nombre de bits de data Bit 2 : 0 un bit de stop Bit 3 : 0 pas de parité, 1 avec parité Bit 4 : 0 parité impaire, 1 parité paire Bit 5 : logique du bit de parité Bit 6 : 1 génération d’un break Bit 7 : DLAB (accès Baud Rate Registers) Ø Ex : codage du nombre de bits : %11 → 8 bits data jc/md/lp-01/05 OAL x 86 33
MODEM Control Register • • Bit 0 : DTR, gère le signal DTR Bit 1 : RTS, le signal RTS Bit 2 : OUT 1, gère une sortie auxiliaire Bit 3 : OUT 2, gère une sortie auxiliaire Bit 4 : LOOP, gère le mode loopback Bit 5 : 0 Bit 6 : 0 Bit 7 : 0 jc/md/lp-01/05 OAL x 86 34
Line Status Register • • Bit 0 : 1 DR, Receiver Data Ready Bit 1 : 1 OE, Overrun Error Bit 2 : 1 PE, Parity Error Bit 3 : 1 FE, Framing Error Bit 4 : 1 BI, Break Interrupt Bit 5 : 1 THRE, Transmitter Holding Reg. Empty Bit 6 : 1 TEMT, Transmitter Empty (vide) Bit 7 : 1 erreur dans la FIFO de réception jc/md/lp-01/05 OAL x 86 35
Baud Rate Generator • Avec un oscillateur à 1, 8432 MHz les nombres à placer dans les registres diviseurs du Baud Rate Generator pour obtenir les vitesses classiques sont : – 110 bauds 1047 – 330 bauds 384 – 1200 bauds 96 – 9600 bauds 12 – 38400 bauds 3 jc/md/lp-01/05 OAL x 86 36
Offset des registres du 16550 #define Io. Port. Base ((PUCHAR) 0 x 03 F 8) #define com. Tx. Buffer 0 x 00 #define com. Rx. Buffer 0 x 00 #define com. Divisor. Low 0 x 00 #define com. Divisor. High 0 x 01 #define com. Int. Enable 0 x 01 #define com. Int. Id 0 x 02 #define com. FIFOControl 0 x 02 #define com. Line. Control 0 x 03 #define com. Modem. Control 0 x 04 #define com. Line. Status 0 x 05 #define com. Modem. Status 0 x 06 jc/md/lp-01/05 OAL x 86 37
Status du 16550 // Masque des bits du Line Status Register #define LS_TSR_EMPTY 0 x 40 #define LS_THR_EMPTY 0 x 20 #define LS_RX_BREAK 0 x 10 #define LS_RX_FRAMING_ERR 0 x 08 #define LS_RX_PARITY_ERR 0 x 04 #define LS_RX_OVERRUN 0 x 02 #define LS_RX_DATA_READY 0 x 01 #define LS_RX_ERRORS (LS_RX_FRAMING_ERR | LS_RX_PARITY_ERR | LS_RX_OVERRUN) jc/md/lp-01/05 OAL x 86 38
Accès aux ports • Windows CE utilise deux fonctions pour accéder aux registres de l’espace I/O utilisé par tous les périphériques – WRITE_PORT_UCHAR – READ_PORT_UCHAR jc/md/lp-01/05 OAL x 86 39
WRITE_PORT_UCHAR VOID WRITE_PORT_UCHAR( PUCHAR Port, UCHAR Value); Parameters Port [in] Pointer to the port that must be a mapped memory range in I/O space. Value [in] Byte to be written to the port. Return Values None. jc/md/lp-01/05 OAL x 86 40
READ_PORT_UCHAR( PUCHAR Port ); Parameters Port [in] Pointer to the port that must be a mapped memory range in I/O space. Return Values This function returns the byte read from the specified port address. jc/md/lp-01/05 OAL x 86 41
OEMInit. Debug. Serial // Access Baud Divisor, DLAB=1 WRITE_PORT_UCHAR(Io. Port. Base+com. Line. Control, 0 x 80); // 38400 Bauds WRITE_PORT_UCHAR(Io. Port. Base+com. Divisor. Low, 0 x 3); WRITE_PORT_UCHAR(Io. Port. Base+com. Divisor. High, 0 x 00); // 8 -bit, no parity, DLAB=0 WRITE_PORT_UCHAR(Io. Port. Base+com. Line. Control, 0 x 03); // Enable FIFO if present WRITE_PORT_UCHAR(Io. Port. Base+com. FIFOControl, 0 x 01); // No interrupts, polled WRITE_PORT_UCHAR(Io. Port. Base+com. Int. Enable, 0 x 00); // Assert DTR, RTS WRITE_PORT_UCHAR(Io. Port. Base+com. Modem. Control, 0 x 03); jc/md/lp-01/05 OAL x 86 42
OEMRead. Debug. Byte (1) int OEMRead. Debug. Byte(void) { unsigned char uc. Status; unsigned char uc. Char; if ( Io. Port. Base ) {// le port existe, lecture du status uc. Status = READ_PORT_UCHAR (Io. Port. Base+com. Line. Status); if ( uc. Status & LS_RX_DATA_READY ) {// il y a un caractère dans le buffer de réception uc. Char = READ_PORT_UCHAR (Io. Port. Base+com. Rx. Buffer); jc/md/lp-01/05 OAL x 86 43
OEMRead. Debug. Byte (2) // caractère correct ? if ( uc. Status & LS_RX_ERRORS ) return (OEM_DEBUG_COM_ERROR); else return (uc. Char); }// fin du if ( uc. Status & LS_RX_DATA_READY ) }// fin du if (Io. Port. Base) return (OEM_DEBUG_READ_NODATA); }// fin OEMRead. Debug. Byte jc/md/lp-01/05 OAL x 86 44
OEMWrite. Debug. Byte void OEMWrite. Debug. Byte(BYTE uc. Char) { if ( Io. Port. Base ) { while ( !(READ_PORT_UCHAR(Io. Port. Base+com. Line. Status) & LS_THR_EMPTY) ) { ; // le port existe, attente de Tx RDY } WRITE_PORT_UCHAR(Io. Port. Base+com. Tx. Buffer, uc. Char); } } jc/md/lp-01/05 OAL x 86 45
OEMWrite. Debug. String void OEMWrite. Debug. String(unsigned short *str) { if (Io. Port. Base) { while ( *str ) { while ( !(READ_PORT_UCHAR(Io. Port. Base+com. Line. Status) & LS_THR_EMPTY) ) { ; // le port existe, attente de Tx RDY } WRITE_PORT_UCHAR(Io. Port. Base+com. Tx. Buffer, (UCHAR)*str++); } }// fin du if (Io. Port. Base) } jc/md/lp-01/05 OAL x 86 46
Interrupt Request Register (1) • Mémorise les demandes d’interruption des lignes IR 0 à IR 7 • Pour les architectures X 86 la demande est mémorisée sur front montant • Acquittement automatique de la demande lors de la prise en compte par le processeur • Lorsqu’une demande est mémorisée, et si elle n’est pas masquée par l’Interrupt Mask Register, cela entraîne l’envoi du signal INT au CPU jc/md/lp-01/05 OAL x 86 47
Interrupt Request Register (2) jc/md/lp-01/05 OAL x 86 48
Interrupt Enable Register • Bit 0: This bit enables the Received Data Available Interrupt (and timeout INT in the FIFO mode) when set to logic 1 • Bit 1: This bit enables the Transmitter Holding Register Empty Interrupt when set to logic 1. • Bit 2: This bit enables the Receiver Line Status Interrupt when set to logic 1. • Bit 3: This bit enables the MODEM Status Interrupt when set to logic 1. • Bits 4 through 7: These four bits are always logic 0. jc/md/lp-01/05 OAL x 86 49
Programmable Interrupt Controller PIC 8259 A jc/md/lp-01/05 OAL x 86 50
Architecture du PIC jc/md/lp-01/05 OAL x 86 51
Câblage des PICs jc/md/lp-01/05 OAL x 86 52
Principe de fonctionnement • Les IRQ entrantes sont mémorisées dans le registre IRR (IRQ 0 la plus prioritaire) • Le priority resolver détermine le niveau demandeur autorisé le plus prioritaire et génère le signal INT • Le CPU répond par INTA ce qui mémorise le bit du niveau le plus prioritaire dans ISR • Le CPU envoie à nouveau INTA et récupère le vecteur d’interruption sur le bus de données jc/md/lp-01/05 OAL x 86 53
Interrupt Mask Register • Registre de 8 bits • Chaque bit correspond à un masque pour le niveau d’interruption correspondant • Un bit à 1 masque l’interruption • Une IT survenant sur un niveau masqué est mémorisée dans le registre IRR mais ne provoque pas l’envoi du signal INT vers le CPU • Ce registre (IMR) sera positionné par un mot de commande OCW 1 jc/md/lp-01/05 OAL x 86 54
In-Service Register • Mémorise les niveaux d’interruption en cours de traitement (1 bit par niveau) • En fin de traitement en mode X 86, le programme de traitement de l’interruption doit générer une commande pour acquitter le bit correspondant, à moins de fonctionner avec acquittement automatique jc/md/lp-01/05 OAL x 86 55
Accès aux registres • L’accès ne se fait pas par un adressage mais par l’envoi de mots de commande OCWx – OCW 1 permet d’écrire l’IMR – OCW 3 sélectionne la lecture de l’IRR ou de l’ISR. La lecture réelle de ces registres est faite par un nouvel accès au boîtier • L’accès aux registres par le logiciel n’a de sens qu’après le déroulement d’une séquence d’initialisation par l’envoi de mots ICWx jc/md/lp-01/05 OAL x 86 56
Programmation du PIC • Après un reset hardware le PIC doit être configuré par 3 ou 4 mots de commandes appelés ICWs (Initialization Command Word) • Un bit du mot de commande ICW 1 précise s’il y a 3 ou 4 mots de commande • ICW 1 est envoyé avec le bit A 0 à 0, les autres ICWs sont envoyés avec le bit A 0 à 1 • Après la phase d’initialisation le PIC peut recevoir de nouvelles commandes par des OCWs (Operation Command Word) jc/md/lp-01/05 OAL x 86 57
ICW 1 pour X 86 • • Bit 0 : 1 ICW 4 nécessaire Bit 1 : 0 mode cascadé, 1 PIC unique Bit 2 : 0 en X 86 Bit 3 : 0 interruption sur front, 1 sur niveau Bit 4 : 1 spécifie avec A 0 à 0 un ICW 1 Bit 5 : 0 en X 86 Bit 6 : 0 en X 86 Bit 7 : 0 en X 86 jc/md/lp-01/05 OAL x 86 58
ICW 2 pour X 86 • • Ø Bit 0 : 0 Bit 1 : 0 Bit 2 : 0 Bit 3 : bit V 3 du vecteur d’interruption Bit 4 : bit V 4 du vecteur d’interruption Bit 5 : bit V 5 du vecteur d’interruption Bit 6 : bit V 6 du vecteur d’interruption Bit 7 : bit V 7 du vecteur d’interruption Les bits 0, 1, 2 sont positionnés automatiquement par le PIC avec la valeur du niveau d’IT traitée jc/md/lp-01/05 OAL x 86 59
ICW 3 Maître • Bit 0 : 1 → entrée connectée sur un autre PIC • Bit 1 : 1 → entrée connectée sur un autre PIC • Bit 2 : 1 → entrée connectée sur un autre PIC • Bit 3 : 1 → entrée connectée sur un autre PIC • Bit 4 : 1 → entrée connectée sur un autre PIC • Bit 5 : 1 → entrée connectée sur un autre PIC • Bit 6 : 1 → entrée connectée sur un autre PIC • Bit 7 : 1 → entrée connectée sur un autre PIC Ø Dans notre cas un esclave sur IR 2 donc 0 x 04 jc/md/lp-01/05 OAL x 86 60
ICW 3 Esclave • Bit 0 : codage du slave ID (ID 0) • Bit 1 : codage du slave ID (ID 1) • Bit 2 : codage du slave ID (ID 2) • Bit 3 : 0 • Bit 4 : 0 • Bit 5 : 0 • Bit 6 : 0 • Bit 7 : 0 Ø Dans notre cas l’esclave est sur IR 2 d’où 010 jc/md/lp-01/05 OAL x 86 61
ICW 4 pour X 86 • • Bit 0 : 1 mode X 86 Bit 1 : 0 acquitté par le programme d’IT Bit 2 : 0 mode normal X 86 Bit 3 : 0 mode normal X 86 Bit 4 : 0 mode normal X 86 Bit 5 : 0 Bit 6 : 0 Bit 7 : 0 jc/md/lp-01/05 OAL x 86 62
Accès aux registres Après la séquence d’initialisation • Écriture de l’Interrupt Mask Register par une commande OCW 1 • Lecture de l’Interrupt Request Register ou de l’In -Service Register en deux temps : écriture d’un OCW 3 (bit 0 à 0 pour l’IRR et à 1 pour l’ISR) ; cette écriture positionne le boîtier pour que la lecture suivante fournisse le contenu de l’IRR ou de l’ISR sur le bus de données jc/md/lp-01/05 OAL x 86 63
Operation Command Words • Les commandes OCW sont envoyées individuellement sans ordre à respecter et à tout moment • OCW 1 est défini par A 0=1 • OCW 2 et OCW 3 sont définis par A 0=0 et D 4=0 • La différence entre OCW 2 et OCW 3 est faite par le bit D 3 de la commande : D 3=0 pour un OCW 2 et D 3=1 pour un OCW 3 jc/md/lp-01/05 OAL x 86 64
OCW 1 • Écriture de l’Interrupt Mask Register (IMR) • Défini par A 0=1 • Les bits D 0 à D 7 de l’OCW 1 sont écrits dans l’IMR • Chaque bit correspond à un niveau d’IT • Le registre est un masque : – Un bit à 1 inhibe le niveau d’interruption – Un bit à 0 autorise le niveau d’interruption jc/md/lp-01/05 OAL x 86 65
OCW 2 (1) • • Bit 0 : codage du niveau d’IR concerné Bit 1 : codage du niveau d’IR concerné Bit 2 : codage du niveau d’IR concerné Bit 3 : 0 Bit 4 : 0 Bit 5 : les bits 5, 6 et 7 permettent de gérer Bit 6 : des modes différents de traitement de Bit 7 : l’interruption jc/md/lp-01/05 OAL x 86 66
OCW 2 (2) • Quand le PIC est programmé pour fonctionner avec un acquittement spécifique de l’interruption (dans ICW 4, Bit D 1=1), on peut disposer de plusieurs commandes pour gérer finement l’acquittement des interruptions • On peut notamment introduire une gestion circulaire des priorités par les commandes envoyées par le logiciel qui traite l’interruption ; ces commandes concernent le niveau indiqué par les bits 0, 1 et 2 du mot OCW 2 jc/md/lp-01/05 OAL x 86 67
OCW 3 • • Bit 0 : avec Bit 1, codage pour lire IRR (10) ou Bit 1 : ISR (11) sur la prochaine lecture du PIC Bit 2 : 0 fonctionnement normal Bit 3 : 1 (OCW 3) Bit 4 : 0 (OCW) Bit 5 : 0 fonctionnement normal Bit 6 : 0 fonctionnement normal Bit 7 : 0 jc/md/lp-01/05 OAL x 86 68
Mapping des PICs • PIC maître adresse 0 x 20 – Le fil A 0 du bus d’adresse étant connecté sur l’entrée A 0 du PIC, un échange à l’adresse 20 correspond à la sélection du PIC avec une entrée A 0 à 0, alors qu’un échange à l’adresse 21 correspond à une sélection du PIC avec une entrée A 0 à 1 • PIC esclave adresse 0 x. A 0 – De même, les deux adresses seront 0 x. A 0 et 0 x. A 1 jc/md/lp-01/05 OAL x 86 69
Programmation des PICs • Séquence d’initialisation en assembleur pour suivre au mieux toutes les commandes ICWs. On a successivement 4 ICWs pour le PIC maître et 3 ICWs pour le PIC esclave et deux OCWs • Nous programmons les modes les plus simples • Ultérieurement, nous rencontrerons la séquence de traitement des interruptions qui fera intervenir d’autres OCWs jc/md/lp-01/05 OAL x 86 70
Initialisation des PICs (1) void Init. PICs(void) { int i; __asm { ; First, do PIC 1 master mov al, 011 h ; Init command 1, ICW 1: cascade, 4 ICW out 020 h, al ; 020 h, address PIC 1, A 0=0 jmp short $+2 mov al, 040 h ; Init command 2, ICW 2: vector to 64 out 021 h, al ; 021 h, address PIC 1, A 0=1 jmp short $+2 jc/md/lp-01/05 OAL x 86 71
Initialisation des PICs (2) mov al, 004 h ; Init command 3, ICW 3: slave on IRQ 2 out 021 h, al jmp short $+2 mov al, 001 h ; Init command 4, ICW 4: normal EOI out 021 h, al jmp short $+2 mov al, 00 Bh ; OCW 3: Select In Service Register out 020 h, al mov al, 0 FFh ; OCW 1: Start with all interrupts disabled out 021 h, al jc/md/lp-01/05 OAL x 86 72
Initialisation des PICs (3) ; Now do PIC 2 slave on IRQ 2 of PIC 1 mov al, 011 h ; Init command 1, ICW 1: cascade, 4 ICW out 0 A 0 h, al ; 0 A 0 h, address PIC 2, A 0=0 jmp short $+2 mov al, 048 h ; Init command 2, ICW 2: vector to 72 out 0 A 1 h, al ; 0 A 1 h, address PIC 2, A 0=1 jmp short $+2 mov al, 002 h ; Init command 3, ICW 3: slave on IRQ 2 out 0 A 1 h, al jmp short $+2 jc/md/lp-01/05 OAL x 86 73
Initialisation des PICs (4) mov al, 001 h ; Init command 4, ICW 4: normal EOI out 0 A 1 h, al mov al, 00 Bh ; OCW 3: Select In Service Register out 0 A 0 h, al mov al, 0 FFh ; OCW 1: Start with all interrupts disabled out 0 A 1 h, al ; end of initialization jc/md/lp-01/05 OAL x 86 74
Initialisation des PICs (5) ; Clear any interrupts that might be pending after a warm ; reboot mov al, 020 h ; OCW 2: non specific End Of Interruption out 020 h, al ; PIC 1 mov al, 020 h ; OCW 2: non specific End Of Interruption out 0 A 0 h, al ; PIC 2 } jc/md/lp-01/05 OAL x 86 75
Récupération de l’IT par CE • A chaque vecteur d’interruption est associé par la fonction Hook. Interrupt un même programme de traitement d’interruption (Pe. RPISR) qui fournit au système le numéro logique associé à l’interruption physique en cours de traitement • Le système interroge alors sur ce niveau les éventuels programmes chaînés • Si ce programme n’est pas concerné par cette interruption, il rend le contrôle au système jc/md/lp-01/05 OAL x 86 76
Conclusion Nous avons : • Présenté quelques unes des fonctions utilisées pour démarrer la plate-forme • Étudié le principe du traitement des interruptions dans Windows CE • Préparé l’utilisation de ce mécanisme à travers l’exemple d’une liaison série en nous limitant à la récupération de l’interruption par le système jc/md/lp-01/05 OAL x 86 77