Utilisation du SDK mbed sur un tout petit microcontrôleur LPC810

Magazine
Marque
Open Silicium
Numéro
17
|
Mois de parution
janvier 2016
|
Domaines


Résumé
Le microcontrôleur LPC810 de NXP est un cortex-M0+ disponible en petit boîtier DIP8. Avec ses 30 MHz, 1 Ko de RAM, 4 Ko de Flash et son faible coût de 1€, il se veut une alternative 32-bit aux ATtiny. Nous allons utiliser le SDK mbed de ARM et l'exemple MBED_BLINKY pour explorer sa mise en œuvre.

Body

lpc800_dip8

1. SDK mbed et LPC810, la rencontre

Le SDK mbed est une bibliothèque open source développée par ARM fournissant une API indépendante du hardware, simplifiant ainsi la programmation de votre microcontrôleur préféré. ARM propose le mbed Compiler, un IDE en ligne déjà présenté dans Hackable n°3, mais ne proposant qu'un sous-ensemble des plateformes supportées par le SDK mbed.

Une plateforme mbed Enabled doit avoir une interface USB, proposant un périphérique mass-storage pour reflasher le microcontrôleur, l'accès au port série, et une interface générique de debug CMSIS-DAP. Vous trouverez la liste des plateformes mbed Enabled sur https://developer.mbed.org/platforms/ et plus d'informations sur le « mbed HDK Handbook » sur https://developer.mbed.org/handbook/mbed-HDK#cmsis-dap-interface.

La plateforme mbed Enabled la plus proche du LPC810 est la « NXP LPC800-MAX », avec un LPC812 : 4 Ko de RAM et 16 Ko de Flash. Bien que ces deux microcontrôleurs soient de la même famille, les binaires compilés pour le LPC812 ne pourront être utilisés sur le LPC810 parce que la stack est placée à la fin de la RAM, bien au-delà de ce que supporte le LPC810.

Nous allons donc devoir sortir des sentiers battus et nous passer (des limitations) de l'IDE en ligne : c'est tout un univers de plateformes atypiques qui devient accessible ! Il est bon de noter qu'il ne suffit souvent que de petits changements pour pouvoir supporter une nouvelle plateforme si le microcontrôleur est supporté.

2. Mon premier build

2.1 Installation du cross-compilateur

Commençons par installer le cross-compilateur (toolchain) « bare-metal » pour les processeurs arm. Les utilisateurs de distributions Debian et dérivées pourront installer le paquet gcc-arm-none-eabi. Les autres distributions fournissent peut-être un paquet équivalent, ou peuvent télécharger une version « Bare-metal toolchain for Cortex-R/M » de Linaro depuis https://www.linaro.org/downloads/ (il y a même une version Windows...).

2.2 Récupération du SDK mbed

Il faut ensuite récupérer la dernière version depuis le dépôt officiel sur GitHub :

cyprien@linux-dev:~/hk$ git clone https://github.com/mbedmicro/mbed.git

Cloning into 'mbed'...

remote: Counting objects: 52343, done.

remote: Compressing objects: 100% (19/19), done.

remote: Total 52343 (delta 7), reused 0 (delta 0), pack-reused 52324

Receiving objects: 100% (52343/52343), 31.29 MiB | 3.25 MiB/s, done.

Resolving deltas: 100% (34451/34451), done.

Checking connectivity... done.

Checking out files: 100% (5638/5638), done.

cyprien@linux-dev:~/hk$

Le SDK mbed requiert python 2.7, et l'outil python-setuptools. J'avoue tout de suite que j'avais sauté cette étape, mais elle est documentée dans mbed/docs/BUILDING.md et permet sûrement d'éviter de tomber sur des erreurs python lors de l'exécution des scripts mbed. L'installation des modules python pour mbed peut alors se faire :

cyprien@linux-dev:~/hk/mbed$ sudo python setup.py install

running install

running bdist_egg

[ . . . ]

Finished processing dependencies for mbed-tools==0.1.14

2.3 Extraction du test MBED_BLINKY

Le SDK est prévu pour être compilé pour une plateforme donnée, et de compiler des programmes de tests. Il est même possible d'automatiser l'exécution de ces tests sur une plateforme mbed Enabled connectée sur la machine. Mais pour plus de flexibilité, nous allons utiliser la fonction d'exportation pour obtenir une archive ne contenant que les fichiers nécessaires pour le LPC810, la toolchain GCC pour ARM, et le programme de test MBED_BLINKY :

