Styles

jeudi 12 février 2009

Système embarqué et programmation Nintendo DS

M’étant épris de la nintendo DS, je me suis mis à expérimenter un développement pour cette merveille de raffinement technologique. Quand on étudie l’architecture de cette machine, on ne peut s’empêcher de penser que ses concepteurs ont pris du plaisir à la concevoir. En voyant la représentation de l’architecture ci-dessous, cela m’a tout de suite rappelé celle de l’Amiga qui tirait plus sa force de son chipset original que de son processeur proprement dit :

La nintendo DS a deux processeurs différents : un ARM7TDMI et un ARM946E-S partageant des espaces mémoires en commun, ayant à leur disposition, différents types de mémoire plus ou moins rapide (DTCM et ITCM, WRAM, ICACHE et DCACHE de l’ARM9…)

Programmer pour la nintendo DS, c’est bien programmer pour "un système embarqué" (embedded). Un des concepts importants en programmation embarqué est l’utilisation de registre mappé sur la mémoire : « memory-mapped registers ». Ce genre de technique apporte son lot de problèmes et de solution, notamment par l'emploi, en langage C, du mot clé "volatile", qui n'a rien à voir avec les oiseaux, comme nous le montre très bien Nigel Jones dans How to use C's volatile keyword et que je vous traduirais ainsi :
Les système embarqués contiennent du vrai matériel, habituellement avec des périphériques sophistiqués. Ces périphériques contiennent des registres dont les valeurs peuvent changer de façon asynchrone vis à vis du déroulement du programme. Pour prendre un exemple très simple, considérez un registre de status sur 8 bits qui soit mappé sur la mémoire à l'adresse 0x1234. Il est nécessaire de scruter le registre de status jusqu'à ce qu'il ne soit plus égal à 0. Une implémentation naive et incorrecte pourrait être comme cela :

uint8_t * pReg = (uint8_t *) 0x1234;

// Wait for register to become non-zero.
while (*ptr == 0);
// Do something else.

Cela va très certainement ne pas fonctionner dès que vous allez autoriser les optimisations du compilateur, du fait que le compilateur va générer de l'assembleur qui va ressembler à ça :

     mov ptr, #0x1234
mov a, @ptr
loop bz loop

La logique de l'optimisateur est assez simple : ayant déjà lu la valeur de la variable dans l'accumulateur (à la deuxième ligne de l'assembleur), il n'y a pas besoin de la relire puisque la valeur sera toujours la même. Ainsi, en troisième ligne, on abouti à une boucle infinie. Pour forcer le compilateur à faire ce que nous voulons, nous modifions la déclaration en :

uint8_t volatile * pReg = (uint8_t volatile *) 0x1234;

L'assembleur va maintenant ressembler à ça :
      mov ptr, #0x1234
loop mov a, @ptr
bz loop

Le comportement désiré est obtenu.
C’est dans ce genre d’exemple qu’on s’aperçoit qu’il est toujours bon de savoir ce qui se passe en dessous (en assembleur) du langage que l’on utilise (le langage C).

La programmation sur Nintendo DS regroupe un ensemble d'avantages certains pour le jeune programmeur (comme pour les moins jeunes comme moi :) ) :

- programmation directe pour la machine : il n'y a pas de système d'exploitation entre le programme que vous concevez et la machine. Cela oblige à comprendre comment fonctionne réellement un système embarqué, et un système informatique tout court.

- programmation d'une console de jeu : c'est motivant (c'est fun quoi :) ) parce qu'on peut arriver à avoir beaucoup d'effets graphiques 2D, 3D et sonores, et puis il y a aussi une véritable tablette graphique, une connexion réseau Wifi, un microphone intégré (et bientôt un appareil photo sur la nouvelle console Nintendo DSi)

- simplicité du kit de développement grâce à devkitpro qui contient tout ce qui est nécessaire pour développer correctement sur Nintendo DS. Cela permet d'apprendre le langage C pour ce qu'il a de meilleur : un accès très bas niveau et performant.

Aujourd'hui, j'imagine que pour un gosse qui découvre l'informatique et veut y mettre les mains, la Nintendo DS est bien plus motivante, dans un premier temps, que d'attaquer directement des systèmes embarqués ou de la programmation Web. Il est toujours important de s'essayer dans le domaine où on a le plus d'endurance aux échecs, là où vous retrouverez le plus facilement de la motivation même en face de problèmes insondables. Garder du plaisir à programmer c'est ça qui permet d'aller au delà des bugs et problèmes, et d'aboutir à des systèmes géniaux comme ce à quoi ont aboutis les concepteurs de la Nintendo DS.

Dans un deuxième temps, après s'être fait la main sur cette console, on peut toujours se tourner vers des systèmes qui nous plaisent mieux, comme des systèmes embarqués (Arduino ou le .NET Micro Framework par exemple), des systèmes d'exploitation (Linux ou pourquoi pas OpenBSD, voire même s'essayer à décoder les tripes de Windows) ou encore des applications Web / SGBD...

1 commentaire:

PypeBros a dit…

Ahh ... le développement sur DS. Quelle belle aventure...