Introduction à la programmation sur PlayStation Portable
Signature : | Mis en ligne le : 22/11/2007
Catégorie(s) :
  • GNU/Linux Magazine
  • | Domaine :
    Commentez creative commons
    Nous proposons de présenter les outils de développement libres pour la console de jeux PlayStation Portable. Après l’installation de la chaîne de cross-compilation et un premier exemple simple d’affichage graphique, nous interfacerons un récepteur GPS à la console et afficherons les coordonnées GPS courantes ou le trajet parcouru. L’objectif est de géolocaliser les points d’accès wifi détectés au moyen de l’interface de communication sans fil dont est équipée la console et de réaliser ainsi un outil de wardriving peu encombrant et présentant une autonomie de quelques heures.

    1 Introduction

    Le développement sur console de jeux portable est un moyen pratique de se familiariser avec la plupart des concepts du développement logiciel pour systèmes embarqués tout en profitant d’une plate-forme de développement peu coûteuse (par rapport aux systèmes industriels dédiés), avec de nombreuses interfaces fournies par défaut (touches, écran, périphériques de communication) et une puissance de calcul digne des ordinateurs actuels [1, 2]. Cependant, les principaux fabricants de consoles de jeux n’ont jamais été favorables au développement amateur de logiciels pour leur matériel et le programmeur désireux d’appliquer ses compétences à ces plateformes a dû tant bien que mal trouver les ressources nécessaires. Nous allons ici présenter les outils de développement disponibles pour la PlayStation Portable (PSP) de Sony : cette console fournit un écran couleur de résolution acceptable (480×272 pixels), un processeur central basé sur une architecture MIPS1 cadencé à 333 MHz [3], de nombreux périphériques (ports USB, série asynchrone, wifi) et un support de stockage de masse peu coûteux et accessible depuis un PC fonctionnant sous GNU/Linux (le Sony Memory Stick). Nous allons tenter d’utiliser au mieux ce matériel dans un objectif d’acquisition et de visualisation de données. Il ne sera pas ici question de développement de jeux qui nécessite des méthodes de programmation très particulières que l’auteur ne maîtrise pas. 1 Architecture modulaire très utilisée dans les systèmes embarqués tels que les points d’accès Broadcom : http://www.linux-mips.org/wiki/Systems Nous supposerons dans la suite de ce document que nous disposons d’un Sony Memory Stick et d’un adaptateur permettant de connecter une telle carte mémoire sur un PC, et éventuellement d’un câble de liaison PSP-USB.

    2 Installation des outils de développement

    Plusieurs langages permettant le développement d’applications pour la PSP (dits "homebrew" dans la communauté de développeurs PSP) sont disponibles : mentionnons ici notamment les langages interprétés tels que Lua ou Python. Nous nous intéresserons ici cependant directement à la solution la plus efficace, à savoir l’utilisation de gcc pour compiler du code C ou assembleur à destination du processeur MIPS de la PSP.

    2.1 Mise à jour du firmware de la console

    La première étape pour rendre une PlayStation Portable (PSP) utilisable par un développeur est de revenir à un firmware permettant l’exécution depuis le support de stockage de masse Memory Stick (MS). En effet, historiquement, Sony n’avait pas pris soin d’empêcher l’exécution d’un programme depuis ce support et cette fonctionnalité inattendue sembla poser un problème de sécurité. Il s’en est suivi une séquence de mises à jour du firmware par Sony interdisant l’exécution de programmes depuis le MS, et la mise à disposition par les développeurs indépendants de méthodes pour ramener sa PSP à un firmware acceptant de telles fonctionnalités. Le firmware de prédilection pour le développeur a pour version 1.5. Notre premier objectif est donc de reflasher le firmware de la PSP de sa version disponible à l’achat vers la version 1.5 qui autorise l’exécution d’un programme depuis le support de masse MS [4]. Attention La PSP deviendra inutilisable si cette opération échoue. Il est fondamental de bien se documenter sur les dangers de flasher sa PSP afin d’en remplacer le firmware courant par celui de la version 1.5. L’auteur ne saurait être tenu responsable pour tout dommage résultant d’un échec de cette mise à jour. La version du firmware sur une PSP achetée en France en décembre 2006 est 2.01. Le passage du firmware 2.01 au firmware 1.5 est bien documenté à http://gueux-forum.net/index.php?showtopic=125133 Un MS d’au moins 32 MB est pour cela nécessaire. Cette mise à jour efface bien entendu tous les logiciels ajoutés par Sony entre la version 1.5 et la version fournie au moment de l’achat de sa console – notamment le logiciel d’affichage de pages web. Ces fonctionnalités peuvent être retrouvées en repassant provisoirement sur un firmware plus récent grâce à Devhook. Ce logiciel permet en effet, depuis un firmware 1.50, de charger en mémoire volatile un firmware plus récent et les applications associées, et ce, jusqu’à la réinitialisation de la console (par sa mise hors tension par exemple). Nous avons utilisé à ces fins la version de Devhook incluant toutes les mises à jour, version 0.44 disponible à http://3mul.free.fr/v1/module.php?page=programme_detail&type_programme=emulateurs&i=63 qui a le bon goût de déjà inclure tous les firmwares à utiliser. Il n’est pas clair que les versions plus récentes que 1.50 des firmwares amènent des améliorations notables, si ce n’est de brider l’utilisateur dans les applications possibles de sa PSP : l’accès aux firmwares plus récents ne semble donc pas d’un intérêt remarquable, si ce n’est de se rassurer sur la disponibilité des quelques logiciels ajoutés récemment par Sony. La phase la plus dangereuse est passée : nous avons maintenant une PSP capable d’exécuter un logiciel depuis le support MS. Nous allons maintenant aborder les aspects d’installation des outils de compilation de nos programmes sous GNU/Linux à destination du processeur MIPS de la PSP (cross-compilation).

    2.2 Installation de la chaîne de cross-compilation

    La cross-compilation de code à destination du processeur MIPS de la PSP depuis l’ordinateur sur lequel tourne GNU/Linux (ici un processeur compatible Intel x86) nécessite la compilation du trio habituel gcc (version 4.0.2), binutils (version 2.16.1) et newlib (version 1.13.0). Les développeurs pour PSP ont considérablement simplifié le travail en fournissant un script, toolchain.sh dans l’archive psptoolchain-20060120.tgz disponible à http://ps2dev.org/psp/Tools, qui se charge de récupérer les bonnes versions des codes sources, leur appliquer les patchs nécessaires pour supporter l’architecture PSP, et de les compiler avec les bonnes options – principalement –target=psp. Une fois psp-gcc installé dans son emplacement par défaut /usr/local/pspdev/bin, il ne nous reste plus qu’à compiler le PSPSDK (obtenu par CVS auprès de svn://svn.pspdev.org/psp/trunk/pspsdk) afin d’obtenir tous les outils nécessaires à la génération de binaires prêts à être exécutés depuis un firmware 1.5 sur la PSP. Cette opération est assez lourde puisqu’elle nécessite entre 32 et 64 MB de RAM et environ 1,5 GB d’espace disque. L’accès à la console de jeu se fera soit après installation d’iRShell disponible à http://dl.qj.net/index.php?pg=12&fid=11531&catid=190 qui permet d’accéder à la PSP comme à une clé de stockage de masse sur port USB (Fig. 1), soit via le MS.

    /img-articles/lm/92/cc-art-psp/fig-1.jpg

    Figure 1 : Connexion de la PSP à un ordinateur portable sous Debian GNU/Linux sur lequel est installé le PSP SDK : la console apparaît comme un support de stockage de masse sur le bus USB.

    3 Premier exemple : la fractale de Mandelbrot

    De nombreux tutoriaux sont disponibles sur le web, et ceux qui semblent les plus pertinents sont disponibles à http://www.psp-programming.com/tutorials/ En nous inspirant de ces présentations, nous allons commencer par développer une petite application simple affichant sur l’écran de la PSP la fractale de Mandelbrot (accès au mode graphique) et sauvant sur MS le résultat du calcul pour exploitation ultérieure. La fractale de Mandelbrot [5] est définie comme l’ensemble des points c dans le plan complexe pour lesquels l’itération de la suite zn+1=zn2+c (z0=c) ne diverge pas. Nous affichons pour chaque point c le nombre d’itérations, borné à un maximum de 16, au bout duquel la suite a été identifiée comme divergente (c.-à-d. la couleur du point c est n lorsque |zn|>2, pour n<17 – l’ensemble des points blancs sur la Fig. 2 présente donc les valeurs de c pour lesquelles la suite n’a pas divergé au bout de 16 itérations).

    Tableau 1 : Exemple de programme affichant la fractale de Mandelbrot et stockant sur MS les résultats du calcul. Aucune optimisation n’a été incluse dans ce code – qu’il s’agisse de l’affichage ou de l’algorithme de calcul – afin de le garder aussi lisible que possible : la durée d’exécution du calcul est de 37 secondes.

    Le Makefile associé au programme (Tab. 1) est présenté dans le Tab. 2 : il s’appelle, pour générer un exécutable pour firmware 1.5, par la commande make kxploit qui génère deux sous-répertoires, mandel et mandel% dans l’exemple qui nous intéresse ici (le nom de l’exécutable présenté par la PSP et des sous-répertoires associés sont définis par la variable PSP_EBOOT_TITLE du Makefile). Ces deux répertoires sont placés sur le MS dans le sous répertoire PSP/GAME afin d’être reconnus lors de leur exécution sur la PSP. Si plusieurs projets sont placés dans le même sous-répertoire, on prendra soin, avant chaque nouvelle compilation, d’effacer les objets et le fichier PARAM.SFO qui contient les paramètres de génération de l’exécutable EBOOT.PBP inclus dans ces répertoires.

    Tableau 2 : Fichier de configuration Makefile associé au programme présenté au Tab. 1.

    Nous utilisons pour l’accès au mode graphique une bibliothèque graphics.h disponible dans les exemples de http://www.freewebs.com/jason867/psphomebrew.htm Le principal intérêt de ce code réside dans la mise en évidence de l’adresse de la mémoire vidéo et la procédure à suivre pour y écrire (fonction PlotPixel()) ou en lire le contenu pour effectuer une capture d’écran.

    /img-articles/lm/92/cc-art-psp/fig-2.jpg

    Figure 2 : Capture d’écran du résultat de l’exécution du programme présenté au Tab. 1

    Nous constatons dans cet exemple que l’appel aux fonctions du système d’exploitation exécuté par la PSP implique un certain nombre de changements de nomenclature par rapport à l’ANSI C classique. Par exemple, l’ouverture de fichier habituelle par fopen() est remplacée par sceIoOpen() avec les mêmes arguments, et fclose() est remplacé par sceIoClose(). Le reste du code suit une syntaxe tout à fait classique par ailleurs. Une autre possibilité pour l’affichage en mode texte d’informations sur la PSP est l’utilisation du mode Debug : initialisé par la procédure pspDebugScreenInit();, il permet d’afficher des caractères ASCII au moyen de la fonction pspDebugScreenPrintf() qui accepte une liste d’arguments identique à celle dont nous avons l’habitude avec printf(). Nous utiliserons plus bas ce mode pour afficher les trames NMEA issues d’un récepteur GPS connecté à la PSP. 2 Disponible auprès de Lextronic, www.lextronic.fr, pour 83 euros TTC : http://www.lextronic.fr/laipac/tf30.htm

    4 Communication par le port série asynchrone

    Nous allons dépasser le cadre des tutoriaux sus-cités pour aborder les aspects d’accès aux ports de communication de la PSP, aspect le plus intéressant pour faire interagir la console avec le monde qui l’entoure. Nous avons présenté à plusieurs reprises dans ces pages [6, 7] des développements autour de récepteurs GPS OEM de coût raisonnable au vu de leurs performances. Cependant, un point délicat avec l’enregistrement en aveugle de trames GPS au cours d’un trajet est l’incapacité de vérifier en temps réel le bon fonctionnement du logiciel d’acquisition : rien n’est plus frustrant que de rentrer d’une longue randonnée et de se rendre compte qu’un élément du circuit d’acquisition n’a pas fonctionné correctement. Nous allons ici utiliser la PSP comme écran d’affichage des trames acquises, comme support de stockage de masse non volatile de secours pour conserver les traces du trajet, pour finalement combiner ces fonctionnalités avec l’acquisition géolocalisée de quantités physiques (dans le cas qui nous intéressera plus bas, la puissance radiofréquence reçue depuis des points d’accès wifi).

    /img-articles/lm/92/cc-art-psp/fig-3.jpg/img-articles/lm/92/cc-art-psp/fig-4.jpg

    Figure 3 : Gauche : montage connectant un GPS à une PSP. Les composants passifs ont pour vocation de protéger la PSP contre tout signal indésirable (la diode 1N4148 élimine tout risque d’appliquer un potentiel négatif sur la broche RxD, tandis que les deux LED en série limitent le potentiel appliqué à RxD à environ 3,4 V. La résistance en parallèle avec les deux LED permet alors au potentiel de RxD de redescendre lors du passage d’un bit 1 à un bit 0). Nous avons pu connecter un récepteur GPS Laipac PG31 (alimenté en 3,3 V et communiquant donc sur un signal haut à cette tension) sans composant passif de protection. Noter qu’un MAX(3)232 comporte non seulement une pompe de charge générant la tension négative nécessaire au protocole RS232, mais aussi des inverseurs : il ne suffit donc pas de connecter une diode pour faire communiquer un PC avec la PSP, mais en plus un inverseur. Droite : utilisation de ce montage pour afficher la position au cours d’un trajet en voiture.

    Le connecteur à 6 broches situé à côté de la prise de l’écouteur audio (en bas à gauche de la PSP) contient tous les signaux pour permettre une communication asynchrone compatible avec la norme RS232 [8]. Les niveaux des signaux sont entre 0 V et 2,5 V nominaux, compatibles avec un signal haut à 3,3 V. Nous allons connecter un récepteur GPS Laipac PG-312. La connexion ne nécessite aucune précaution particulière bien que nous ayons choisi de placer deux LED afin de protéger le port série de la PSP de tout risque de surtension (une diode Zener ferait le même effet). Une fiche capable de s’insérer dans l’emplacement prévu à côté du connecteur audio doit être réalisée : nous gravons pour ceci un circuit imprimé double-face (époxy FR4 de 1,6 mm d’épaisseur) avec 3 pistes de chaque côté, espacées de 1,5 mm et de 1 mm de largeur. Le lecteur n’ayant pas accès au matériel nécessaire pour graver un circuit imprimé pourra détruire une carte PCI pour en récupérer trois broches du connecteur prévu pour s’enficher dans une carte mère de PC (Fig. 5).

    Tableau 3 : Exemple de programme permettant de sélectionner la vitesse de communication du GPS sur son port RS232 (4800 bauds par défaut pour le Laipac PG-31), puis d’afficher les trames NMEA brutes issues du récepteur, ou de traiter ces trames pour en extraire latitude et longitude pour restituer les informations de façon graphique.

    Un exemple de code minimaliste permettant de capturer les trames sur le port série et de les afficher est disponible à http://forums.ps2dev.org/viewtopic.php?t=6294 On y trouve l’initialisation de la vitesse de transfert par la commande pspDebugSioSetBaud(38400); que nous adaptons à nos propres besoins. Nous observons cependant que ce code contient une boucle de taille prédéfinie qui ne saurait convenir pour une application générale. Nous allons donc remplacer cette boucle par une condition de boucle infinie (while (1) { ...}) et conditionner la sortie de cette boucle par l’appui d’un bouton sur la PSP. Cependant, l’utilisation de la fonction bloquante d’interrogation des touches sceCtrlReadBufferPositive() pour détecter l’appui d’une touche que nous associerions à l’arrêt du programme est trop lente et nous fait perdre des caractères. La solution qui nous a semblé appropriée est l’appel à la fonction non bloquante sceCtrlPeekBufferPositive() qui – n’étant pas bloquante jusqu’au prochain rafraîchissement de l’écran – nous permet d’interrompre proprement le programme (par appel à la fonction sceKernelExitGame();) sans perdre de caractère transmis par le port série. Nous profitons de la gestion de l’appui des touches pour proposer la translation de l’origine de la carte affichée à l’écran, l’effacement ou la capture d’écran (Fig. 4).

    /img-articles/lm/92/cc-art-psp/fig-42.jpg

    Figure 4 : Captures d’écrans obtenues lors de l’acquisition de traces en voiture (gauche : du péage de Saint-Arnould au sud de Paris au bois de Boulogne à Paris) et à pied (droite : Jardin de Bagatelle, Paris). L’image de gauche a été recentrée en cours d’acquisition au moyen des flèches de direction à mi-hauteur alors que la trace allait sortir de l’écran : les points blancs indiquent le pas de translation lors du recentrage de la trace.

    Il apparaît à l’usage que les fichiers créés pour les sauvegardes sur MS ne sont créés qu’au moment de leur fermeture. Cela signifie que les données accumulées ne sont réellement stockées que lors de la fermeture du fichier, c’est-à-dire à la fin d’une séance d’acquisition de données. Aucune solution satisfaisante n’a pour le moment été identifiée pour conserver les données en cours d’utilisation du programme, avant de quitter proprement et de fermer le fichier (sceIoClose() qui se comporte exactement comme l’habituel fclose()). Il ne semble pas exister de fonction pour vider les tampons (fonction fflush() classiquement) sur PSP. L’ensemble des fonctions spécifiques au PSP SDK sont décrites à http://psp.jim.sh/pspsdk-doc/ Nous sommes donc capables, à ce stade d’avancement, de capturer des informations sur le port série et de les afficher soit en mode texte, soit en mode graphique (Fig. 4), sur l’écran de la PSP. Il nous reste maintenant à encoder, dans la couleur de chaque point, l’évolution spatiale d’une quantité physique mesurée au cours du trajet.

    5 Utilisation de l’interface wifi

    Nous avons donc démontré notre capacité à interfacer un récepteur GPS à une PSP pour afficher le trajet parcouru, et éventuellement de conserver en mémoire non volatile les latitudes et longitudes échantillonnées toutes les secondes. La PSP est par ailleurs équipée d’une interface wifi : quoi de plus naturel donc que de combiner la fonction de géolocalisation avec la capacité à écouter et identifier tous les points d’accès wifi à proximité (wardriving et warwalking) [9].

    /img-articles/lm/92/cc-art-psp/fig-5.jpg

    Figure 5 : Montage minimal pour géopositionner les points d’accès wifi au moyen de la PSP. Dans ce cas, le connecteur entre le GPS et la PSP a été réalisé au moyen d’un bout de carte PCI (connecteur s’enfichant normalement sur la carte mère d’un PC).

    La mise en œuvre de l’interface wifi de la PSP n’est pas aisée et nécessite l’appel à des fonctions du firmware fourni par Sony et identifiées par reverse engineering [10]. La structure de données retournée par ces fonctions contient – pour un maximum de 32 points d’accès – des informations telles que les identifiants (BSSID et nom du point d’accès), la puissance reçue (RSSI, Received Signal Strength Indication) ou le mode d’encryption des trames. L’excellent exemple mis à disposition avec le PSPSDK dans le répertoire samples/wlanscan_elf nous fournit en fait pratiquement toutes les fonctionnalités dont nous avons besoin, et il nous suffit de joindre ce programme avec celui présenté précédemment pour réaliser une application de cartographie des points d’accès échantillonnés toutes les secondes (Fig. 5). Nous avons choisi de présenter en temps réel le trajet parcouru et le nombre de points d’accès vus est codé dans la couleur du point affiché (mode graphique), ou alternativement les coordonnées de la position et les identifiants des points d’accès vus (Tab. 4).

    Tableau 4 : Exemple de fichier acquis à pied avec un échantillonnage toutes les secondes, présentant la position GPS – sous forme de trames ASCII brutes extraites de la transmission RS232 (format degrés, minutes et fractions de minutes) et après conversion au format degrés + fractions de degrés (validant ainsi le bon fonctionnement de la bibliothèque mathématique et du calcul flottant) – associée aux points d’accès wifi visibles identifiés dans l’ordre par la puissance reçue, le BSSID et le nom.

    Cette présentation de l’interfaçage d’un GPS avec la PSP ne saurait être complète sans une mention au travail de développement associé à l’application Map This! disponible à http://deniska.dcemu.co.uk/ Il ne nous a malheureusement pas encore été possible de faire fonctionner ce programme avec le PG31.

    /img-articles/lm/92/cc-art-psp/fig-6.jpg

    Figure 6 : Gauche : copie d’écran d’une trace acquise au cours d’un trajet à pied entre le bois de Boulogne et le Jardin d’Acclimatation (Paris). L’intensité de gris indique le nombre de points d’accès wifi identifiés pour chaque point GPS de la trace (échantillonnage toutes les secondes). Plus le point est clair, moins il y a de points d’accès wifi détectés. Nous constatons clairement que le nombre de points d’accès augmente lorsqu’on s’approche des quartiers résidentiels (nord) pour s’annuler dans le parc (sud). Droite : vue aérienne de la même zone. Dans cette seconde vue, l’absence de point d’accès wifi se traduit par un point vert clair qui devient d’autant plus rouge que le nombre de points d’accès détectés est élevé.

    Conclusion

    Nous avons présenté la console de jeu Sony PlayStation Portable comme une plate-forme de développement d’applications embarquées alliant une puissance de calcul intéressante, une bonne autonomie pour un prix inférieur aux systèmes industriels équivalents. Nous avons présenté les modifications logicielles à effectuer sur la console pour la rendre apte à exécuter nos programmes (flasher un nouveau firmware), et la méthode pour installer les outils de cross-compilation sous GNU/Linux. Nous avons ensuite illustré notre capacité à écrire un programme fonctionnel en mode graphique par l’affichage de la fractale de Mandelbrot, pour ensuite aborder les aspects d’interfaçage de matériel sur le port de communication asynchrone compatible RS232. L’application finale est un outil de géolocalisation des points d’accès wifi. Nous avons vu que le PSP SDK, basé sur gcc compilé à destination d’une architecture MIPS, nous fournit une interface de développement très proche du C classiquement utilisé pour développer des applications sous GNU/Linux. Cependant, l’utilisation intensive des fonctions fournies par le firmware propriétaire de Sony pour accéder aux fonctions bas niveau et au matériel induit certaines différences et signifie que toutes les fonctions habituellement accessibles à un programme C ne sont pas (encore) nécessairement implémentées sur PSP. Rérérences
    Vous souhaitez commenter cet article ?
    Brèves Flux RSS
    Édito : GNU/Linux Magazine N°170
    Édito : GNU/Linux Magazine Hors-Série N°71
    Édito : MISC N°72
    Édito : Open Silicium N°10
    Édito : GNU/Linux Magazine N°169
    Communication RSS Com. RSS Presse
    HACKITO ERGO SUM
    GNU/Linux Magazine, partenaire du SymfonyLive Paris
    Opensilicium, partenaire de RTS EMBEDDED
    Linux Pratique et Linux Essentiel, Partenaire de l’Open World Forum
    Gnu/Linux Magazine, Partenaire des JDEV 2013
    Rechercher un article dans notre base documentaire :
    En kiosque Flux RSS

    Le tout nouveau GNU/Linux Magazine est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau GNU/Linux Magazine HS est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Misc est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Open Silicium est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Linux Pratique est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...