Exécution de Code dans les systèmes embarqués
Je suis en train de travailler dans le système intégré de domaine. Je voudrais savoir comment un code est exécuté à partir d'un microcontrôleur(uC n'a pas besoin d'être subjective, en général), à partir d'un fichier C. Aussi je voudrais savoir animaux comme le code de démarrage, le fichier d'objet, etc. Je ne pourrais pas le trouver en ligne les documentations concernant les trucs ci-dessus. Si possible, veuillez fournir des liens qui explique les choses à partir de zéro. Merci d'avance pour votre aide
Il serait utile d'indiquer quel type de microcontrôleur.
Travaille dans 8051 contrôleur. je sais un peu comment les opcodes sont récupérées et exécuté en langage d'assemblage). mais je voudrais savoir comment faire un projet avec plusieurs C fichiers s'exécute sur une uC.
le C fichiers n'exécutent pas les! 🙂 Ils sont compilés en fichiers objets, et lié à un exécutable final de l'image, qui est chargé soit de flash ou de la RAM et de l'exécuter à partir de là.
Travaille dans 8051 contrôleur. je sais un peu comment les opcodes sont récupérées et exécuté en langage d'assemblage). mais je voudrais savoir comment faire un projet avec plusieurs C fichiers s'exécute sur une uC.
le C fichiers n'exécutent pas les! 🙂 Ils sont compilés en fichiers objets, et lié à un exécutable final de l'image, qui est chargé soit de flash ou de la RAM et de l'exécuter à partir de là.
OriginalL'auteur inquisitive | 2009-09-02
Vous devez vous connecter pour publier un commentaire.
Être un microprocesseur architecte, j'ai eu l'occasion de travailler à un niveau très bas pour logiciel. Fondamentalement, le faible niveau intégré est très différent de général de programmation PC uniquement au matériel spécifique.
De bas niveau logiciel embarqué peut être décomposé en:
main()
. edit: les Variables qui doivent être initialisées et aussi dans certaines parties de la mémoire qui ont besoin de compensation sont faits ici. En gros, tout ce qui est nécessaire pour faire bouger les choses dans un 'état'.main()
fonction. Comme vous pouvez le voir, beaucoup de choses sont en fait sous le capot et se produire avant même votre première et principale fonction est appelée. Ce code peut généralement être écrit comme indépendant du matériel si il y a une bonne la couche d'abstraction matérielle disponibles. Le code de l'application va certainement faire usage de beaucoup de fonctions de la bibliothèque. Ces bibliothèques sont généralement liés statiquement dans les systèmes embarqués.Espère que ce sera un bon début. N'hésitez pas à laisser des commentaires si vous avez d'autres requêtes.
exécution se produit par l'exécution de chaque instruction de flash." Certains processeurs courir le code directement à partir de flash et d'autres pas. Je crois que le 8051 va exécuter le code à partir de flash. Extrémité supérieure (32 bits)des processeurs embarqués, comme un PC de copier le code de l'application dans la mémoire vive et de l'exécuter à partir de la RAM.
Étape 2 sera aussi configurer les variables statiques dans la mémoire RAM et de copier les données d'initialisation de trop.
oui, c'est généralement le cas. Parfois, un compilateur drapeau peut contrôler les choses comme point zéro .sev et ce démunis.
Je voudrais vous répondre sybreon, mais (dans le point 2) je ne pense pas que C suppose, il y aura un tas. De nombreux embedded c compilateurs préallouer de la mémoire pour les variables statiques et les allouer de l'espace pour les variables locales dans la pile. Dans ce cas, le tas n'entrerait en jeu si vous avez été en utilisant des bibliothèques avec malloc(). Pas sûr que le C++ constructeurs.
OriginalL'auteur sybreon
En général, vous travaillez beaucoup niveau inférieur à celui des ordinateurs à usage général.
Chaque CPU ont un certain comportement sur le pouvoir en place, tels que l'effacement de tous les registres et le réglage du compteur de programme pour 0xf000 (tout est ici non spécifiques, comme l'est votre question).
L'astuce est de s'assurer que votre code est à la bonne place.
Le processus de compilation est généralement semblable à usage général, les ordinateurs que vous traduisez C en code machine (fichiers objets). À partir de là, vous devez lier le code avec:
Système de démarrage de code, en général, juste initialise le matériel et met en place l'environnement de sorte que votre code C peut travailler. Bibliothèques d'exécution dans les systèmes embarqués font souvent les gros trucs encombrants (comme à virgule flottante de soutien ou de printf) en option afin de réduire code de la météorisation.
L'éditeur de liens dans les systèmes embarqués aussi, généralement, c'est beaucoup plus simple, de la sortie d'emplacement fixe mais plutôt à un code relogeable binaires. Vous pouvez l'utiliser pour assurer le démarrage de code de passe (par exemple) 0xf000.
Dans les systèmes embarqués, en général, vous voulez que le code exécutable d'être là dès le début de sorte que vous pouvez graver dans l'EPROM (ou EEPROM ou Flash ou un autre dispositif qui maintient le contenu sur puissance-vers le bas).
Bien sûr, gardez à l'esprit de ma dernière incursion était avec 8051 et 68302 processeurs. Il se peut que "embarqué" systèmes sont aujourd'hui complète de boîtes de Linux avec toutes sortes de merveilleux matériel, auquel cas il n'y aurait pas de réelle différence entre l'usage général et intégré.
Mais j'en doute. Il y a toujours un besoin pour un bas au sérieux-spec matériel qui a besoin de personnalisé les systèmes d'exploitation et/ou le code de l'application.
SPJ Technologies Embarquées a un téléchargeable à l'évaluation de leur 8051 environnement de développement qui semble être ce que vous voulez. Vous pouvez créer des programmes jusqu'à 2K en taille, mais il semble aller à travers l'ensemble du processus (de la compilation de la liaison, de la génération de l'hexagone ou les fichiers BIN pour le dumping sur le matériel cible, même un simulateur qui permet d'accéder à la sur-puce de trucs et de périphériques externes).
La non-évaluation des coûts des produits 200 Euros mais, si tout ce que vous voulez, c'est un peu un jeu, que je venais de télécharger l'évaluation - autres que la limite de 2K, c'est le produit complet.
OriginalL'auteur paxdiablo
J'ai l'impression que vous êtes le plus intéressé dans ce sybreon appelle "l'étape 2." Beaucoup peut arriver, et qu'il varie considérablement selon la plate-forme. Habituellement, ce genre de choses est gérée par une combinaison de chargeur de démarrage, support de la carte du paquet, Runtime C (CRT), et si vous en avez, le système d'exploitation.
En général, après que le vecteur de reset, une sorte de bootloader va exécuter à partir de flash. Ce bootloader peut-il suffit de configurer le matériel et le saut dans votre application CRT, aussi en flash. Dans ce cas, le CRT serait probablement désactiver l' .sev, copiez le .les données de la RAM, etc. Dans d'autres systèmes, le chargeur de démarrage peut scatter-chargement de l'application à partir d'un fichier codé, comme un ELFE, et le CRT seulement met en place d'autres d'exécution des trucs (tas, etc.). Tout cela se passe avant le CRT appelle l'application du main().
Si votre application est lié statiquement, l'éditeur de liens directives permet de spécifier les adresses où .de données/.bss et la pile sont initialisés. Ces valeurs sont liées à la CRT ou codés dans le format ELF. Dans une dynamique liée environnement, de l'application de chargement est généralement géré par un système d'exploitation qui re-cibles de l'ELFE à courir dans toute la mémoire de l'OS désigne.
Aussi, certains objectifs d'exécuter des applications à partir de flash, mais d'autres vont copier le fichier exécutable .texte de flash de RAM. (C'est généralement une vitesse/empreinte de compromis, car la RAM est plus rapide/plus large que flash sur la plupart des cibles.)
OriginalL'auteur Casey Barker
Ok, je vais donner un coup de cette...
Tout d'abord les architectures. Von Neumann contre de Harvard. Harvard l'architecture est séparée de la mémoire pour le code et les données. Von Neumann n'a pas. Harvard est utilisé dans de nombreux microcontrôleurs et c'est ce que je suis familier avec.
Afin de commencer avec votre base de Harvard architecture que vous avez de la mémoire de programme. Lorsque le microcontrôleur démarre pour la première fois, il exécute les instructions à l'emplacement de la mémoire à zéro. Habituellement, c'est un SAUT de commande de l'adresse où le code principal commence.
Maintenant, quand je dis instructions que je veux dire opcodes. Les Opcodes sont des instructions codées en binaire de données, généralement 8 ou 16 bits. Dans certaines architectures chaque opcode est codé en dur à dire des choses précises, dans d'autres, chaque bit peut être importante (c'est à dire, bit à 1 signifie transporter les bagages, 2 bits signifie vérifier l'indicateur de zéro, etc). Il y a donc des opcodes et ensuite les paramètres pour les opcodes. Une instruction de SAUT est un opcode et un 8 ou 16 ou 32 bits de l'adresse de mémoire dont le code "sauts". C'est à dire, le contrôle est transféré à les instructions à cette adresse. Il accomplit cela en manipulant un registre spécial qui contient l'adresse de la prochaine instruction à être exécutée. Donc pour passer à l'emplacement de la mémoire 0x0050 il serait de remplacer le contenu de ce registre avec 0x0050. Sur le prochain cycle d'horloge, le processeur va lire le registre et localiser l'adresse de la mémoire et exécuter l'instruction.
L'exécution des instructions provoque des changements dans l'état de la machine. Il y a un registre qui enregistre des informations sur ce que la dernière commande n'a (c'est à dire, si c'est un plus, alors si il y avait un porter, il y est un peu pour ça, etc). Il y a un "accumulateur" registre où le résultat de l'instruction est placé. Les paramètres pour obtenir des instructions pouvez soit aller dans un ou plusieurs registres, ou de l'accumulateur, ou dans les adresses mémoire (de données OU de programme). Les différents opérateurs peuvent uniquement être exécutées sur les données à certains endroits. Par exemple, vous pourriez être en mesure d'AJOUTER des données à partir de deux registres et avoir le résultat s'afficher dans l'accumulateur, mais vous ne pouvez pas prendre de données à partir des données de deux emplacements de mémoire et d'avoir le résultat s'afficher dans un autre emplacement de mémoire. Vous auriez à déplacer les données que vous souhaitez les registres, faire l'addition, puis déplacez le résultat dans l'emplacement de mémoire souhaité. C'est pourquoi l'assemblée est considérée comme difficile. Il y a autant de registres de l'état que l'architecture est conçue pour. Plus d'architectures complexes peuvent avoir plus de permettre à des commandes plus complexes. Plus simples peuvent pas.
Il existe également une zone de mémoire de la pile. C'est juste une zone de mémoire pour certains microcontrôleurs (comme le 8051). Dans d'autres, il peut avoir des protections spéciales. Il existe un registre appelé pointeur de pile qui enregistre ce que l'emplacement de la mémoire le sommet de la pile est à. Lorsque vous "pousser" quelque chose sur la pile à partir de l'accumulateur alors le 'top' adresse de mémoire est incrémenté et les données à partir de l'accumulateur est de mettre dans l'ancienne adresse. Lors de la récupération ou à éclater de données à partir de la pile, c'est l'inverse qui est fait et les pointeurs de pile est décrémenté et les données de la pile est mis dans l'accumulateur.
Maintenant j'ai aussi sorte de vitrage sur la façon dont les instructions sont 'exécution'. Eh bien, ce est quand vous obtenez le bas vers le numérique logique - VHDL genre de truc. Les multiplexeurs et les décodeurs et de la vérité des tables et tels. C'est le nitty gritty de la conception du genre. Donc, si vous voulez 'move', le contenu d'un emplacement mémoire dans l'accumulateur que vous avez à comprendre l'adressage logique, claire l'accumulateur s'inscrire, ET avec les données à l'emplacement de la mémoire, etc. C'est assez décourageant quand placé tous ensemble, mais si vous avez fait des parties distinctes (comme l'adressage, un demi-additionneur, etc) en VHDL ou en toute logique numérique de la mode, vous pourriez avoir une idée de ce qui est exigé.
Comment est-ce lié à C? Eh bien, un compilateur va prendre la C des instructions et de les transformer en une série d'opcodes pour effectuer les opérations demandées. Tout cela est fondamentalement hex de données des uns et des zéros placés à un certain point dans la mémoire programme. Ceci est fait avec compilateur/linker directives dire ce que l'emplacement de la mémoire est utilisée pour ce code. Il est écrit à la mémoire flash sur la puce, et puis quand la puce redémarre, il va de code d'emplacement de mémoire 0x0000 et Saute à l'adresse de début du code dans la mémoire programme, puis commence à bosser à opcodes.
OriginalL'auteur Stephen Friederichs
J'ai de l'expérience avec les microcontrôleurs AVR, mais je pense que ce sera à peu près la même pour tous:
La compilation va dans le même sens que normal C du code. Il est compilé dans les fichiers objets, ceux-ci sont liés ensemble, mais au lieu de délivrer de certains complexes format, comme ELF ou PE, la sortie est simplement placé sur certains d'adresse fixe dans l'uC de la mémoire, sans les en-têtes.
Le code de démarrage (si le compilateur génère un) est ajouté dans une même façon que le code de démarrage "normal" ordinateurs -- il y a un peu de code ajouté avant de votre main() code (et peut-être après).
Une autre différence est le lien -- everythig doit être lié statiquement, parce que les micro-contrôleurs ne disposent pas d'un système d'exploitation pour gérer la liaison dynamique.
Pas tout à fait exacte sur ELF/PE. De nombreux linkers pour des systèmes embarqués de sortie de l'ELFE, c'est juste que le code binaire à l'intérieur il est fixe, adresse, pas indépendant de la position. Donc, il est alors possible de générer un fichier hex (Motorola S-dossier ou Intel Hex) ou directement vidage binaire (en supposant que vous savez l'adresse de départ) à charger dans la mémoire Flash.
OriginalL'auteur cube
Vous pouvez prendre un coup d'oeil à la très détaillé GNU BRAS Tutoriel par Jim Lynch.
OriginalL'auteur starblue
Vous pouvez consulter le lien https://automotivetechis.wordpress.com/.
La séquence suivante donne un aperçu de la séquence de contrôle de l'instruction exécutions:
1) Alloue de la mémoire principale pour l'exécution du programme.
2) Copies de l'espace d'adresse du secondaire et le primaire de la mémoire.
3) Copies de la .le texte et les .sections de données à partir de l'exécutable en mémoire primaire.
4) Copies des arguments du programme (par exemple, les arguments de ligne de commande) sur la pile.
5) Initialise les registres: définit l'esp (pointeur de pile) pour pointer vers le haut de la pile, efface le reste.
6) Sauts de commencer la routine, qui: copies main()‘s des arguments hors de la pile, et les sauts de main().
OriginalL'auteur Shaikmeera