cyprien@linux-dev:~/hk$ cd mbed/

cyprien@linux-dev:~/hk/mbed$ python workspace_tools/project.py -m LPC810 -i gcc_arm -n MBED_BLINKY

[WARNING] Using default settings. Define your settings in the file "workspace_tools/private_settings.py" or in "./mbed_settings.py"

Copy: test_env.h

. . .

Copy: main.cpp

Successful exports:

  * LPC810::gcc_arm     /home/cyprien/hk/mbed/build/export/MBED_BLINKY_gcc_arm_LPC810.zip

Sans paramètre, cette commande vous donnera la liste exhaustive des tests, chaînes de compilations et MCU supportés. Attention toutefois, toutes les toolchains ne sont pas supportées par tous les MCU, et le support de GCC pour les LPC810/812 n'est arrivé que récemment. Pour plus d'informations concernant les scripts existant, vous pouvez vous référer au document BUILDING.md cité plus haut.

Décompressons maintenant l'archive et regardons rapidement ce qu'elle nous réserve :

cyprien@linux-dev:~/hk/mbed$ cd ..

cyprien@linux-dev:~/hk$ unzip -x mbed/build/export/MBED_BLINKY_gcc_arm_LPC810.zip

Archive:  /home/cyprien/hk/mbed/build/export/MBED_BLINKY_gcc_arm_LPC810.zip

  inflating: MBED_BLINKY/GettingStarted.htm  

  inflating: MBED_BLINKY/Makefile    

  inflating: MBED_BLINKY/main.cpp

[ . . .]

  inflating: MBED_BLINKY/mbed/hal/serial_api.h  

cyprien@linux-dev:~/hk$ cd MBED_BLINKY/

cyprien@linux-dev:~/hk/MBED_BLINKY$ ls

env  GettingStarted.htm  main.cpp  Makefile  mbed

2.4 Compilation

Le Makefile indique l'étape suivante :

cyprien@linux-dev:~/hk/MBED_BLINKY$ make

arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb  -c -x assembler-with-cpp -o

mbed/targets/cmsis/TARGET_NXP/TARGET_LPC81X/TOOLCHAIN_GCC_ARM/startup_LPC81X.o

mbed/targets/cmsis/TARGET_NXP/TARGET_LPC81X/TOOLCHAIN_GCC_ARM/startup_LPC81X.S

[ . . . ]

*****

***** You must modify vector checksum value in *.bin and *.hex files.

*****

arm-none-eabi-objcopy -O binary MBED_BLINKY.elf MBED_BLINKY.bin

arm-none-eabi-size  MBED_BLINKY.elf

   text    data     bss     dec     hex filename

   3504     192     228    3924     f54 MBED_BLINKY.elf

cyprien@linux-dev:~/hk/MBED_BLINKY$ ls -l MBED_BLINKY.bin

-rwxr-xr-x 1 cyprien dialout 3696 Sep  6 13:54 MBED_BLINKY.bin

Votre premier exemple mbed est prêt à être flashé ! Notez la taille du binaire, 3696 octets, uniquement pour faire clignoter une LED. Il n'y a plus beaucoup d'espace libre pour faire des choses intéressantes...

Le résultat de la compilation nous met en garde qu'il nous faudra changer la somme de contrôle des vecteurs dans le fichier binaire. Au démarrage, la ROM va vérifier si le « vector checksum » est correct. Si incorrect, le code entrera en mode programmation. La plupart des outils permettant la reprogrammation de ces microcontrôleurs calculent ce checksum à la volée.

2.5 Outil de flashage

Mais comment flasher ce binaire si on utilise directement le microcontrôleur, sans l'interface de programmation mbed ? La famille des LPC se programme via le port série en utilisant le code « In-System Programming » en ROM lorsque la pin 5 nISP est à l'état bas lors de la mise sous tension. J'utilise l'outil lpctools de Nathaël Pajani (Techno Innov), disponible en paquet debian, ou sur le dépôt git http://git.techno-innov.fr/?p=lpctools.

Techno-Innov propose les LPC810 à 1€ pièce, mais aussi des LPC812 (20 pins, 4 Ko de RAM et 16 Ko de Flash) et des kits d'initiation à la soudure avec ces processeurs. Le LPC812 en TSSOP20 pourra être soudé sur un adaptateur DIP20 et être utilisé sur une plaque d'expérimentation. Bien sûr, les binaires générés par l'IDE mbed pourront directement être utilisés ! À trouver sur http://boutique.techno-innov.fr/.

