Activité n°3 : Programmation du kit Atmel SAM9G10

Après avoir effectué quelques tests des versions démos (WinCE et Linux Ångström) fournies avec le kit, on désire conserver seulement la version Linux. Celle-ci doit démarrer automatiquement à la mise sous tension.

Pour réaliser cela, on va reprogrammer le kit.

Préparation

On a besoin :

Atmel fournit :

On relie l’adaptateur USB/RS232 sur le port série SERIAL DEBUG PORT et on lance picocom :

$ picocom -b 115200 /dev/ttyUSB0

Remarque : on sort de picocom en utilisant la combinaison de touches Ctrl-A puis Ctrl-X.

Pour accéder à l’interface de programmation, il faut désactiver le démarrage (boot) à partir de la NAND Flash. Pour cela, il faut retirer le cavalier en J24 :

On alimente le kit SAM9G10 ou on fait un RESET. On observe sur la console SERIAL DEBUG PORT :

RomBOOT
>

Ensuite, on peut relier un câble USB A/B sur le connecteur USB DEVICE.

Remarque : Le bus USB ne permet pas de relier entre eux deux périphériques ou deux hôtes : le seul schéma de connexion autorisé est un périphérique sur un hôte. Pour éviter des branchements incorrects, la norme spécifie deux types de connecteurs : le type A, destiné à être situé sur l’hôte, et le type B, destiné à être situé sur le périphérique. Une mise à jour de la norme USB 2 introduit une version miniature du connecteur B : le mini-B. Elle est fonctionnellement équivalente au connecteur B, mais de dimensions nettement réduites.

On vérifie la détection du périphérique de programmation :

$ dmesg
...
[29346.976166] usb 1-1.2.7: new full-speed USB device number 21 using ehci-pci
[29347.068794] usb 1-1.2.7: New USB device found, idVendor=03eb, idProduct=6124
[29347.068799] usb 1-1.2.7: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[29347.069192] cdc_acm 1-1.2.7:1.0: This device cannot do calls on its own. It is not a modem.
[29347.069213] cdc_acm 1-1.2.7:1.0: ttyACM0: USB ACM device

$ lsusb
...
Bus 001 Device 021: ID 03eb:6124 Atmel Corp. at91sam SAMBA bootloader

$ ls -l /dev/ttyACM0
crw-rw---- 1 root dialout 166, 0 oct.   7 16:34 /dev/ttyACM0

Attention : le périphérique /dev/ttyACM0 ne sera accessible en lecture/écriture que par l’utilisateur propriétaire root et les membres du groupe dialout. Tous les autres (other) utilisateurs auront aucun accès. Pour modifier cette situation, vous pouvez soit changer les droits manuellement ($ sudo chmod 666 /dev/ttyACM0) soit ajouter l’utilisateur (ici toto) dans le groupe dialout ($ sudo adduser toto dialout).

La NAND Flash

Le kit SAM9G10 dispose :

La mémoire ROM interne (32 KOctets) contient un programme d’amorçage (bootstrap) permettant de lancer un démarrage (boot) sur au choix : la NAND Flash, la SDCard ou la DataFlash.

Remarque :

La mémoire flash est une mémoire de masse à semi-conducteurs ré-inscriptible, c’est-à-dire une mémoire possédant les caractéristiques d’une mémoire vive mais dont les données ne disparaissent pas lors d’une mise hors tension. Ainsi, la mémoire flash stocke les bits de données dans des cellules de mémoire, mais les données sont conservées en mémoire lorsque l’alimentation électrique est coupée. La technique flash se décline sous deux principales formes : flash NOR et NAND, selon le type de porte logique utilisée pour chaque cellule de stockage. Sa durée de vie est limitée par le nombre de cycles d’écriture (ici 100,000 PROGRAM/ERASE cycles).

La NAND flash est plus rapide à l’effacement et à l’écriture, offre une plus grande densité et un coût moins important par bit qu’une flash NOR. Du fait de son prix moins élevé, elle est présente dans de nombreux systèmes embarqués (assistants et téléphones portables) en utilisant par blocs la mémoire RAM en mode page comme support d’exécution. Elle est donc utilisée pour le stockage d’informations. Quasiment toutes les mémoires de masse externes (carte MMC, carte SD et carte MS) utilisent cette technologie.

