Pour réaliser un RTOS, j'ai besoin au minimum d'une interruption d'horloge. Donc après un certain laps de temps, une interruption survient et un handler de timer se déclenche. Un controleur d'interruptions est intégré dans le processeur MC68328 (et MC68EZ328). La compréhension du fonctionnement de ce controlleur est indispensable pour impltementer un handler de timer. Je vais donc essayer de décrire son fonctionnement pour le processeur MC68328 qui est simulé par xcopilot. Normalement, avec quelques petites modifications, le mécanisme pourra etre repris pour le MC68EZ328 et donc le palm Vx.
Description du controleur
Le controlleur d'interruption supporte différentes interruptions de source interne ou externe. Ce bloc gère les priorités, encode l'interruption en attente et génere un numéro du vecteur d'interruption pendant le cycle d'aquitement d'une interruption. (Fig 6.1)
Le controlleur suporte 23 interruptions sensibles aux flancs ou aux niveaux. Il y a 7 niveaux d'interruption. Le niveau 7 à la plus hautes priorité et le niveau 1 la plus basses. Les interruptions peuvent provenir des sources suivantes : (voir p 6-1)
Le controlleur génére une vecteur programmable pour chaque niveau d'interruption (voir liste ci-dessous). Ces vecteurs d'interruptions font allusions aux auto-vecteurs d'interruptions ou aux vecteurs d'interruption utilisateurs dans la table des vecteurs d'exception des compatibles 68EC000
Vecteurs d'exception
Un nombre (élément) du vecteur est un nombre de 8 bit qui peut être multiplier par 4 pour obtenir l'adresse d'un vecteur d'exception. Un vecteur d'exception est une localisation en mémoire a partir de laquelle le processeur prend l'adresse d'une routine software utilisée pour gérer l'exception (handler). Chaque exception possède un numéro du vecteur, comme décrit dans la table 6.1. Les interruptions utilisateurs font partie du traitement des exceptions dans le DragonBall et les numéros du vecteur pour les interruptions utilisateurs sont configurable.
Le DragonBall ne fournit pas d'auto-vecteur d'interruptions. Au démarage du système, vous devez programmer le vecteur d'interruption utilisateur pour que le processeur puissent gérer les interruption correctement.
Reset
L'exception reset corresponds au niveau d'exception le plus haut. Une exception reste est traitée pour l'initialisation du sytème et lors d'une pane catastrophique. Tout traitement en cours lors d'un reset est abandonné et ne peut plus être récupérer. Ni le compteur de programme (PC), ni le registre de status (SR) ne sont sauvé. Le processeur est forcé dans l'état superviseur. Le masque de priorité d'interruption est mis à 7. L'adresse dans les 2 premiers mots du vecteur d'exception du reset est utilisée par le processeur comme SSP (Supervisor stack pointer) initial et l'adresse dans les 2 mots suivant du vecteur d'exception du reset est utilisée comme PC initial.
Au démarrage ou lors d'un reset, le chip-select par défaut (CSA0) est séléctionné et toute les autres chip-select non désélectionné. Vous devez utiliser CSA0 pour décoder un espace mémoire EPROM/ROM. Dans ce cas, les deux premiers long mot de lamémoire EPROM/ROM doivent etre programmé pour contenir les SSP et PC initiaux. Le SSP initial doit pointer vers un espace RAM et le PC initial doit pointer vers le code de démarrage dans l'espace EPROM/ROM pour que le processeur puisse exécuter le code de démarrage pour démarrer le système.
Controlleur d'interruption
Quand les interruptions sont recues par le controlleur, elles sont prioritisées et l'interruption autorisée de plus haut niveau en attente est trasmise au coeur du processeur. Avant que le CPU ne réponde à cette interruption, le registre de status est copié en interne. Puis le bit S du registre de status est mis à 1 ce qui place le processeur dans le mode superviseur. Ensuite, le CPU répond avec une cycle d'accusé de reception, dans lequel les 3 bits de poids faibles du bus d'adresse reflete le niveau de l'interruption courante. Le controlleur d'interruption genere un nombre du vecteur pendant le cycle d'accusé de reception et le CPU utilise ce nombre pour générer une adresse de vecteur. Excepter pour l'exception reset, le CPU sauves le status courant du processeur, dont la valeur du PC (qui pointent vers la prochaine instruction à être exécutée après l'interruption), et la copie sauvée du registre de statut. Le nouveau PC est mis à jour avec le contenu du vecteur d'interruption, qui pointent vers la routine d'interruption. Ensuite, le CPU reprend l'exécution en exécutant la routine du service d'interruption.
La priorité des interruptions est basée sur le niveau d'interruption. Si le CPU est en train de traiter une routine de service d'interruption et qu'une interruption de priorité supérieur est recue, le processus décrit ci-dessus est repris et l'interruption de priorité supérieur est traitée. Si la priorité de la nouvelle interruption est inférieur ou égale à l'interruption courrante, l'exécution du handler de l'interruption courante continue. Cette nouvelle interruption est postposée jusqu'à ce que sa priorité deviennent la plus élevée. Les interruptions dans même niveau doivent être prioritisée en software par le handler d'interruption. La routine du service d'interruption doit se terminer par l'instruction RTE, qui restore l'état du processeur avant l'interruption.
Le DragonBall fournit un vecteur d'interuption pour
chacune des 7 niveaux d'interruptions utilisateurs. Ces vecteurs d'interruption
forme la section vecteur d'interruption utilisateur de la table 6.1. Les
vecteurs d'interruptions utilisateurs peuvent etre situé n'importe
ou dans l'intervale d'adresse 0x100 à 0x400. Vous pouvez programmer
les 5 bits de poids fort du nombre du vecteur d'interruption, mais les
3 bits de points faibles refletent le niveau d'interruption en cours. Toutes
les interruptions sont masquable par le controlleur d'interruption. Si
une interruption est masquée, son status est toujours accessible
par le registre d'interruption en attente (IPR)
Génération du vecteur
Le controlleur d'interruption fournit un nombre de vecteur au coeur du processeur. Vous pouvez programmer les 5 bits de poids fort du registre de vecteur d'interruption (IVR) pour autorisé le nombre du vecteur d'interruption de pointer vers n'importe qu'elle adresse dans la table des vecteur d'exception. Cependant, beaucoup des adresses de vecteur sont assignée aux exception interne du coeur et ne peuvent etre réutilisée. Cela laissent seulement un petit intervalle d'espace d'adresse (de 0x100 à 0x400) ou vous pouvez configurer le IVR pour localiser les vecteurs d'interruptions utilisateurs. Par exemple, si vous écriver une valeur de 0x40 dans le IVR, la base du vecteur d'interruption pointe vers 0x100 (0x40 <<2), qui est le debug des vecteurs d'interruption utilisateur. Le codage pour les nombres de vecteurs sont fourniée dans la table 6.2
Modèle de programmation
IVR : Interrupt Vector Register
ICR : Interrupt Control Register
IMR : Interrupt Mask Register
IWR : Interrupt Wake-Up Enable Register
ISR : Interrupt Status Register
IPR : Interrupt Pending Register