Dans la première partie, nous avons découvert les principes
pour réaliser des petits programmes en assembleur avec des données en entrée et
des données en sortie dans la console ou dans des fichiers. Maintenant nous
allons essayer de découvrir des utilisations plus poussées sur le
Raspberry : dessin, gestion de fenêtres, gpio.
Déjà, nous avons pu remarquer que dans les instructions
assembleur ARM, il n’y a pas d’instructions d’entrée-sorties pour accéder à des
interfaces divers : écran, clavier, gpio, usb , réseau. Et donc tout me reste à
découvrir.
Voyons déjà comment dessiner sur l’écran du Raspberry. Les
premières recherches pour lire et écrire directement dans les adresses mémoires
réservées à l’affichage sont des échecs. En effet, un mécanisme de protection
géré par Linux interdit à un utilisateur non habilité à accéder aux adresses
mémoire importantes pour le fonctionnement de l’ordinateur. Mais une autre solution
est proposée, c’est d’utiliser une notion appelée frameBuffer qui permet d’accéder à ces adresses en
effectuant un mapping (mappage ?) entre les adresses physiques et des
adresses en mémoire dont l’accès est autorisé. Voyons le source du programme.
Nous allons commencer par afficher quelques caractéristiques
de l’affichage et pour cela nous décrivons 2 structures de données différentes,
une pour les informations fixes de l’écran, l’autre pour les informations
variables.
Dans la partie .data, nous décrivons les messages pour
afficher les informations principales et dans la section .bss, nous réservons
la place pour le stockage des 2 structures définies plus haut. En effet les
structures ne servent qu’à attribuer des noms et des déplacements à des zones en
fonction de leur emplacement et il faut donc réserver la place en mémoire pour
attribuer un pointeur qui nous servira lors des appels.
Dans la partie code, nous ouvrons le périphérique concernant
notre écran d’affichage. En fait c’est comme ouvrir un fichier mais avec un nom
standard : /dev/fb0. Et pour nous permettre de travailler dessus, nous lui
attribuons les autorisations de lecture écriture. Ensuite nous allons utiliser
l’appel system IOCTL qui permet d’obtenir les informations sur un périphérique à
l’aide de codes fonction spécifiques, d’une part les données fixes qui vont
alimenter la structure fix_info puis les données variables dans la structure
var_info. Comme exemple, nous affichons quelques données : identification,
largeur et hauteur de l’affichage et nombre de bits par pixel.
Puis nous allons effectuer un mapping du périphérique dans
une zone mémoire en utilisant l’appel systeme MMAP. Il faut lui fournir
plusieurs paramètres dont la taille en octet nécessaire. Nous trouvons cette
information dans les données fixes récupérées auparavant (zone FBFIXSCinfo_smem_len).
Vous remarquerez que pour toutes ces opérations, nous testons le code retour
des appels pour vérifier si tout se passe bien, cela évite de chercher trop
longtemps en cas de dysfonctionnement. Le mapping permet de lire et modifier le
contenu de l’affichage dans la mémoire et les modifications sont répercutées
dans le périphérique. (il faudrait approfondir ce mécanisme et voir aussi le
rôle de l’appel système SYNC).
Enfin pour vérifier si tout cela permet d’intervenir sur
l’affichage, nous nous contentions de modifier les pixels sur un huitième de
l’écran avec une couleur bleue (code rgb 0xFF). Évidement quand vous lancez ce
programme depuis la console de la connexion ssh, rien ne se passe. Donc dans un
premier temps, j’ai installé le serveur tightvncserve sur le raspberry et sur
mon ordinateur portable pour afficher les images écran en mode graphique.
Cela n’a rien donné, j’ai donc vérifié plusieurs fois le
programme, et j’étais désespéré de ne rien obtenir. Puis j’ai fait un dernier
test en branchant directement un écran sur le Raspberry et là miracle !! les
pixels bleu sont apparus. Je pensais que cette méthode d’affichage ne fonctionnait
que sur un écran connecté au Raspberry par la prise HDMI. Mais en rédigeant ce
post, je me suis repenché sur le problème. En fait le serveur tightvncserver utilise
un port différent (display :1) de celui utilisé pour l’affichage direct
(display :0) ce qui explique le dysfonctionnement. Mais j’ai trouvé sur le
blog de framboise14 un post sur l’utilisation du serveur X11vnc qui permet
d’afficher le display :0 à distance et cela fonctionne correctement.
Et maintenant quelle suite à donner : et bien vous
savez modifier des pixels !! donc il ne reste plus qu’à écrire toutes les
fonctions d’affichage classiques ( pixels, droites, cercles, polygones etc
etc.) car aucune fonction du système n’est disponible pour cela !!!! ou alors il faut utiliser les fonctions
d’une librairie graphique.
Vous trouverez des exemples d’affichage par cette méthode en
langage C sur le site : http://raspberrycompote.blogspot.fr/2013/
et il faudra adapter les programmes à l 'assembleur.
Exercices : Modifier le programme pour afficher des
trames de couleurs différentes.
Pour
ceux qui aiment les algorithmes, écrire les fonctions pour tracer une droite,
un cercle une ellipse, un rectangle etc etc.