Objectifs

Sur le kit AT91SAM9x5, être capable :

Le kit AT91SAM9x5 dispose d’une mémoire ROM interne (64 KOctets) contenant un programme d’amorçage (bootstrap) permettant de lancer un démarrage (boot) sur au choix : la NAND Flash, la SDCard ou la DataFlash.

Ici, on dispose de 256 MOctets de NAND Flash (29F2G08 : 2Gb / 8 = 256 MO (Micron TechnologyMT29F2G(08,16)AAD,ABD.pdf)

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. Toutefois son interface d’entrée / sortie n’autorise que l’accès séquentiel. Cela tend à limiter au niveau du système sa vitesse effective de lecture, et à compliquer le démarrage direct à partir d’une mémoire NAND. De ce fait elle est moins bien adaptée que la NOR pour exécuter du code machine. 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).

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.

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.

$ dmesg
...
[84712.871591] usb 3-9.4.2: New USB device found, idVendor=03eb, idProduct=6124
[84712.871594] usb 3-9.4.2: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[84712.872120] cdc_acm 3-9.4.2:1.0: This device cannot do calls on its own. It is not a modem.
[84712.872157] cdc_acm 3-9.4.2:1.0: ttyACM0: USB ACM device

$ lsusb
...
Bus 003 Device 020: ID 03eb:6124 Atmel Corp. at91sam SAMBA bootloader

$ ls -l /dev/ttyACM0
crw-rw---- 1 root dialout 166, 0 déc.  17 04:57 /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).

$ 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.

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 :

Principe

La séquence de démarrage du kit AT91SAM9x5 est la suivante :

Et la carte mémoire de la NAND Flash :

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 6 zones dans la NAND Flash :

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 :

bootdelay=1
bootargs=console=ttyS0,115200 
mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256k(env),256k(env_redundant),256k(spare), 512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs rw video=LVDS-1:800x480-16
bootcmd=nand read 0x21000000 0x00180000 0x0000765F; nand read 0x22000000 0x00200000 0x003A15E0; bootz 0x22000000 - 0x21000000

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

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

Console DEBUG

Le kit d’Atmel possède un port DEBUG (DBGU) que l’on peut relier au PC avec un adaptateur RS232/USB.

$ dmesg
[90920.265057] usb 3-9.4.4: New USB device found, idVendor=067b, idProduct=2303
[90920.265059] usb 3-9.4.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[90920.265061] usb 3-9.4.4: Product: USB-Serial Controller
[90920.265062] usb 3-9.4.4: Manufacturer: Prolific Technology Inc.
[90920.265697] pl2303 3-9.4.4:1.0: pl2303 converter detected
[90920.266654] usb 3-9.4.4: pl2303 converter now attached to ttyUSB0

$ lsusb
...
Bus 003 Device 010: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port

On obtient un port série virtuel /dev/ttyUSB0 pour la console de débugage que l’on peut utiliser avec soit :

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

Mettre les dip switch SW 1 et 2 à OFF, le JP9 OUVERT et le JP5 CLOSE, on obtient sur la console DBGU :

$ picocom -b 115200 /dev/ttyUSB0

RomBOOT

Mettre le dip switch SW 1 à ON (accès à la NAND Flash) et faire un Reset, on observe alors un démarrage à partir de la NAND Flash :

RomBOOT
AT91Bootstrap 3.8 (Tue Dec 15 12:42:28 CET 2015)

1-Wire: Loading 1-Wire information ...
1-Wire: ROM Searching ... Done, 0x3 1-Wire chips found

1-Wire: BoardName | [Revid] | VendorName
  #0x0  SAM9x5-EK [B0]      FLEX
  #0x1  SAM9X35-CM [B1]      EMBEST
  #0x2  SAM9x5-DM [B0]      FLEX

1-Wire: SYS_GPBR2: 0x4010426, SYS_GPBR3: 0x8421

NAND: ONFI flash detected
NAND: Manufacturer ID: 0x2c Chip ID: 0x32
NAND: Disable On-Die ECC
NAND: Initialize PMECC params, cap: 0x2, sector: 0x200
NAND: Image: Copy 0x80000 bytes from 0x40000 to 0x26f00000
NAND: Done to load image

U-Boot 2015.01-linux4sam_5.0 (Dec 15 2015 - 12:43:09)

CPU: AT91SAM9X35
Crystal frequency:       12 MHz
CPU clock        :      400 MHz
Master clock     :  133.333 MHz
DRAM:  128 MiB
WARNING: Caches not enabled
NAND:  256 MiB
MMC:   mci: 0
In:    serial
Out:   serial
Err:   serial
Net:   macb0
Error: macb0 address not set.

Hit any key to stop autoboot:  0 

NAND read: device 0 offset 0x180000, size 0x765f
 30303 bytes read: OK

