2010-11-11 34 views
0

Est-il possible d'exécuter 2 programmes C différents (c'est-à-dire 2 principaux()), stockés dans Flash (micro-contrôleur), un à la fois?Deux programmes différents en Flash

J'ai un code de bootloader qui est un programme séparé et réside dans une section protégée séparée de ROM. Ensuite, j'ai mon programme d'application qui réside dans une section ROM séparée. Bien que demeurer en mémoire ne soit pas un problème, mais comment l'éditeur de liens interprétera-t-il cela? Comment puis-je basculer entre 2 programmes. Est-ce possible?

Par exemple: Une fois que j'ai terminé avec le chargeur de démarrage, je peux le faire passer à la fonction Application, mais comment l'éditeur de liens connaîtra-t-il cette fonction? Pour ajouter, j'utilise la série Freescale HCS08 et IDE est Codewarrior.

En outre, voici la séquence d'étapes: Je charge un code Bootloader en ROM. Ensuite, ce code de bootloader est nécessaire pour charger mon code d'application. Et puis mon code d'application devrait prendre le relais.

Code Bootloader: Programme Domaine d'application ROM Application Program Début

Code d'application: Vérifiez si d'exécuter du code Bootloader ou de l'application elle-même.

+0

Je pense que la réponse, si possible, sera spécifique au micro-contrôleur. Fournissez votre puce cible et vous aurez une meilleure chance d'obtenir une réponse. – nathan

Répondre

0

La façon dont j'ai vu cela fait est de coller le point d'entrée dans un en-tête pour l'application. Ensuite, demandez au chargeur de démarrage de retirer ce point d'entrée et de sauter dessus avec une instruction d'assemblage en ligne appropriée. Vous pouvez avoir besoin d'un script d'éditeur de liens pour obtenir le point d'entrée lui-même depuis l'application. Gnu ld utilise ENTRY.

+0

pouvez-vous s'il vous plaît expliquer plus loin que j'ai deux _Entrypoints, un pour bootloader et un autre pour l'application. – Punit

+0

@punit: Les deux programmes sont liés de manière indépendante et le point d'entrée de la seconde est inséré dans un en-tête que le premier lit. – nmichaels

1

Main est juste une fonction. Vous pouvez le renommer et écrire un autre principal qui appelle l'un d'entre eux.

Si vous ne voulez pas renommer principale dans la source que vous pouvez mutiler son nom par définir ou clé du compilateur:

cc -Dmain=main1 ... 

(pour le premier programme), et

cc -Dmain=main2 ... 

(pour la deuxième). Sélecteur principal:

int main(void) { 
    if(x) return main1(); 
    else return main2(); 
} 

Puis reliez tous ensemble et téléchargez sur votre contrôleur.

Mais il y a un problème avec les ISR: vous ne pouvez pas assigner deux routines à un seul vecteur irq. Si les vecteurs sont codés en dur dans un emplacement flash (comme dans la plupart des contrôleurs 8 bits), vous ne pouvez pas changer les ISR. Vous devrez écrire un wrapper ISR, en reconnaissant quel programme est exécuté et en appelant ISR approprié.

UPD deuxième question est que les variables liées statiquement de la première et deuxième programme seront en RAM simultanément tout en un seul ensemble d'entre eux est utilisé. Cela peut épuiser la RAM (dont une petite partie existe souvent dans le microcontrôleur) trop tôt.

UPD2 Oh, maintenant je comprends vraiment. Si vous souhaitez les lier et les télécharger séparément, vous devez traiter les cartes de liens. Dans ce cas, les mêmes noms de symboles (comme beaucoup de main) ne sont pas un problème. Dans la carte de l'éditeur de liens, vous devez définir le point d'entrée connu [définir l'adresse absolue], à partir duquel l'un des codes d'application commence.Le code de démarrage (généralement le code d'assemblage) doit être lié à cette adresse. À partir du sélecteur, vous devez décider et accéder directement à l'emplacement défini. (Ne le faites que pour le chargeur de démarrage si votre application est également un sélecteur).

Point d'entrée fourni par liaison peut être accessible par le programme en fonction extern:

int app2_start(void); 

{ 
    .... /* condition check */ 
    app2_start(); /* this symbol defined in linker map, not in any source */ 
} 

Mais ce n'est pas l'adresse de celui-ci est principale, parce que C RTL() ont ne font beaucoup initialisations (pile, les variables initialisées , tas, IO, etc.) avant que main() puisse commencer.

Il est plus courant que le bootloader décide, s'il s'exécute lui-même ou application, car si le code de l'application échoue, le chargeur de bood peut devenir inaccessible.

+0

Merci pour votre contribution. Eh bien, je pense qu'il n'y aurait pas de problème avec les vecteurs, car je les ai gardés au même endroit pour le code Bootloader et le code de l'application. Et à la fois, le code de l'application sera exécuté ou le code du bootloader. Donc, les ISR sont sûrs ?? – Punit

+0

Non, les ISR ne sont pas sécurisés ici. Cette approche en fait essentiellement un programme avec deux fonctions. – nmichaels

+0

ISR serait aussi sûr que vous les écrivez. J'ai seulement déclaré que vous ne pouvez probablement pas avoir deux ISR différents pour un seul vecteur. Est-ce la même chose pour les deux programmes? Ce n'est pas un problème. – Vovanium