On va s’intéresser à l’accès à la NAND Flash pour y installer un système à exécuter au démarrage. Atmel fournit le logiciel SAM-BA pour contrôler les mémoires internes du kit (SRAM, DDRAM, NAND Flash, DATA Flash).

La carte mémoire de la NAND Flash pour la version de démonstration installée est la suivante :

Les fichiers chargés dans cette mémoire sont :

$ cd $HOME/XXXX-XXXX/Demo/

$ ls -l
-rw------- 1 tv tv  31M oct.  29  2009 Angstrom-x11-sam9g10ek2-image-glibc-ipk-2009.X-stable-at91sam9g10ek2.rootfs.jffs2
-rw------- 1 tv tv 102K oct.  29  2009 AT91Launcher-at91sam9g10-ek2-sdram.bin
-rw------- 1 tv tv  31K oct.  29  2009 at91sam9g10ek2_defconfig
-rw------- 1 tv tv 1,6K juil.  6  2010 demo-at91sam9g10ek2.bat
-rw------- 1 tv tv 2,1K août  13  2010 demo-at91sam9g10ek2.tcl
-rw------- 1 tv tv 1,5M oct.  29  2009 linux-2.6.27-at91-exp.2-at91sam9g10ek2.bin
-rw------- 1 tv tv 4,6K juil.  7  2009 nandflash_at91sam9g10ek2.bin
-rw------- 1 tv tv 1,5M oct.  29  2009 Sam9g10-ek2-Sam9Launcher480272.bin
-rw------- 1 tv tv  32M oct.  29  2009 WinCE-6.0-at91sam9g10ek2.nb0
  1. Le fichier Sam9g10-ek2-Sam9Launcher480272.bin fait une taille 1,5M. Il est chargé à l’adresse 0x100000. Vérifier qu’il n’écrase pas le système de fichiers jffs2 qui est chargé lui à l’adresse 0x400000.

    Espace = 0x400000 - 0x100000 = 0x300000 soit 3 MO ce qui est suffisant pour y stocker un fichier de 1.5 MO

  2. Comparer les tailles des deux systèmes WinCE et Linux.

    WinCE = 32M Linux = 1,5M + 31M = 32,5 M

  3. Combien reste-t-il de place de libre dans la NAND Flash ?

    0x4600000 -> 70 MO + 32M pour WinCE = 102 MO Il reste donc : 256 MO - 102 MO = 154 MO

  4. Est-ce suffisant pour y placer le disque flash ?

    Oui la partition de la FAT fait 123 MO ce qui est inférieur à l’espace restant libre (154 MO).

SAM-BA

Le logiciel SAM-BA d’Atmel fournit un ensemble d’outils pour la programmation de microcontrôleurs ARM (SAMA5, SAM3, SAM4, SAM7 et SAM9).

$ sudo apt-get install tcl8.4 tclx8.4 tk8.4

$ cd /opt/

$ unzip sam-ba_2.15.zip 

$ rm -f sam-ba_2.15.zip

$ ls
sam-ba_cdc_linux  

$ ls sam-ba_cdc_linux 
applets  doc  sam-ba  sam-ba_64  tcl_lib  usr

// Manuellement
$ export PATH=$PATH:/opt/sam-ba_cdc_linux

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:$HOME/bin:/opt/sam-ba_cdc_linux

// Automatiquement
$ vim ~/.bashrc
export PATH=$PATH:/opt/sam-ba_cdc_linux

$ source $HOME/.bashrc

On utilisera SAM-BA pour flasher un nouveau système sur le kit Atmel. Pour cela, il faut relier le kit (le périphérique) au PC (l’hôte) en utilisant le bus USB.

$ sam-ba_64

Grâce à SAM-BA, il sera donc possible d’accéder en lecture/écriture à l’ensemble des espaces mémoires intégrés au kit (DDRAM, NAND, …). Quelque soit le kit utilisé, il est primordial de connaître le placement des cavaliers ou micro switch à configurer pour activer ou désactiver les accès.

