Question

Relatif à:

Si vous écrivez du code pour un le microcontrôleur est présent une réelle différence si vous écrivez en assembleur ou en C ou dans un autre langage de haut niveau? Si vous écriviez du code C, comment le compileriez-vous?

Merci

Était-ce utile?

La solution

Plusieurs commentaires:

1) Absolument pas d'assemblage, sauf si des contraintes de performances ou d'optimisation le justifient. Les métriques suivantes franchissent le toit avec l'assemblage:

  • le temps de le coder
  • le temps de le déboguer
  • le temps de le tester
  • le temps de le documenter
  • le temps de comprendre (un an plus tard) ce que vous faisiez lorsque vous l'avez codé
  • chances de faire une erreur

2) Ma préférence serait C ++ plutôt que C pour son encapsulation d'espace de noms & amp; sa facilitation des pratiques à la compilation au moment de la compilation. C a trop d'opportunités pour les collisions de variables globales et d'espaces de noms. (Java en temps réel serait bien, mais de ce que je comprends, ses exigences sont encore très élevées)

Ou plutôt un sous-ensemble de C ++: Exceptions d'exclusion, fonctions virtuelles, identification du type à l'exécution, allocation dynamique de la mémoire dans la plupart des cas - tout élément non spécifié à la compilation, car il nécessite généralement beaucoup de ressources supplémentaires. pendant l'exécution. C'est le "gonflement". de C ++.

J'ai utilisé à la fois les compilateurs de TI et IAR pour C ++, pour les microcontrôleurs TMS320 et MSP430 (respectivement) et avec les paramètres d'optimisation appropriés, ils permettent de réduire de façon considérable la charge de travail attendue de C ++. (Surtout si vous l’aidez en utilisant judicieusement le mot clé inline )

J'ai même utilisé des modèles pour certains de leurs avantages au moment de la compilation, qui favorisent une bonne réutilisation du code: par exemple. écrire un seul fichier de code source pour gérer les CRC 8 bits, 16 bits et 32 ??bits; et polymorphisme au moment de la compilation pour vous permettre de spécifier le comportement habituel d'une classe, puis de le réutiliser. mais remplacer certaines de ses fonctions. Encore une fois, le compilateur TI avait une surcharge extrêmement faible avec les paramètres d’optimisation appropriés.

Je recherchais un compilateur C ++ pour les PIC de la puce; La seule société que j'ai trouvée qui en produit une est IAR. ($$$ a été un obstacle mais j’espère en acheter un exemplaire un jour.) Les compilateurs Microchip C18 / C30 sont plutôt bons, mais ils sont en C, pas en C ++.

3) Une mise en garde spécifique concernant l’optimisation du compilateur: cela peut rendre / rendra le débogage très difficile; souvent, il est impossible de suivre en une étape le code C / C ++ optimisé et vos fenêtres de surveillance peuvent afficher des variables sans corrélation avec ce que vous pensez qu'elles devraient contenir avec du code non optimisé. (Un bon débogueur vous avertirait qu’une variable donnée a été optimisée en dehors de la mémoire ou dans un registre plutôt que dans un emplacement mémoire. De nombreux débogueurs ne le font pas. & Gt; :(

Un bon compilateur vous permettrait également de choisir / d'optimiser l'optimisation au niveau de la fonction via #pragmas. Ceux que j'ai utilisés ne vous permettent que de spécifier l'optimisation au niveau du fichier.

4) Interfaçage du code C avec l’assemblage: c’est généralement difficile. Le moyen le plus simple consiste à créer une fonction de stub qui porte la signature souhaitée, par exemple. uint16_t foo (uint16_t a, uint32_t b) {retour 0; } , où uint16_t = short signé, nous expliquons généralement le nombre de bits. Ensuite, compilez-le et modifiez l'assembly qu'il produit (veillez à laisser les parties début / sortie du code) et faites attention à ne pas écraser les registres sans les restaurer après l'avoir terminé.

L'assemblage en ligne peut généralement avoir des problèmes à moins que vous ne fassiez quelque chose de très simple, comme activer / désactiver les interruptions.