3. Mon premier montage

blinky

Fig. 1 : Montage correspondant au test MBED_BLINKY. Notez bien que le LPC810 n'accepte que du 3.3V !

Le programme de test fait clignoter une LED connectée au LPC8120. Il s'agit de la LED1, définie comme étant le GPIO P0_2.

Le bouton poussoir ne sert qu'à entrer en mode programmation et peut être remplacé par un fil à ne brancher que lorsque nécessaire. Appuyez sur le bouton ou connectez la pin 5 à la masse pendant que vous connectez l'adaptateur USB série sur votre ordinateur. Vous devez voir dans vos logs l'apparition d'un périphérique ttyUSB0, que vous allez utiliser flasher le LPC810 :

cyprien@linux-dev:~/hk/MBED_BLINKY$ lpcprog -d /dev/ttyUSB0 -c flash MBED_BLINKY.bin

Device session openned.

Part ID 0x00008100 found on line 18

Flash now all blank.

Checksum check OK

Flash size : 4096, trying to flash 15 blocks of 256 bytes : 3840

Writing started, 15 blocks of 256 bytes ...

cyprien@linux-dev:~/hk/MBED_BLINKY$

Si vous obtenez une erreur à cette étape, il est possible que vous ayez loupé le processus de reboot, ou que vous ayez oublié de déconnecter un terminal du port série (oui, ça m'arrive très souvent!). Retentez votre chance.

Si vous avez utilisé un fil pour entrer en mode programmation, c'est le moment de le retirer. Provoquez alors un redémarrage en débranchant et rebranchant l'adaptateur USB, puis observez la LED clignoter. Félicitations !

Mises en garde habituelles :

  • la tension d'alimentation du LPC810 est de 3.3V. Le LPC810 n'est pas tolérant au 5V. Il ne faut donc utiliser que des convertisseurs USB série fournissant du 3.3V ;
  • seules les pins P0_2 et P0_3 du LPC810 (ainsi que P0_7 et P0_13 sur un LPC812) supportent un courant jusqu'à 20mA (idéal pour les LED), et il faudra se limiter à 4 mA pour les autres pins.

4. mbed et les 4 petits kilos...

Faire clignoter une LED, c'est un peu le Hello World du maker. En mbed, cela donne :

#include "mbed.h"

DigitalOut myled(LED1);

int main() {

    while(1) {

        myled = 1;

        wait(0.2);

        myled = 0;

        wait(0.2);

    }   

}

Le code se trouve dans le fichier main.cpp. Ajoutons un petit message dans la boucle, puis compilons à nouveau :

#include "mbed.h"

DigitalOut myled(LED1);

int main() {

    while(1) {

        puts("Hello World!");

        myled = 1;

        wait(0.2);

        myled = 0;

        wait(0.2);

    }   

}

cyprien@linux-dev:~/hk/MBED_BLINKY$ make

[ . . . ]

/usr/lib/gcc/arm-none-eabi/4.8/../../../arm-none-eabi/bin/ld: MBED_BLINKY.elf section `.text' will not fit in region `FLASH'

/usr/lib/gcc/arm-none-eabi/4.8/../../../arm-none-eabi/bin/ld: region RAM overflowed with stack

/usr/lib/gcc/arm-none-eabi/4.8/../../../arm-none-eabi/bin/ld: region `FLASH' overflowed by 2464 bytes

collect2: error: ld returned 1 exit status

Makefile:64: recipe for target 'MBED_BLINKY.elf' failed

make: *** [MBED_BLINKY.elf] Error 1

Aïe ! Nous venons de déborder de la flash, avec un simple puts(). Nous sommes coincés, et il serait tentant de conclure dès maintenant par « mbed c'est uniquement pour les gros microcontrôleurs ». Pas si vite ! Regardons ce qu'est mbed et ce que l'on peut faire.

On peut énumérer ainsi les différentes couches du SDK mbed :

  • les registres d'accès au matériel, c'est le mapping mémoire des périphériques du microcontrôleur, généralement fourni par le vendeur du microcontrôleur ;
  • l'implémentation CMSIS-CORE, qui donne accès aux fonctionnalités des cœurs Cortex-M sous une interface générique, fournie par ARM ;
  • l'implémentation de la couche d'abstraction mbed, qui fournit l'accès aux périphériques (GPIO, port série, timers...) via une API indépendante du matériel ;
  • l'interface et l'implémentation de la mbed API.

Vous l'aurez sans doute remarqué, le code de test utilise la classe C++ DigitalOut. Celle-ci fait partie de la mbed API. Elle utilise en interne la HAL mbed, qui est entièrement écrite en C.

5. Utilisation de la mbed HAL en C

Nous allons nous passer de la mbed ABI en C++ pour n'utiliser que la HAL C. Il faut donc renommer notre fichier main.cpp en main.c, et faire un petit make clean pour se débarrasser des fichiers de dépendances.

Modifions donc le code de notre exemple :

#include "serial_api.h"

#include "gpio_api.h"

#include "wait_api.h"

/* Déclaration des objets GPIO et port série */

gpio_t myled;

serial_t pc;

/* L'interface pour le port série ne propose pas l'équivalent de puts */

static void serial_puts(serial_t *obj, const char *msg)

{

    while(*msg) serial_putc(obj, *msg++);

    serial_putc(obj, '\n');

}


int main() {

    /* Initialisation du port série */

    serial_init(&pc, P0_4, P0_0);

    serial_baud(&pc, 115200);

    /* Initialisation du GPIO de la LED */

    gpio_init_out(&myled, LED1);

    while(1) {

        serial_puts(&pc, "Hello World!");

        gpio_write(&myled, 1);

        wait_ms(200);

        gpio_write(&myled, 0);

        wait_ms(200);

    }

    return 0;

}

Voyons ce qui a changé :

  • utilisation de wait_ms(int) plutôt que wait(float). L'utilisation de nombres entiers évite au compilateur d'ajouter le code d'émulation des nombres flottants ;
  • utilisation de l'API gpio_api.h pour faire clignoter la LED ;
  • utilisation de l'API serial_api.h pour la gestion du port série. Utiliser puts() fait inclure les fonctions de la libc pour la gestion de la sortie standard.

Voyons voir le résultat de la compilation :

cyprien@linux-dev:~/hk/MBED_BLINKY$ make

arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb  -c -x assembler-with-cpp -o

mbed/targets/cmsis/TARGET_NXP/TARGET_LPC81X/TOOLCHAIN_GCC_ARM/startup_LPC81X.o

mbed/targets/cmsis/TARGET_NXP/TARGET_LPC81X/TOOLCHAIN_GCC_ARM/startup_LPC81X.S

[ . . . ]

*****

***** You must modify vector checksum value in *.bin and *.hex files.

*****

arm-none-eabi-objcopy -O binary MBED_BLINKY.elf MBED_BLINKY.bin

arm-none-eabi-size  MBED_BLINKY.elf

   text    data     bss     dec     hex filename

   3280     192     256    3728     e90 MBED_BLINKY.elf

cyprien@linux-dev:~/hk/MBED_BLINKY$ ls -l MBED_BLINKY.bin

-rwxr-xr-x 1 cyprien dialout 3472 Sep  6 15:46 MBED_BLINKY.bin

Ça rentre ! Il ne reste plus qu'à rebooter le LPC810 en pensant bien à appuyer sur le bouton pour entrer en mode programmation, réexécuter la commande pour flasher le nouveau code, et rebooter à nouveau. Vous pourrez alors voir sur le port série le nouveau message.

Vous voilà prêts pour explorer la HAL mbed et faire preuve de créativité. Malheureusement, il ne semble pas y avoir de documentation dédiée de ces API C, et il faudra donc se contenter du code source. Vous trouverez les principaux fichiers en-tête C dans mbed/libraries/mbed/hal/ et quelques-uns dans mbed/libraries/mbed/api/.

Références


Sur le même sujet

Des kits de développement FPGA à moins de 30 €

Magazine
Marque
Hackable
Numéro
32
|
Mois de parution
janvier 2020
|
Domaines
Résumé

Même s’il est possible de faire 90 % du développement en simulation et sans matériel, quand on «fait du FPGA», on souhaite pouvoir toucher du concret. Il est donc nécessaire d’avoir une carte électronique permettant de faire fonctionner son projet en réel. Les outils de développement sur FPGA ont la réputation d’être chers et réservés aux universités et bureaux d’études. Ce n’est pourtant plus le cas, il existe de plus en plus de kits de développement permettant de mettre le pied à l'étrier à moindres frais. Et tous proposent désormais leur logiciel de développement gratuit fonctionnant sous GNU/Linux (mais pas tous libres). Nous allons ici lister quelques-uns de ces kits.

Un éclairage économique pour plante domestique

Magazine
Marque
Hackable
Numéro
32
|
Mois de parution
janvier 2020
|
Domaines
Résumé

Avec l'hiver s'en vont la chaleur et la lumière, ce qui ne plaît pas aux plantes exotiques, qui n'ont jamais demandé un tel traitement. Évidemment, la technologie a des solutions et celle que nous étudierons ici repose sur quelques fonds de tiroirs et un module à LED très spécial.

Le coût de la rétro-ingénierie du silicium

Magazine
Marque
Hackable
Numéro
32
|
Mois de parution
janvier 2020
|
Domaines
Résumé

La rétro-ingénierie matérielle est une pratique qui a longtemps été réservée aux états et aux industriels, et ce, en grande partie à cause des coûts engendrés. Cependant aujourd'hui, chaque personne ayant un bagage technique suffisant peut pratiquer cet art sans avoir à dépenser des sommes astronomiques, on peut alors précisément se poser la question du coût matériel pour différentes configurations. Je vais vous présenter différents ensembles de matériels selon leurs coûts, que nous ferons correspondre à différents niveaux d'expertise en laboratoire. Cet article s'adresse donc autant aux amateurs néophytes, désireux d'acquérir la capacité de pratiquer la rétro-ingénierie matérielle, qu'aux universités voulant lancer un laboratoire dans ce domaine. Nous n'aborderons ici qu'un seul type d'attaque, celle par analyse de puces de silicium. Pour les autres types d'attaques, vous aurez généralement une seule méthode disponible et donc un seul type de matériel ou de machine, ce qui rend la chose trop spécifique pour être abordé ici.

Reverse-engineering d’une alimentation numérique et contrôle avec bash

Magazine
Marque
Hackable
Numéro
32
|
Mois de parution
janvier 2020
|
Domaines
Résumé

Le marché propose de nos jours des alimentations de laboratoire aux caractéristiques très intéressantes : compactes, puissantes, programmables... Conçues et fabriquées en Chine, évidemment, elles sont économiques et très peu concernées par les standards ou les protocoles, contrairement aux équipements professionnels des grandes marques, chers, mais relativement ouverts. Cet article va examiner un modèle particulier que vous risquez de retrouver sous une forme ou une autre. Ses protocoles ont pu être documentés, grâce aux efforts de la communauté des bricoleurs, ce qui rend cet appareil encore plus utile et très facile à programmer !

Module interface I2C pour écran LCD

Magazine
Marque
Hackable
Numéro
32
|
Mois de parution
janvier 2020
|
Domaines
Résumé

Les afficheurs LCD alphanumériques disposant d'une interface compatible HD44780 (composant Hitachi à l'origine) se pilotent tous de la même façon et peuvent avoir différentes caractéristiques et tailles : une ligne de 8 caractères, quatre lignes de 20 caractères, deux lignes de 16 caractères, etc., tantôt avec rétroéclairage, tantôt sans.

Simulez vos circuits électroniques avant de réaliser vos cartes électroniques avec KiCAD

Magazine
Marque
Hackable
Numéro
32
|
Mois de parution
janvier 2020
|
Domaines
Résumé

Tout comme la conception et la modélisation de systèmes mécaniques via des logiciels libres tels que FreeCAD, SaloméMeca ou bien des logiciels propriétaires comme Catia/Solidworks, la conception, simulation et réalisation de circuits électroniques n'ont jamais été aussi simples depuis l'arrivée de la version 5 de KiCAD [1, 2, 3]. Bien qu'existant depuis de nombreuses années, la dernière mouture de KiCAD intègre la librairie partagée Ngspice pour réaliser les simulations. Il est cependant toujours possible d'utiliser directement Ngspice en tant que plugin, comme nous le verrons également en fin d'article [4].

Par le même auteur

Utilisation du SDK mbed sur un tout petit microcontrôleur LPC810

Magazine
Marque
Open Silicium
Numéro
17
|
Mois de parution
janvier 2016
|
Domaines
Résumé
Le microcontrôleur LPC810 de NXP est un cortex-M0+ disponible en petit boîtier DIP8. Avec ses 30 MHz, 1 Ko de RAM, 4 Ko de Flash et son faible coût de 1€, il se veut une alternative 32-bit aux ATtiny. Nous allons utiliser le SDK mbed de ARM et l'exemple MBED_BLINKY pour explorer sa mise en œuvre.