NAND read: device 0 offset 0x200000, size 0x3a15a0
 3806624 bytes read: OK
Kernel image @ 0x22000000 [ 0x000000 - 0x3a15a0 ]
## Flattened Device Tree blob at 21000000
   Booting using the fdt blob at 0x21000000
   Loading Device Tree to 27dda000, end 27de465e ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
...

Programmation

Pré-requis :

La procédure est la suivante :

Exemple 1 : 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_5series_1.2/linux4sam-angstrom-x11-at91sam9x5ek.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-x11-at91sam9x5ek.zip
Archive:  linux4sam-angstrom-x11-at91sam9x5ek.zip
   creating: linux4sam-angstrom-x11-at91sam9x5ek/
  inflating: linux4sam-angstrom-x11-at91sam9x5ek/at91sam9x5ek_demo_linux_nandflash.bat  
  inflating: linux4sam-angstrom-x11-at91sam9x5ek/Angstrom-x11-at91sam9-image-eglibc-ipk-v20110624-at91sam9x5ek.rootfs.ubi  
  inflating: linux4sam-angstrom-x11-at91sam9x5ek/boot.bin  
  inflating: linux4sam-angstrom-x11-at91sam9x5ek/u-boot.bin  
  inflating: linux4sam-angstrom-x11-at91sam9x5ek/at91sam9x5ek_demo_linux_nandflash.tcl  
  inflating: linux4sam-angstrom-x11-at91sam9x5ek/at91sam9x5ek_demo_linux_nandflash.sh  
  inflating: linux4sam-angstrom-x11-at91sam9x5ek/uImage-2.6.39-r2-at91sam9x5ek.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. Sur les systèmes embarqués, il est couramment utilisé uImage, un fichier qui inclut le noyau et U-Boot ainsique les informations pour le chargement. uImage est créé avec l’outil mkimage.

L’archive fournit :

Remarque : UBIFS (UBI File System) est un système de fichiers journalisé, conçu pour les systèmes à mémoire flash comme les Solid State Drive, développé par Nokia avec l’aide de l’Universtité de Szeged. UBIFS s’appuie sur UBI (Unsorted Block Images), une couche d’abstraction matérielle présente dans le noyau Linux depuis la version 2.6.22 qui permet de gérer les périphériques à base de mémoire NAND flash.

$ cd linux4sam-angstrom-x11-at91sam9x5ek

$ chmod +x at91sam9x5ek_demo_linux_nandflash.sh
$ ./at91sam9x5ek_demo_linux_nandflash.sh

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

Quelques informations sur le système installé :

// L'OS
# uname -a
Linux at91sam9x5ek 2.6.39 #1 Fri Nov 18 12:49:36 CET 2011 armv5tejl GNU/Linux

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

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

// Le système de fichiers
# df -h | grep rootfs
ubi0:rootfs             217.7M     85.6M    132.2M  39% /

La distribution Ångström, installée ici, utilise des paquets IPK. Le gestionnaire de paquet à utiliser est opkg.

Remarque : 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 est réalisée à partir des fichiers “.conf” dans /etc/opkg/. Il faut tout d’abord modifier les URLs :

http://feeds.angstrom-distribution.org/feeds/next/ipk/eglibc/armv5te/

en

http://feeds.angstrom-distribution.org/feeds/v2013.12/ipk/eglibc/armv5te/

On peut faire cela en une seule commande :

# sed -i 's#feeds/next#feeds/v2013.12#' /etc/opkg/*.conf

On met à jour le référencement des paquets, puis on installe gcc :

# opkg update
# opkg install gcc-dev
# opkg install binutils

On peut maintenant écrire notre premier programme :

# 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).

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.

Remarque : 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

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

$ scp hello-arm root@192.168.52.44:/home/root

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

# ./hello-arm
Hello ARM!

Sur le même principe, on peut réaliser un programme en C++ :

$ vim hello.cpp 
#include <iostream>

using namespace std;

int main()
{
   cout << "Hello, ARM" << endl;
   return 0;
}

$ echo $CXX
arm-poky-linux-gnueabi-g++ -march=armv5e -marm -mthumb-interwork --sysroot=/opt/poky-atmel/2.0/sysroots/armv5e-poky-linux-gnueabi

$ $CXX -o hello-cpp hello.cpp

$ file hello-cpp 
hello-cpp: 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]=89f906f1b60b3e144c9b1e5fb90ff3ea4615b6e1, not stripped

$ scp hello-cpp root@192.168.52.44:/home/root

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

# ./hello-cpp
Hello, ARM

Exemple 2 : Yocto/Poky

Si vous avez créé votre système à partir de Yocto/Poky, vous disposez du script “flasher.sh” depuis votre répertoire de build :

$ ../../meta-atmel/scripts/flasher.sh core-image-minimal /dev/ttyACM0 at91sam9x35ek

Retour au sommaire