L’approche que j’aime le plus est celui des éléments intrinsèques du compilateur / "extended ASM". syntaxe. Le compilateur C de Microchip est basé sur le compilateur GNU C et il possède un ASM étendu " ce qui vous permet de coder des bits d’assemblage inline mais vous pouvez lui donner beaucoup d’allusions pour lui indiquer les registres / variables que vous référencez et

Autres conseils

La plupart des fabricants de microcontrôleurs fournissent une sorte de compilateur croisé dans lequel vous pouvez compiler le code sur votre PC, puis le transférer sur le microcontrôleur.

Pourquoi C?
L’avantage de C est que votre code sera plus facilement transférable à d’autres microcontrôleurs à l’avenir. L'histoire de l'informatique a montré que le code durait généralement plus longtemps que les implémentations matérielles.
Un deuxième avantage est constitué par les structures de contrôle (si, pour, tant que) qui rendent le code plus lisible et maintenable.

Pourquoi le langage d'assemblage?
Vous pouvez effectuer des optimisations à la main.

Verdict
Comme c'est souvent le cas avec ce type de question, les compromis sont très dépendants de l'utilisation spécifique.
Sachez qu’il est souvent possible de mélanger les deux en effectuant des appels à l’assemblage dans le code C, afin de trouver le bon équilibre pour votre projet.

Spécifique au matériel PIC
Il semble ne pas avoir l'option de GCC avec la plupart des matériels PIC. D'autre part, comme l'a noté un intervenant, le compilateur Microchip C30 pour les PIC24 et dsPIC33 16 bits est gcc.
Le SDCC ne prend pas en charge le PIC. Nouvelle information: selon un commentaire, SDCC prend en charge les PIC de manière pratique.
Il existe d’autres options open source, mais je n'ai aucune expérience de ces options.

La meilleure option est probablement de coder en C, puis dans les rares cas où vous avez besoin d'optimiser à la main et que vous pouvez faire mieux que le compilateur, vous devriez coder l'assembly dans vos fichiers c.

Le codage des assemblages appartient au passé pour les ordinateurs personnels, mais il est très utile dans les systèmes embarqués.

L’écriture d’un assemblage dans Embedded est différente de celle d’un assemblage sur PC. Les compilateurs PC sont "meilleurs que les humains". à générer des instructions optimisées. Les systèmes embarqués ont souvent des architectures étranges, et leurs compilateurs d’optimisation ne sont pas aussi avancés que ceux d’un compilateur d’optimisation pour PC.

Un problème que j'ai rencontré avec l'écriture d'assemblage pour un microcontrôleur est la nécessité d'être très prudent dans la présentation de votre code. Avoir une table de sauts transcende les limites de la mémoire et provoquer le saut de votre code dans des endroits vraiment étranges est plutôt inquiétant. Codage en C, le compilateur couvre cette base pour vous.

J'irais certainement avec C. C'est plus rapide et cela crée un logiciel plus fiable. L'assemblage a très peu à offrir et dans des occasions rares. Rappelez-vous que dans C:

  • Vous pourrez facilement porter le code depuis des plates-formes existantes, même à partir d'un PC.
  • Vous pouvez développer dans un langage de haut niveau sans compromettre la vitesse d'exécution ou la taille du code. Si un compilateur de qualité est disponible (il y a beaucoup de choix pour PIC18), ceux-ci seraient probablement meilleurs avec C que les assemblages faits à la main.
  • Il est beaucoup plus facile de déboguer, de tester et de gérer le code. C produit un code plus fiable.

Une autre chose qui concerne spécifiquement PIC18. Vous n’aurez pas à vous soucier de l’architecture PIC non intuitive ni de choses comme les BANQUES de mémoire.

J'ai eu une bonne expérience avec les compilateurs IAR de C pour les années 8051.

Mon approche récente a toujours été la suivante: -

Écrivez-le en C avec un compilateur optimiseur performant, et UNIQUEMENT ALORS qu’il y a un problème de taille ou de vitesse, envisagez de réécrire certaines pièces dans l’assembleur.

