Aller au contenu

Chaîne d’outils

Les chaînes d’outils sont toujours dépendantes des cibles (microcontrôleurs) sur lesquelles les applications doivent être développées. Vous trouverez souvent des produits commerciaux, mais il est toujours très intéressant de regarder du côté des logiciels libres.

Dans ce cours, nous avons travaillé avec la chaîne d’outils de développement de GNU (GNU toolchain), qui offre une large palette d’outils et supporte pratiquement tous les processeurs actuels.

Le développement logiciel pour des systèmes embarqués peut se réaliser généralement indifféremment sur des hôtes Windows ou Linux. Cependant, il est souvent plus efficace de travailler sur des hôtes Linux. Ces machines offrent un environnement plus adapté au développement logiciel croisé (cross-development) et simplifient le travail en simulation.

Note

Avec le WSL-2 de Windows 10, il est possible d’utiliser un environnement Linux sous Windows. Cela permet de travailler avec les outils Linux tout en restant sous Windows.

Quelques outils intéressants de la GNU-Toolchain

  • make : pour automatiser de la génération de logiciel
  • gcc : pour compiler du code C/C++
  • ar : pour créer des bibliothèques
  • as : pour assembler du code assembleur
  • ld : pour éditer les liens
  • gdb : pour débugger
  • objdump : pour lister des informations d’un fichier de code objet
  • strip : pour éliminer les symboles d’un fichier de code objet
  • gcov : pour effectuer des tests de couverture de code
  • gprof : pour profiler le logiciel

Compilation

compilation de l’application pour le debugging :

gcc -Wall -Wextra -g -c -O0 -std=gnu11 -o fibonacci.o fibonnaci.c

Options :

  • -Wall : enclenche tous les warning
  • -Wextra : enclenche des warning supplémentaires
  • -g : enclenche les options pour le debugging
  • -c : indique au compilateur de ne pas linker l’application
  • -O0 : force l’optimisation du code généré
  • -std=gnu11 : autorise l’utilisation des extensions de 2011
  • -o : spécifie le nom du fichier de sortie

Si tous les fichiers d’entête (header files) ne sont pas dans le même répertoire que le fichier à compiler :

  • -I dir : spécifie le répertoire où le compilateur trouvera les header files, par exemple :
    -I. -I.. -I /workspace/include
    

Édition de liens (linker)

Après la compilation de l’application, vous devez linker tous les fichiers afin d’obtenir le fichier exécutable :

gcc fibonacci.o -o fibonacci

Il est également possible de compiler et de linker l’application en une seule commande :

gcc -Wall -Wextra -g -O0 -std=gnu11 -o fibonacci fibonnaci.c

Options :

  • -o : spécifie le nom de l’exécutable

Attention

L’option -c ne doit être utilisée

Linker Script File

Pour compléter l’édition de lien, le linker a besoin de connaître l’emplacement des différentes mémoires du microprocesseur

Le Linker Script File décrit ces emplacements par leur taille et location

Il permet de regrouper les différentes sections composant un programme et de les placer dans la mémoire

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */

_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 256K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 1024K
}

/* Sections */
SECTIONS
{
  /* The program code and other data into "FLASH" Rom type memory */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
  } >FLASH

  /* Constant data into "FLASH" Rom type memory */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH

  /* Uninitialized data section into "RAM" Ram type memory */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM

  /* User_heap_stack section, to check that there is enough "RAM" memory left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM

}

Création de bibliothèques

Compiler les fichiers de la bibliothèque :

gcc -Wall -Wextra -g -c -O0 -std=gnu11 -o mymathlib.o mymathlib.c

Créer la bibliothèque :

ar cr libmymathlib.a mymathlib.o}

Options :

  • c : crée une bibliothèque nommée libmymathlib.a
  • r : insère le fichier mymathlib.o dans la bibliothèque

Générer l’application en utilisant la bibliothèque :

gcc -Wall -Wextra -g -O0 -std=gnu11 main.c -lmymathlib -L. -o exec

Options :

  • -llibrary : spécifie le nom de la bibliothèque à utiliser. Si le nom spécifié est library, le linker cherchera les fichiers avec le préfixe lib et l’extension .a ou .so : liblibrary.a et liblibrary.so.
  • -Ldir : spécifie le répertoire où le linker trouvera le fichier de la bibliothèque, par exemple :
    -L. -L.. -L /workspace/lib`