Opzione 1: lingue interpretate
Questo non risponde direttamente alla domanda (che è un'ottima domanda, a proposito, e spero di imparare da una risposta che la indirizzi direttamente), ma è molto comune quando si realizzano progetti che possono caricare programmi esterni in cui scrivere i programmi esterni un linguaggio interpretato. Se le risorse sono limitate (quali saranno su questo processore, hai pensato di utilizzare un PIC32 o un piccolo processore ARM per questo?), È comune limitare la lingua a un sottoinsieme della specifica completa. Ancora più in basso nella catena sono linguaggi specifici di dominio che fanno solo alcune cose.
Ad esempio, il progetto elua è un esempio di linguaggio interpretato a bassa risorsa (64 kB RAM). Puoi comprimerlo fino a 32k di RAM se rimuovi alcune funzionalità (Nota: non funzionerà sul tuo attuale processore, che è un'architettura a 8 bit. L'uso della RAM esterna sarà probabilmente troppo lento per la grafica). Fornisce un linguaggio veloce e flessibile in cui i nuovi utenti potrebbero programmare facilmente i giochi se si fornisce un'API minima. C'è molta documentazione disponibile per la lingua online. Ci sono altre lingue (come Forth e Basic) che potresti usare in modo simile, ma penso che Lua sia l'opzione migliore al momento.
Allo stesso modo, potresti creare il tuo linguaggio specifico per il dominio. Dovresti fornire un'API più completa e una documentazione esterna, ma se i giochi fossero tutti simili, non sarebbe troppo difficile.
In ogni caso, il PIC18 probabilmente non è il processore che userei per qualcosa che coinvolge programmazione / scripting e grafica personalizzati. Potresti avere familiarità con questa classe di processori, ma suggerirei che sarebbe un buon momento per usare qualcosa con un driver dello schermo e più memoria.
Opzione 2: basta riprogrammare il tutto
Se, tuttavia, stai già programmando di programmare tutti i giochi da solo in C, non preoccuparti di caricare solo la logica di gioco dalla scheda SD. Hai solo 32kB di Flash da riprogrammare e potresti facilmente ottenere una scheda microSD da 4 GB per questo. (Nota: le schede più grandi sono spesso SDHC, che è più difficile da interfacciare). Supponendo che tu usi ogni ultimo byte del tuo 32 kB, che lasci spazio sulla scheda SD per 131.072 copie del tuo firmware con qualsiasi logica di gioco ti serva.
Esistono molte note per scrivere bootloader per PIC, come AN851 . Dovresti progettare il tuo bootloader per occupare un'area specifica di memoria (probabilmente la parte superiore dell'area di memoria, specificala nel linker) e specifica che i progetti firmware completi non raggiungono questa area. L'appnote lo spiega in modo più dettagliato. Sostituisci semplicemente "Sezione di avvio del PIC18F452" con "Sezione di avvio specificata nel linker" e tutto avrà senso.
Quindi, il tuo bootloader deve solo consentire all'utente di selezionare un programma da eseguire dalla scheda SD e copiare il tutto. Un'interfaccia utente potrebbe essere che l'utente deve tenere premuto un pulsante per accedere alla modalità di selezione. Di solito, il bootloader controlla semplicemente lo stato di questo pulsante al ripristino e, se non viene tenuto premuto, si avvia nel gioco. Se viene tenuto premuto, dovrebbe consentire all'utente di scegliere un file sulla scheda SD, copiare il programma e continuare l'avvio nel [nuovo] gioco.
Questa è la mia attuale raccomandazione.
Opzione 3: Magia profonda che coinvolge la memorizzazione di solo una parte del file esadecimale
Il problema con il meccanismo previsto è che il processore non si occupa delle API e delle chiamate di funzione, si occupa di numeri - indirizzi ai quali il puntatore dell'istruzione può saltare e si aspetta che ci sia un codice che esegue una chiamata di funzione secondo una specifica API. Se provi a compilare solo una parte del programma, il linker non saprà cosa fare quando chiami check_button_status()
o toggle_led()
. Potresti sapere che quelle funzioni esistono nel file esadecimale sul processore, ma deve sapere esattamente a quale indirizzo risiedono.
Il linker già suddivide il codice in più sezioni; potresti teoricamente suddividerlo in sezioni aggiuntive con alcuni -section
e #pragma
incantesimi. Non l'ho mai fatto e non so come. Fino a quando i due metodi precedenti non mi mancheranno (o qualcuno pubblicherà una risposta fantastica qui), probabilmente non imparerò questo meccanismo e quindi non posso insegnartelo.