Difference between revisions of "Proj-2011-2012-qemu"

From air
Jump to navigation Jump to search
Line 34: Line 34:
 
MemoryRegion *address_space_mem = get_system_memory();
 
MemoryRegion *address_space_mem = get_system_memory();
 
pic = armv7m_init(address_space_mem, flash_size, sram_size, kernel_filename, cpu_model);
 
pic = armv7m_init(address_space_mem, flash_size, sram_size, kernel_filename, cpu_model);
où pic est un tableau de qemu_irq (voir [[Qemu#Assemblage]]) correspondant aux fils d'entrer dans le processeur.
+
où pic est un tableau de qemu_irq (voir [[Qemu#Assemblage]]) correspondant aux fils d'entrée dans le processeur.
Dans notre cas les taille des différentes mémoires sont :
+
Dans notre cas les tailles des différentes mémoires sont :
 
*RAM: 16 KBits
 
*RAM: 16 KBits
 
*Flash: 128 Kbits
 
*Flash: 128 Kbits

Revision as of 15:33, 25 April 2012

Émulation de la carte STM32L-Discovery avec Qemu

schéma 1 : Interface entre Qemu et l'UI‎

Enseignant:

  • Olivier Richard

Etudiants:

  • CLAVELIN Aurélien
  • EID Timothée
  • MERCIER Michael

Le but de ce projet est de d'ajouter le support de la carte STM32L-Discovery dans le logiciel de virtualisation Qemu. Il fait suite au projet de l'année dernière (fiche projet) basé lui aussi sur Qemu mais portant sur la carte Stellaris Luminary Lm3s6965.

Qemu

Voir Qemu

Fichiers

Téléchargement

Lien vers le projet à venir...

Description

Afin d'émuler la carte STM32L-Discovery les fichiers suivant ont été ajoutés au dossier src/hw de Qemu :

  • stm32.c pour décrire la carte dans son ensemble
  • stm32_gpio.c pour les GPIOs
  • stm32_button.c pour les boutons
  • stm32_led.c pour les LEDs
  • stm32_rcc.c pour le module RCC (ce module n'est que très partiellement émulé et donc non fonctionnel)

Composants émulés

Processeur et Mémoire

Le processeur utilisé par la carte est un processeur Cortex-M3 r1p1 (doc) déjà supporté par Qemu.

Pour initialiser celui-ci, il est nécessaire d'utiliser la fonction

MemoryRegion *address_space_mem = get_system_memory();
pic = armv7m_init(address_space_mem, flash_size, sram_size, kernel_filename, cpu_model);

où pic est un tableau de qemu_irq (voir Qemu#Assemblage) correspondant aux fils d'entrée dans le processeur. Dans notre cas les tailles des différentes mémoires sont :

  • RAM: 16 KBits
  • Flash: 128 Kbits

GPIO

L'émulation des GPIO est gérée par le fichier stm32_gpio.c. Les GPIO sont les connecteur de base de la carte. Il permet de communiquer avec le bouton USER 0 et les LEDs.

Périphériques

L'émulation ne porte pour l'instant que sur les deux LEDs (stm32_led.c) et le bouton USER0 (stm32_button.c) qui communique avec l'extérieur de Qemu grâçe à chardev .

Exemple

Nous allons détaillé la composition d'un composant à partir de l'exemple de stm32_gpio

  • Tout d'abord il faut inclure sysbus
#include "sysbus.h"
  • Les registres utilisé par le composant sont ensuite placés dans une structure :
typedef struct {
   SysBusDevice busdev;

   /* Registres GPIO (Reference Manual p119 */
   uint32_t mode; /* Mode */
   uint16_t otype; /* Output type */
   uint32_t ospeed; /* Output speed */
   uint32_t pupd; /* Pull-up/Pull-down */
   uint16_t ind; /* Input data */
   uint16_t outd; /* Output data register */
   uint16_t outd_old; /* Output data register */
   uint32_t bsr; /* Bit set/reset */
   uint32_t lck; /* Lock */
   uint32_t afrl; /* Alternate function low */
   uint32_t afrh; /* Alternate function high */
   
   qemu_irq irq_out[NB_PIN];
   unsigned char id;
} stm32_gpio_state;
  • Cette structure est décrite sous la forme d'une VMStateDescription permettant à Qemu de l'enregistré correctement
static const VMStateDescription vmstate_stm32_gpio = {
   .name = "stm32_gpio",
   .version_id = 1,
   .minimum_version_id = 1,
   .fields = (VMStateField[])
   {
       VMSTATE_UINT32(mode, stm32_gpio_state),
       VMSTATE_UINT16(otype, stm32_gpio_state),
       VMSTATE_UINT32(ospeed, stm32_gpio_state),
       VMSTATE_UINT32(pupd, stm32_gpio_state),
       VMSTATE_UINT16(ind, stm32_gpio_state),
       VMSTATE_UINT16(outd, stm32_gpio_state),
       VMSTATE_UINT16(outd_old, stm32_gpio_state),
       VMSTATE_UINT32(bsr, stm32_gpio_state),
       VMSTATE_UINT32(lck, stm32_gpio_state),
       VMSTATE_UINT32(afrl, stm32_gpio_state),
       VMSTATE_UINT32(afrh, stm32_gpio_state),
       VMSTATE_END_OF_LIST()
   }
};
  • Une structure SysBusDeviceInfo renseigne la fonction d'initialisation, le nom, la taille de la structure des registres ainsi que la VMStateDescription.
static SysBusDeviceInfo stm32_gpioA_info = {
   .init = stm32_gpio_init_A,
   .qdev.name = "stm32_gpio_A",
   .qdev.size = sizeof (stm32_gpio_state),
   .qdev.vmsd = &vmstate_stm32_gpio,
};
  • Elle est passée en paramètre à la fonction sysbus_register_withprop elle même passée en paramètre de la macro device_init
static void stm32_gpio_register_devices(void) {
   sysbus_register_withprop(&stm32_gpioA_info);
}
device_init(stm32_gpio_register_devices)
  • Voici la fonction d'initialisation du composant :
static int stm32_gpio_init(SysBusDevice *dev, const unsigned char id) {
   int iomemtype;
   stm32_gpio_state *s = FROM_SYSBUS(stm32_gpio_state, dev);
   s->id = id;
   
   //Initialisation de la plage mémoire
   iomemtype = cpu_register_io_memory(stm32_gpio_readfn, stm32_gpio_writefn, s, DEVICE_NATIVE_ENDIAN);
   sysbus_init_mmio(dev, 0x24, iomemtype);

   //Initialisation des pins
   qdev_init_gpio_in(&dev->qdev, stm32_gpio_in_recv, NB_PIN);
   qdev_init_gpio_out(&dev->qdev, s->irq_out, NB_PIN);

   //Initialisation
   stm32_gpio_reset(s);
   vmstate_register(&dev->qdev, -1, &vmstate_stm32_gpio, s);

   return 0;
}

les structures stm32_gpio_readfn et stm32_gpio_writefn sont respectivement une CPUReadMemoryFunc et une CPUWriteMemoryFunc et contiennent les fonctions de lecture et d'écriture sur les registres déclarés dans le stm32_gpio_state. Ces fonction sont de la forme :

static uint32_t stm32_gpio_read(void *opaque, target_phys_addr_t offset) {
   stm32_gpio_state *s = (stm32_gpio_state *) opaque;

   switch (offset) {
       case 0x00: /* Mode */
           return s->mode;
       case 0x04: /* oType */
           return s->otype;
       case 0x08: /* oSpeed */
           return s->ospeed;
       ...

Le fichier stm32_gpio.c complet est disponible File:Stm32 gpio.txt

Interface graphique

Une interface graphique utilisateur (UI) à été développer afin de permettre à l'utilisateur une meilleur prise en main. Qemu se connecte à l'UI par des sockets fournis par les modules des deux LED et du bouton via chardev.Le schéma 1 résume ce fonctionnement.


QemuAndUI.png

L'UI à été développer en Python2.7 avec la bibliothèque tkinter.

Glossaire des acronymes

Vous trouverez le glossaire ici