la GUI de SAM-BA offre des fonctionnalités très complètes mais il sera plus intéressant de travailler avec des scripts pour automatiser le processus de flashage. Ici, on utilisera le langage Tcl (Tool Command Language).

Remarque : Tcl est un langage de script initialement conçu en 1988 par John Ousterhout et son équipe à l’université de Californie à Berkeley. Il s’inspire principalement des langages C, Lisp, sh et awk. Ce langage à typage dynamique est multiplateformes, extensible, facile à apprendre et repose sur douze règles syntaxiques. Tcl s’interface très aisément avec le langage C, ce qui lui permet de servir par exemple d’interprète embarqué dans des applications.

  1. Qu’est-ce qu’un langage de script ?

    Un langage de script est un langage de programmation qui a besoin d’un interpréteur pour s’exécuter. Historiquement, ils ont été créés pour raccourcir le processus traditionnel de développement (édition-compilation-édition des liens-exécution) propre aux langages compilés. On parle parfois de langage de programmation dynamique car certains langages de scripts peuvent aussi être compilés (PHP, Perl, Python par exemple).

Le site www.at91.com fournit un ensemble de ressources et d’images binaires prêtes à l’emploi pour un grand nombre de kits Atmel :

Voir aussi : http://www.at91.com/linux4sam/

Principe

Comme on désire installer seulement la version Linux, on va modifier la carte mémoire de la NAND Flash comme ceci :

Attention : Avant de flasher un nouveau système, il faudra tout d’abord effacer l’ensemble de la mémoire NAND Flash.

Il va falloir donc flasher 5 zones dans la NAND Flash, tout d’abord les 3 fichiers suivants :

Remarque : L’environnement U-Boot est un bloc de mémoire qui sera copiée dans la RAM lorsque U-Boot démarre. Il est utilisé pour stocker des variables d’environnement pour configurer le système. Après un reset, U-Boot va attendre un nombre de secondes (variable bootdelay) avant d’exécuter le contenu de la variable bootcmd. Le contenu de la variable bootargs sera transmis au noyau Linux comme arguments de démarrage. La variable mtdparts permet de partager un schéma commun de partition MTD entre U-Boot et le noyau Linux. MTD (Memory Technology Device) est un type de fichier de périphérique de Linux pour interagir avec la mémoire flash. cf. UBootEnvVariables.

Exemple de variables d’environnement U-BOOT :

ethaddr=3a:1f:34:08:54:54
bootdelay=3
baudrate=115200
bootargs=mem=64M console=ttyS0,115200 
mtdparts=atmel_nand:4M(bootstrap/uboot/kernel)ro,60M(rootfs),-(data) root=/dev/mtdblock1 rw rootfstype=jffs2
bootcmd=nand read.jffs2 $kernelLoadAddr $kernelUbootAddr $kernelSize; bootm $kernelLoadAddr

Puis le système d’exploitation qui sera décomposé en 2 fichiers :

Remarque : Le noyau dispose d’un espace mémoire de 2 MOctets et le système de fichiers peut occuper l’espace restant (256 MO - 4MO = 252 MO).

  1. Est-ce que l’on conservera le disque interne flash ?

    Non car l’ensemble de la mémoire NAND Flash va être effacée. Il faut le sauvegarder avant tout opération d’effacement.

  2. Quelle sera la taille maximale pour le chargeur d’amorçage U-Boot ?

    Taille max U-Boot = 0x60000 - 0x20000 = 0x40000 soit 256 KO

  3. Quelle sera la taille maximale pour le noyau Linux ?

    Taille max kernel = 0x400000 - 0x200000 = 0x200000 soit 2 MO

  4. Quelle sera la taille maximale pour le système de fichiers ?

    Taille max rootfs = 0x400000 = 4 MO soit 256 MO - 4 MO = 252 MO

Programmation

Pré-requis :

La procédure est la suivante :

Installation de la distribution Ångström

On récupère une image prête à l’emploi sur le site www.at91.com :

