P2013
Final - MI52 1.
Questions (10pts)
Répondre brièvement
1. Pour pouvoir fonctionner un programme écrit dans un langage tel que le C nécessite une pile initialisée. Expliquer brièvement l'utilité d'une pile et ce pourquoi un programme C ne peut fonctionner sans pile
2. Expliquez ce que sont le “ bss ” et le “ heap ”
3. Pour les systèmes sans OS, les routines de traitement des interruptions sont déclarées avec l'attribut interrupt : __attribute__ ((interrupt)) lorsque l'on utilise gcc. Expliquez pourquoi cela est nécéssaire et ce que cela change pour la fonction.
4. Les processeurs disposent généralement de plusieurs modes de fonctionnement. Typiquement un mode utilisateur et un mode privilégié souvent appelé superviseur. Expliquez l'intérêt de disposer de plusieurs mode de fonctionnement.
5. Une interruption système est une interruption générée par un périphérique de type timer et qui se déclenche à intervalle de temps régulier (toutes les 10 ms par exemple). Quel est l'intérêt d'une telle interruption pour un système multitâche préemptif
6. Expliquez brièvement la différence entre une mémoire flash NOR et une mémoire flash NAND pour un utilisateur de ces mémoires.
7. Quel est l'intérêt de définir certaines zones mémoire comme non “ cachable ” et/ou non “ bufferable ”
8. Expliquer brièvement pourquoi l'adressage virtuelle permet aux processus d'avoir leur espace mémoire mutuellement protégés.
9. Lors de la commutation d'un processus (changement du processus en exécution) pourquoi est-il nécessaire d'invalider le TLB et les caches de premiers niveau s'ils travaillent avec des adresses virtuelles ?
10. Lors de l'exécution d'une routine de traitement des interruptions sur une système d'exploitation de type linux ou windows, pourquoi n'est-t-il pas possible de copier des données depuis/vers un buffer d'une application à partir de son adresse virtuelle ?
2.
Exercice réception de donnée (10pts)
Il s'agit dans ce TP d'écrire le logiciel de récupération des données pour une interface matériel qui reçois des données issues d'un périphérique distant.
Description Interface
registres de l'interface et adresse
Adresse nom description
0xB0000000 data registre de donnée (32 bits RO) 0xB0000004 state registre d'état (32 bits RO)
0xB0000008 ctrl registre de contrôle de la liaison (32 bits RW)
Lorsqu'une donnée est reçue par l'interface, elle est placée dans le registre data et le bit 0 du registre state passe à 1. Ce bit reste à 1 tant qu'une donnée non lue est présente dans le registre data. A l'initialisation ou après un reset de l'interface ce bit 0 du registre state est à 0.
le bit 2 du registre ctrl est le bit de contrôle des requêtes d'interruption. Lorsqu'il est à 1, les IRQ sont actives et une IRQ est générée selon l'état des bits 0 et 1 du registre state : une requête d'interruption est générée si le bit 0 du registre state est à 1 (donnée présente) ou si le bit 1 du registre state est à 1 (time-out). Les requête d'interruptions sont de type niveau (ligne active en permanence tant que l'interface n'est pas acquitée).
L'interface est munie d'un time-out automatique. Si après l'arrivée d'un donnée, aucune autre donnée n'est reçue après un certain temps, le bit 1 du registre state passe à 1, si les interruptions sont activée alors une requête d'interruption est générée.
La lecture du registre state remet ce bit à 0 et désactive la requête d'interruption.
Description du logiciel
L'application est une application multitâche basée sur FreeRTOS.
Le point d'accès pour demander des données reçue sur l'interface est une fonction que l'on appellera read et qui prend en paramètre une adresse (buf :adresse buffer utilisateur) et un entier count correspondant au nombre de données en octets demandé. Cette fonction est non bufferisée et synchrone : les données sont récupérées directement de l'interface (et non d'un buffer temporaire) et la fonction se bloque jusqu'à ce que les count données soient reçues ou jusqu'à ce qu'un time-out soit
1/2 Nicolas Lacaille
P2013 généré par l'interface. La fonction renvoie le nombre de données effectivement reçues et placées dans le buffer utilisateur (=
count ou le nombre de données reçues avant le time-out).
Les attentes doivent se faire de manière passive avec un sémaphore binaire dont les primitives sont données ci-après.
Primitives FreeRTOS
xSemaphoreHandle xSemaphore; /* déclaration d'un sémaphore binaire */
void vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore ); /* initialisation du sémaphore, sémaphore signalé */
portBASE_TYPE xSemaphoreTake( xSemaphoreHandle xSemaphore , ( portTickType ) xTicksToWait )) ;
portBASE_TYPE xSemaphoreGive( xSemaphoreHandle xSemaphore, portBASE_TYPE *pxHigherPriorityTaskWoken);
portBASE_TYPE xSemaphoreGiveFromISR( xSemaphoreHandle xSemaphore,
portBASE_TYPE *pxHigherPriorityTaskWoken);
portBASE_TYPE est du type int pour la plate-forme.
Initialisation et contexte
On considère qu'à l'initialisation le sémaphore binaire a été créé (variable globale nommée xSemaphore) et initialisé à l'état non signalé (=0). On ne considérera pas les accès concurrents à la routine read. On ne s'occupe pas de relancer le sheduler après une interruption (plus précisément, on ne s'occupe pas du paramètre pxHigherPriorityTaskWoken de la fonction xSemaphoreGiveFromISR). La routine de traitement des interruptions est appelée vISRHandler, elle est appelée par la routine vISREntry qui est celle appelé par le système lorsque l'interface génère une requête d'interruption.
static void vSREntry( void ) __attribute__ ((naked)) {
portSAVE_CONTEXT(); // sauvegarde contexte tâche vISRHandler();
portRESTORE_CONTEXT(); //restauration contexte tâche }
Travail demandé
Il vous reste 2 fonctions à écrire :
• int read (int * buf, int count) ;
• void vISRHandler(void);
Expliquer le principe de fonctionnement de votre pilote et donnez le code C des deux fonctions précédentes.
2/2 Nicolas Lacaille