Cependant, depuis que j'ai adopté cette approche, je n'ai jamais besoin d'écrire une seule ligne d'assembleur ...

Allez c!

J'ai travaillé pour un grand fabricant de CE. La dernière fois que j'ai vu l'assemblage, c'était autour de 1996 dans quelques petites routines de services d'interruption pour les algorithmes de décodage et d'accord TV RC5 et RC6. Après cela, toujours utilisé c et C ++ (uniquement les classes utilisées, pas de stl, exceptions ou rtti). J'ai de bonnes expériences avec l'ancien compilateur KEIL pour 8051 et avec le compilateur greenhills (MIPS) et l'ensemble d'outils VxWorks (basé sur PowerPC).

Comme le dit Roddy, écrivez d’abord en C et optimisez ensuite l’assemblage (si nécessaire).

Dans de nombreux cas, l’assemblage peut être plus rapide. Lorsque vous utilisez un ordinateur de bureau, les compilateurs ont tendance à être optimisés au point que l’assemblage manuel est rarement une nécessité, alors que c’est souvent le cas dans le monde américain. De plus, si vous avez besoin d’écrire des routines de traitement des interruptions, vous ne pourrez souvent pas le faire en C.

En ce qui concerne la compilation, recherchez un compilateur C pour votre cible.

Certainement C, sauf quand

  • la mémoire de programme est extrêmement limitée. Après avoir minutieusement optimisé manuellement votre code assembleur, vous réussissez à adapter votre programme à ces 1024 octets de Flash, avec 0 octets restants. Dans ce cas, aucun compilateur C ne sera utile.

  • vous voulez avoir un contrôle absolu de la synchronisation. Si la latence des interruptions est trop longue, vous devrez faire appel à l'assembleur.

Le problème, de nos jours, est que l'embarqué peut être n'importe quoi, d'un ATTiny avec 6 broches et quelques octets de RAM à un SBC multi-cœur exécutant un système d'exploitation intégré qui ferait honte aux ordinateurs de bureau de certaines personnes.

En tant que tel, le choix de l'environnement de langage / développement doit prendre en compte votre efficacité par rapport à la complexité du système.

Tout d'abord, C fonctionne partout et évolue plutôt bien. Plus vous montez, plus vous appelez des bibliothèques externes, etc. pour gérer la complexité.

Pour les très petits micros (mesure flash / RAM en octets), il vaut mieux utiliser ASM. Lorsque vous atteignez la plage de kb, vous pouvez utiliser le langage C ou n'importe quelle autre langue traditionnelle, car vous n'avez pas besoin de compter. chaque octet. Une fois que vous avez des mégaoctets, vous avez à la fois la capacité et, de plus en plus probable, le besoin d’utiliser un RTOS pour tout gérer et réduire le temps de développement. Au moment où vous avez du matériel, vous pouvez exécuter un système d’exploitation complet, vous pouvez probablement vous en abstenir et tout écrire dans une cellule matelassée telle que Java ou autre sans trop vous soucier de la façon terrible dont tout cela est gaspillé et comment vous le faites. plus un vrai programmeur ...;)

L'exception à ce qui précède est lorsque vous avez besoin de toutes les performances que vous pouvez obtenir du matériel, auquel cas vous devrez peut-être baisser d'un niveau ou deux pour que tout soit efficace.

C’est la ligne de fond si vous utilisez C, vous pouvez l’optimiser plus tard, je n’utiliserais rien d’autre que C ou un assembleur (pas de C ++, etc).