$ wget -c ftp://www.at91.com/pub/demo/linux4sam_2.0/linux4sam-angstrom-at91sam9g10ek.zip

Remarque : Ångström est une distribution Linux pour système embarqué, qui succède au projet OpenZaurus. Contrairement à ce dernier, qui était dédié aux seules machines Zaurus, Ångström peut fonctionner sur un plus grand nombre de plates-formes et d’appareils. Cette distribution est le résultat de l’union de développeurs des projets OpenZaurus, OpenEmbedded et OpenSimpad.

On décompresse l’archive :

$ unzip linux4sam-angstrom-at91sam9g10ek.zip 
Archive:  linux4sam-angstrom-at91sam9g10ek.zip
  inflating: linux4sam-angstrom-at91sam9g10ek/Angstrom-x11-at91sam9-image-glibc-ipk-2009.X-stable-at91sam9g10ek.rootfs.jffs2  
  inflating: linux4sam-angstrom-at91sam9g10ek/at91sam9g10ek_demo_linux_dataflash.bat  
  inflating: linux4sam-angstrom-at91sam9g10ek/at91sam9g10ek_demo_linux_dataflash.tcl  
  inflating: linux4sam-angstrom-at91sam9g10ek/at91sam9g10ek_demo_linux_nandflash.bat  
  inflating: linux4sam-angstrom-at91sam9g10ek/at91sam9g10ek_demo_linux_nandflash.tcl  
  inflating: linux4sam-angstrom-at91sam9g10ek/dataflash_at91sam9g10ek.bin  
  inflating: linux4sam-angstrom-at91sam9g10ek/nandflash_at91sam9g10ek.bin  
  inflating: linux4sam-angstrom-at91sam9g10ek/u-boot-1.3.4-exp.4-at91sam9g10ek-dataflash_cs0.bin  
  inflating: linux4sam-angstrom-at91sam9g10ek/u-boot-1.3.4-exp.4-at91sam9g10ek-nandflash.bin  
  inflating: linux4sam-angstrom-at91sam9g10ek/uImage-2.6.30-r1-at91sam9g10ek.bin

Remarque : Image est le fichier binaire générique d’un noyau (kernel) Linux. Maintenant, on utilise plus souvent zImage, une version compressée auto-extractible.

  1. Qu’est-ce uImage ?

    Sur les systèmes embarqués, on utilise couramment uImage, un fichier qui inclut le noyau et U-Boot ainsi que les informations pour le chargement. uImage est créé avec l’outil mkimage.

L’archive fournit :

  1. Qu’est-ce JFFS2 ?

    JFFS2 (Journaling Flash File System version 2) est un système de fichiers journalisé utilisé sur les systèmes à mémoire flash. Il succède à JFFS, et ne sera finalement pas remplacé par JFFS3 mais par UBIFS. JFFS2 a été inclus dans le noyau Linux depuis la version 2.4.10. C’est donc le système de fichiers utilisé pour le système de fichiers racine (rootfs) de Linux.

On va remplacer le système Linux fourni dans cette archive par celui de la version démo :

$ cd linux4sam-angstrom-at91sam9g10ek/

$ rm -f Angstrom-x11-at91sam9-image-glibc-ipk-2009.X-stable-at91sam9g10ek.rootfs.jffs2  

$ rm -f uImage-2.6.30-r1-at91sam9g10ek.bin

$ cp $HOME/XXXX-XXXX/Demo/Angstrom-x11-sam9g10ek2-image-glibc-ipk-2009.X-stable-at91sam9g10ek2.rootfs.jffs2 .

$ cp $HOME/XXXX-XXXX/Demo/linux-2.6.27-at91-exp.2-at91sam9g10ek2.bin .

$ vi at91sam9g10ek_demo_linux_nandflash.tcl  
...
################################################################################
#  Main script
################################################################################
set bootstrapFile   "nandflash_at91sam9g10ek.bin"
set ubootFile       "u-boot-1.3.4-exp.4-at91sam9g10ek-nandflash.bin"    
set ubootEnvFile    "ubootEnvtFileNandFlash.bin"
set kernelFile      "linux-2.6.27-at91-exp.2-at91sam9g10ek2.bin"
set rootfsFile      "Angstrom-x11-sam9g10ek2-image-glibc-ipk-2009.X-stable-at91sam9g10ek2.rootfs.jffs2"

