Option 1: Langues interprétées
Cela ne répond pas directement à la question (qui est une excellente question, BTW, et j'espère apprendre d'une réponse qui la traite directement), mais c'est très courant lorsque vous faites des projets qui peuvent charger des programmes externes pour écrire les programmes externes dans un langage interprété. Si les ressources sont limitées (ce qu'elles seront sur ce processeur, avez-vous pensé à utiliser un PIC32 ou un petit processeur ARM pour cela?), Il est courant de restreindre la langue à un sous-ensemble de la spécification complète. Plus loin dans la chaîne se trouvent des langages spécifiques au domaine qui ne font que peu de choses.
Par exemple, le projet elua est un exemple de langage interprété à faibles ressources (64 Ko de RAM). Vous pouvez réduire cela à 32 Ko de RAM si vous supprimez certaines fonctionnalités (Remarque: cela ne fonctionnera pas sur votre processeur actuel, qui est une architecture 8 bits. L'utilisation de la RAM externe sera probablement trop lente pour les graphiques). Il fournit un langage rapide et flexible dans lequel les nouveaux utilisateurs pourraient facilement programmer des jeux si vous fournissez une API minimale. Il y a beaucoup de documentation disponible pour la langue en ligne. Il existe d'autres langues (comme Forth et Basic) que vous pourriez utiliser de la même manière, mais je pense que Lua est la meilleure option pour le moment.
Dans la même veine, vous pouvez créer votre propre langage spécifique au domaine. Vous devrez fournir une API plus complète et une documentation externe, mais si les jeux étaient tous similaires, cela ne serait pas trop difficile.
Dans tous les cas, le PIC18 n'est probablement pas le processeur que j'utiliserais pour quelque chose qui implique une programmation / un script et des graphiques personnalisés. Vous connaissez peut-être cette classe de processeurs, mais je dirais que ce serait le bon moment pour utiliser quelque chose avec un pilote d'affichage et plus de mémoire.
Option 2: reprogrammer le tout
Si, cependant, vous prévoyez déjà de programmer tous les jeux vous-même en C, ne vous embêtez pas à charger uniquement la logique du jeu à partir de la carte SD. Vous n'avez que 32 Ko de Flash à reprogrammer et pourriez facilement obtenir une carte microSD de 4 Go pour cela. (Remarque: les cartes plus grandes sont souvent SDHC, ce qui est plus difficile à interfacer). En supposant que vous utilisez le dernier octet de votre 32 Ko, cela laisse de la place sur la carte SD pour 131 072 copies de votre firmware avec la logique de jeu dont vous avez besoin.
Il existe de nombreuses annexes pour écrire des chargeurs de démarrage pour les PIC, comme AN851 . Vous devez concevoir votre chargeur de démarrage pour occuper une région spécifique de la mémoire (probablement le haut de la région de la mémoire, vous devez le spécifier dans l'éditeur de liens) et spécifier que les projets de micrologiciel complets n'atteignent pas cette région. L'annexe le précise plus en détail. Il suffit de remplacer "Section de démarrage du PIC18F452" par "Section de démarrage que je spécifie dans l'éditeur de liens" et tout cela aura du sens.
Ensuite, votre chargeur de démarrage doit simplement permettre à l'utilisateur de sélectionner un programme à exécuter à partir de la carte SD et de copier le tout. Une interface utilisateur pourrait être que l'utilisateur doit maintenir enfoncé un bouton-poussoir pour entrer dans le mode de sélection. Normalement, le chargeur de démarrage vérifie simplement l'état de ce bouton lors de la réinitialisation et, s'il n'est pas maintenu enfoncé, démarre le jeu. S'il est maintenu enfoncé, il devrait permettre à l'utilisateur de choisir un fichier sur la carte SD, de copier le programme et de continuer à démarrer dans le [nouveau] jeu.
Ceci est ma recommandation actuelle.
Option 3: magie profonde impliquant de ne stocker qu'une partie du fichier hexadécimal
Le problème avec votre mécanisme envisagé est que le processeur ne traite pas des API et des appels de fonction, il traite des nombres - adresses auxquelles le pointeur d'instruction peut sauter et s'attendre à ce qu'il y ait du code qui exécute un appel de fonction selon une spécification d'API. Si vous essayez de compiler juste une partie du programme, l'éditeur de liens ne saura pas quoi faire lorsque vous appelez check_button_status()
ou toggle_led()
. Vous savez peut-être que ces fonctions existent dans le fichier hexadécimal du processeur, mais il doit savoir précisément à quelle adresse elles résident.
L'éditeur de liens divise déjà votre code en plusieurs sections; vous pourriez théoriquement diviser cela en sections supplémentaires avec des incantations -section
et certains #pragma
. Je ne l'ai jamais fait et je ne sais pas comment. Jusqu'à ce que les deux méthodes ci-dessus me manquent (ou que quelqu'un poste une réponse impressionnante ici), je n'apprendrai probablement pas ce mécanisme et je ne peux donc pas vous l'enseigner.