La clé est le jeu d’instructions de microcontrôleur si vous utilisez un PIC ou même un 8051, je n’utiliserais que l’assembleur. S'il s'agit d'un compilateur isa tel que arm ou avr ou msp430, utilisez C pour sauvegarder certains types de frappe, mais vous aurez probablement des routines dans l'assembleur pour diverses raisons. De même, vous voudrez probablement éviter une bibliothèque C, même newlib peut être trop volumineux, empruntez du code ou des idées mais ne faites pas simplement en relier une. Oh, revenons à la question, regardez quels compilateurs C sont disponibles pour la cible, encore une fois Arm et avr, vous n'aurez aucun problème. Probablement msp est bien aussi. Ce n'est pas parce que Keil ou Iar vous VENDRE un compilateur que vous devriez l'acheter ou l'utiliser, la sortie de paye pour des compilateurs gratuits peut être redoutable. De toute façon, vous devez être bien au courant et examiner le résultat (vous devrez probablement écrire un désassembleur pour le faire).

En bout de ligne (une autre ligne de fond), il n’existe pas de réponse globale (évitez tout ce qui est supérieur à C, c’est toujours une réponse globale), cela dépend toujours de la plate-forme, des ressources dont vous disposez, de vos tâches et des exigences de performance. les exigences de portabilité sont (si elles sont réellement intégrées à un microcontrôleur, une grande partie de celles-ci est par définition non portable), les compilateurs, les débogueurs, les jtag, etc. sont disponibles, même dans la mesure où le système d'exploitation hôte sur lequel vous développez peut être un facteur important .

Il est un autre moment où l'écriture dans l'assemblage peut être nécessaire: si vous devez effectuer un test de RAM de bas niveau ou similaire, cela nécessite un contrôle absolu sur l'emplacement de stockage des données.

Par exemple, un logiciel confirmant SIL -2 (niveau d'intégrité de sécurité) et supérieur peut nécessiter des contrôles continus sur la RAM, afin de détecter toute corruption éventuelle des données. La zone de RAM que vous contrôlez ne peut pas changer pendant la vérification. L'écriture du test dans l'assembleur vous permet donc de vérifier que cela est vrai, par exemple en stockant les variables locales dans des registres spécifiques ou dans une autre zone de RAM. . Ce serait difficile, voire impossible, dans C.

Le code de démarrage qui met à zéro la RAM et initialise des variables statiques non nulles peut également être écrit en assembleur pour la même écriture, bien que ce type de code soit normalement fourni.

Si vous écrivez du code qui dépend fortement de périphériques spécifiques à un périphérique et que la chaîne d'outils que vous utilisez ne fournit pas les éléments intrinsèques nécessaires pour les utiliser efficacement (comme le compilateur Freescale DSP563CC de merde), utilisez l'assembly. .

De plus, je pense que les règles non écrites de l'assemblage par rapport à un langage de haut niveau sont plus ou moins les mêmes que celles du développement de logiciels de bureau: maintenez le code propre, maintenable et optimisez le code actif avec le langage machine.

Le code en langage assembleur est très rapide et occupe peu de place, mais le code écrit en langage assembleur n'est pas réutilisable. Cette fonctionnalité de réutilisation pour le code est la fonctionnalité la plus importante pour la conception de logiciels. Par exemple, si vous avez un code de projet d'assembleur pour un processeur x86, il ne peut être utilisé que pour un processeur x86, pas pour un processeur ARM. Mais si vous avez du code projet C / C ++ pour un processeur x86, vous pouvez utiliser ce code pour un processeur ARM. Il est donc préférable d'éviter l'assembleur pour le développement de logiciels.

C'est dommage que personne n'ait mentionné Forth ou Scheme jusqu'à présent. Les deux peuvent convenir à de petits environnements et générer des gains de productivité impressionnants.

Plain C ou Pascal, Modula2. Mais en raison de la disponibilité du compilateur, cela signifie que C.

Les suppléments de C ++ et autres ne sont intéressants que pour des raisons de style, car l’allocation dynamique et la taille du programme sont généralement très limitées.

De même, une exécution plus compliquée peut s'avérer pénible si vos applications deviennent de plus en plus serrées.

Assembler peut aussi être utile, mais uniquement si vous vendez des quantités vraiment gigantesques, et qu'un micrologiciel plus petit signifie une puce plus petite et moins chère (moins de flash) et que la taille du programme est compatible (lisez: il y a des chances que vous l'obtiendrez bugfree in time)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top