Opção 1: Idiomas Interpretados
Isso não responde diretamente à pergunta (que é uma excelente pergunta, BTW, e espero aprender com uma resposta que a aborda diretamente), mas é muito comum ao executar projetos que podem carregar programas externos para escrever programas externos em uma linguagem interpretada. Se os recursos forem escassos (que estarão neste processador, você já pensou em usar um PIC32 ou um pequeno processador ARM para isso?), É comum restringir o idioma a um subconjunto da especificação completa. Ainda mais abaixo, estão linguagens específicas de domínio que fazem apenas algumas coisas.
Por exemplo, o projeto elua é um exemplo de uma linguagem interpretada com poucos recursos (64 kB de RAM). Você pode compactar isso para 32k de RAM se remover alguns recursos (Nota: ele não funcionará no seu processador atual, que é uma arquitetura de 8 bits. O uso de RAM externa provavelmente será muito lento para gráficos). Ele fornece uma linguagem rápida e flexível na qual novos usuários podem programar jogos facilmente se você fornecer uma API mínima. Há muita documentação disponível para o idioma online. Existem outras linguagens (como Forth e Basic) que você pode usar de maneira semelhante, mas acho que Lua é a melhor opção no momento.
Da mesma forma, você pode criar seu próprio idioma específico do domínio. Você precisaria fornecer uma API mais completa e documentação externa, mas se os jogos fossem todos semelhantes, isso não seria muito difícil.
De qualquer forma, o PIC18 provavelmente não é o processador que eu usaria para algo que envolve programação / script e gráficos personalizados. Você pode estar familiarizado com essa classe de processadores, mas eu sugiro que esse seja um bom momento para usar algo com um driver de vídeo e mais memória.
Opção 2: basta reprogramar a coisa toda
Se, no entanto, você já planeja programar todos os jogos em C, não se preocupe em carregar apenas a lógica do jogo no cartão SD. Você tem apenas 32kB de Flash para reprogramar e pode facilmente obter um cartão microSD de 4 GB para isso. (Nota: cartões maiores costumam ser SDHC, o que é mais difícil de interface). Supondo que você use cada último byte dos seus 32 kB, isso deixa espaço no cartão SD para 131.072 cópias do seu firmware com a lógica do jogo que você precisa.
Existem várias notas de app para escrever gerenciadores de inicialização para PICs, como o AN851 . Você precisaria projetar seu carregador de inicialização para ocupar uma região específica da memória (provavelmente a parte superior da região da memória, você especificaria isso no vinculador) e especificar que os projetos completos de firmware não atinjam essa região. A nota explicativa explica isso em mais detalhes. Apenas substitua "Seção de inicialização do PIC18F452" por "Seção de inicialização especificada no vinculador" e tudo fará sentido.
Em seguida, o seu carregador de inicialização precisa apenas permitir que o usuário selecione um programa para executar no cartão SD e copie tudo. Uma interface do usuário pode ser que o usuário mantenha pressionado um botão para entrar no modo de seleção. Normalmente, o gerenciador de inicialização apenas verifica o status desse botão na redefinição e, se não estiver sendo pressionado, inicia o jogo. Se mantida pressionada, seria necessário permitir ao usuário escolher um arquivo no cartão SD, copiar o programa e continuar a inicializar no [novo] jogo.
Esta é a minha recomendação atual.
Opção 3: Magia profunda envolvendo o armazenamento de apenas parte do arquivo hexadecimal
O problema com o mecanismo previsto é que o processador não lida com APIs e chamadas de função, lida com números - endereços para os quais o ponteiro de instruções pode saltar e espera que haja código que execute uma chamada de função de acordo com uma especificação da API. Se você tentar compilar apenas uma parte do programa, o vinculador não saberá o que fazer quando você ligar check_button_status()
ou toggle_led()
. Você pode saber que essas funções existem no arquivo hexadecimal do processador, mas precisa saber exatamente em que endereço elas residem.
O vinculador já divide seu código em várias seções; teoricamente, você poderia dividir isso em seções adicionais com alguns -section
e #pragma
encantamentos. Eu nunca fiz isso e não sei como. Até que os dois métodos acima falhem comigo (ou alguém poste uma resposta incrível aqui), provavelmente não aprenderei esse mecanismo e, portanto, não posso ensiná-lo.