## NandFlash Mapping
set bootStrapAddr   0x00000000
set ubootAddr       0x00020000
set ubootEnvAddr    0x00060000
set kernelAddr      0x00200000
set rootfsAddr      0x00400000
...

On est prêt pour “flasher” le système Linux demandé :

$ sam-ba_64 /dev/ttyACM0 AT91SAM9G10-EK at91sam9g10ek_demo_linux_nandflash.tcl

À partir de la console DEBUG ou en ssh, vous pouvez vous connecter en root.

Quelques informations sur le système installé :

// L'OS
# uname -a
Linux at91sam9g10ek2 2.6.27 #1 Thu Oct 29 08:50:39 CET 2009 armv5tejl unknown

// Le CPU
# cat /proc/cpuinfo
Processor   : ARM926EJ-S rev 5 (v5l)
BogoMIPS    : 132.71
Features    : swp half thumb fastmult edsp java
...
Hardware    : Atmel AT91SAM9G10-EK

// La mémoire
# cat /proc/meminfo | grep Mem
MemTotal:        61856 kB
MemFree:         14152 kB

// Le système de fichiers
# df -h | grep root
/dev/root   60.0M     31.9M     28.1M  53% /
  1. La quantité de mémoire correspond-elle à la SDRAM ou à la NAND Flash ?

    La RAM (Random Access Memory) est la mémoire vive ou mémoire système dans laquelle le système place les données lors de leur traitement. Ici, c’est de la SDRAM (Synchronous Dynamic Random Access Memory) qui est un type particulier de mémoire vive ayant une interface de communication synchrone. Le kit possède 64 MO de SDRAM (cf. Micron Technology 256mb_sdr.pdf).

    La NAND flash est une mémoire de masse pour le stokage à long terme des informations sous forme de fichiers. Le kit dispose de 256 MO de NAND Flash (cf. Micron Technology MT29F2G(08,16)AAD,ABD.pdf).

Programmation C/C++

La distribution installée ici n’a pas déployé les paquets de développement.

La distribution Ångström utilise des paquets IPK. Le gestionnaire de paquet à utiliser est opkg.

  1. Qu’est-ce qu’un paquet (package) sous Linux ?

    Un paquet ou parfois paquetage (package) est une archive (souvent compressée) comprenant les fichiers, les informations et procédures nécessaires à l’installation d’un logiciel sur un système d’exploitation en s’assurant de la cohérence fonctionnelle du système ainsi modifié. L’utilisation d’un paquetage logiciel est un élément constitutif d’une bonne pratique d’intégration logicielle.

  2. Quels sont les types de paquets les plus répandus sous Linux ?

    deb est le format de fichier des paquets logiciels de la distribution Debian GNU/Linux. Presque toutes les distributions basées sur Debian utilisent aussi ce format (Ubuntu par exemple).

    rpm (Red Hat Package) est un système de gestion de paquets de logiciels utilisé sur certaines distributions GNU/Linux. C’est le format utilisé par Linux Standard Base (LSB).

    Pacman (contraction de package-manager) est le gestionnaire de paquets officiel de la distribution Linux Arch Linux. Pacman utilise des archives .tar.gz, .bz2 ou .xz pour ses paquets.

    Voir aussi : tgz (fichier archive créé avec tar et ensuite compressé généralement avec gzip), msi (pour les fichiers d’installation pour Windows Installer).

  3. Qu’est-ce que IPK ?

    IPKG (Itsy Package Management System) est un gestionnaire de paquets libre publié sous licence GPLv2. Il permet de gérer l’installation et la mise à jour des logiciels installés sur une distribution GNU/Linux. Il est utilisé dans certains systèmes embarqués. Le développement de ce projet a cessé. De nombreux projets qui utilisaient ipkg, ont adopté opkg comme remplaçant.

La configuration des mirroirs de dépôts est réalisée à partir des fichiers “.conf” dans /etc/opkg/. Il faut tout d’abord modifier les URLs :

[http://www.angstrom-distribution.org/feeds/2008/ipk/glibc/armv5te/)

en

http://feeds.angstrom-distribution.org/feeds/2011.03/ipk/glibc/armv5te/

On peut faire cela en une seule commande :

# sed -i 's#http://www.#http://feeds.#' /etc/opkg/*.conf

# sed -i 's#2008#2011.03#' /etc/opkg/*.conf
  1. Qu’est-ce que sed ? Que fait-il ici ?

    sed (Stream EDitor) est un programme informatique permettant d’appliquer différentes transformations prédéfinies à un flux séquentiel de données texte. sed est souvent décrit comme un éditeur de texte non-interactif.

  2. Que fait sed ici ?

    La commande s signifie substitute (« substituer ») qui indique que les occurrences dans chaque ligne doivent être remplacées. Après le premier caractère / est donnée une expression que sed doit trouver. Après le deuxième / est précisée l’expression remplaçant ce qu’il a trouvé. La commande de substitution (s///) est de loin la commande de sed la plus puissante et la plus fréquemment utilisée.

On met à jour le référencement des paquets, puis on installe les paquets de développement :

# opkg update
# opkg install gcc
# opkg install libgcc-dev
# opkg install binutils
# opkg install cpp
# opkg install g++
# opkg install libstdc++-dev
# opkg install libc6

On peut maintenant écrire notre premier programme C :

# vi hello.c
#include <stdio.h>

int main()
{
    printf("Hello Atmel!\n");
    return 0;
}

# arm-angstrom-linux-gnueabi-gcc -o hello hello.c

# ./hello 
Hello Atmel!

En réalité, un développeur ne programme pas directement sur sa cible (ici le kit Atmel) mais sur sa machine de développement. On a donc besoin d’une chaîne de compilation croisée (cross compliation).

  1. Qu’est-ce qu’une chaîne de compilation ? Qu’est-ce qu’une compilation croisée ?

    Une chaîne de compilation (toolchain) désigne l’ensemble des paquets utilisés dans le processus de compilation d’un programme, pour un processeur donné. Le compilateur n’est qu’un élément de cette chaîne, laquelle varie selon l’architecture matérielle cible. Une chaîne de compilation croisée est une chaîne compilée pour fonctionner sur l’architecture de processeurs de la machine hôte, mais qui va compiler des logiciels pour une architecture cible différente.

  2. Qu’est-ce qu’une compilation croisée ?

    La compilation croisée fait donc référence aux chaînes de compilation capables de traduire un code source en code objet dont l’architecture processeur diffère de celle où la compilation est effectuée. Ces chaînes sont principalement utilisés en informatique industrielle et dans les systèmes embarqués.

On va installer une chaîne de compilation croisée créée à partir de yocto/poky :

$ ./poky-atmel-glibc-x86_64-meta-toolchain-armv5e-toolchain-2.0.sh 

$ . /opt/poky-atmel/2.0/environment-setup-armv5e-poky-linux-gnueabi

$ echo $CC

$ vim hello.c
#include <stdio.h>

int main(int argc, char **argv)
{
   printf("Hello ARM!\n");
   return 0;
}

$ $CC -o hello-arm hello.c

$ file hello-arm
hello-arm: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=878b49bc56e9d1ad774bf070efb3da6e08a086c8, not stripped
  1. Qu’est-ce que ELF ?

    ELF (Executable and Linkable Format) est un format de fichier binaire utilisé pour l’enregistrement de code compilé (objets, exécutables, bibliothèques de fonctions). Aujourd’hui, ce format est utilisé dans la plupart des systèmes d’exploitation de type Unix (GNU/Linux, Solaris, IRIX, System V, BSD), à l’exception de Mac OS X.

Il faut maintenant transférer le binaire “hello-arm” sur la cible. On peut utiliser scp :

$ scp hello-arm root@192.168.52.XXX:/home/root

Puis sur la cible, on exécute le programme :

# ./hello-arm
Hello ARM!

Retour au sommaire