programmation microcontrôleur vs programmation orientée objet

11

J'ai fait de la programmation orientée objet basique avec C ++ (création d'un B-Tree, Hashing Algorithms, Double Linked Lists) et j'ai fait un petit projet en C (comme faire une calculatrice scientifique etc.)

Quelle est la différence entre la programmation matérielle (spécifiquement pour les microcontrôleurs) et la programmation orientée logiciel / objet en termes de mentalité et de "réflexion" que le programmeur doit avoir?

Est-ce que l'un est généralement considéré comme plus difficile que l'autre mon plus grand nombre de personnes?

Avec mon expérience (comme décrit ci-dessus), aurais-je besoin de beaucoup de préparation pour entrer dans la programmation matérielle ou puis-je plonger directement sans trop de préparation?

rrazd
la source
4
La plus grande courbe d'apprentissage sera de savoir comment piloter le matériel spécifique de votre micro. Cela impliquera de parcourir les fiches techniques pendant des heures. Malheureusement, il n'y a pas d'issue facile.
drxzcl
@rrazd, j'ai remarqué que vous avez inclus la balise arduino. Est-ce parce que vous souhaitez utiliser le langage de câblage Arduino et les bibliothèques? Ou allez-vous écrire vos applications embarquées en C pur? Si vous avez l'intention de vous en tenir à l'environnement Arduino, il est assez sûr et facile de jouer car ils ont fait quelques abstractions loin du matériel.
Jon L
@Jon j'ai l'intention d'utiliser une carte Arduino pour commencer. N'est-il pas similaire au langage C? Je pensais que cela impliquait les mêmes concepts de base ....
rrazd
1
Je me demande si vous voulez dire ce que beaucoup de gens appellent la «programmation d'E / S» ou si vous prévoyez de réorganiser le matériel avec du code. L'arduino est décidément le premier; ce dernier serait le domaine des FPGA.
JustJeff
1
@rrazd - J'ai changé de titre; la "programmation matérielle" ressemble trop à HDL (Hardware Description Language), par exemple VHDL et Verilog, qui sont utilisés pour programmer des FPGA et des CPLD.
stevenvh

Réponses:

10

Vous devrez abandonner complètement le paradigme orienté objet lorsque vous aurez affaire à la plupart des microcontrôleurs.

Les microcontrôleurs sont généralement limités en registre et en RAM, avec des fréquences d'horloge lentes et aucun chemin de code en pipeline / parallèle. Vous pouvez oublier Java sur un PIC, par exemple.

Vous devez entrer dans un état d'esprit en langage assembleur et écrire de manière procédurale.

Vous devez garder votre code relativement plat et éviter la récursivité, car les limitations de la RAM peuvent souvent entraîner des problèmes de pile.

Vous devez apprendre à écrire des routines de service d'interruption efficaces (généralement en langage assembleur).

Vous devrez peut-être refactoriser des parties du code manuellement, en langage assembleur, pour implémenter des fonctionnalités que le compilateur ne prend pas en charge (ou prend en charge mal).

Vous devez écrire un code mathématique qui prend en compte la taille des mots et le manque de capacités FPU de la plupart des microcontrôleurs (c'est-à-dire faire une multiplication 32 bits sur un micro = evil 8 bits).

C'est un monde différent. Pour moi, avoir une formation en informatique ou en programmation professionnelle peut être autant un obstacle que ne pas avoir de connaissances du tout quand il s'agit de microcontrôleurs.

Adam Lawrence
la source
1
Il n'est pas nécessaire d'abandonner complètement le paradigme orienté objet, mais sur des micros plus petits, il peut être nécessaire d'abandonner les implémentations d'objets lourds et de vraiment réfléchir à la meilleure façon de résoudre chaque problème. Il s'agit souvent de procédures, mais des objets légers, bien mis en œuvre (généralement à la main), peuvent parfois réduire la taille des projets de microcontrôleurs complexes.
Chris Stratton
6
Tout cela est vrai, sauf l'abandon de l'orientation objet. Vous n'utiliserez probablement pas un langage avec des fonctionnalités OO mais cela n'exclut pas l'orientation des objets. Pour les microcontrôleurs, vous allez écrire des pilotes pour tous les périphériques matériels (ADC, contrôleurs de bus série, PWM, etc.). Un tel pilote doit toujours être écrit de manière orientée objet afin qu'il soit 1) autonome et ne connaisse pas / ne se soucie pas du reste du programme, et 2) implémente une encapsulation privée afin que le reste du programme ne puisse pas entrer et jouer avec. Ceci est 100% possible en C et n'affectera pas les performances.
Lundin
1
Je suis fortement en désaccord avec la première phrase, tous mes projets de microcontrôleurs ont été construits avec C ++ et une approche orientée objet, et les micros que nous avons utilisés n'étaient pas très grands (32 Ko de ROM), le chargeur de démarrage également orienté objet était en moins de 2 Ko, je ne vois pas vraiment de limitation. Vous ne pouvez pas faire de trucs fous mais le design peut être orienté objet sans problème.
Arsenal
@Arsenal Remarque J'ai dit «la plupart» et notez que vous commentez un fil de quatre ans. :)
Adam Lawrence
Je suis totalement en désaccord avec la première et la dernière phrase. Et l'assembly est également utilisé assez rarement et, surtout, uniquement pour les MCU 8 bits (vérifiez simplement ce forum, combien de messages avec le code d'assembly que vous pouvez trouver?). Vous pouvez certainement et (à
mon humble avis
10

Vous devez penser à plusieurs choses:

  • Vous utiliserez C comme langue
  • Vous pouvez toujours créer une sensation d'orientation d'objet en utilisant des pointeurs de fonction afin de pouvoir remplacer des fonctions, etc. J'ai utilisé cette méthode dans les projets passés et actuels et fonctionne très bien. Donc OO est partiellement là mais pas au sens C ++.

Il y a d'autres limitations qui entreront en jeu, comme une vitesse et une mémoire limitées. Donc, à titre indicatif, j'évite:

  • En utilisant le tas, s'il existe un moyen de résoudre le problème sans Malloc, je le fais. Par exemple, je préalloue des tampons et je les utilise simplement.
  • J'ai intentionnellement réduit la taille de la pile dans les paramètres du compilateur pour faire face aux problèmes de taille de pile dès le début, l'optimiser soigneusement.
  • Je suppose que chaque ligne de code sera interrompue par un événement, donc j'évite le code non réentrant
  • Je suppose que même les interruptions sont imbriquées, donc j'écris ce code en conséquence
  • J'évite d'utiliser le système d'exploitation sauf si cela est nécessaire. 70% des projets intégrés n'ont pas vraiment besoin d'un OS. Si je dois utiliser un système d'exploitation, j'utilise uniquement quelque chose avec du code source disponible. (Freertos etc.)
  • si j'utilise un OS, j'abrège presque toujours des choses pour pouvoir changer d'OS en quelques heures.
  • Pour les pilotes, etc. Je n'utiliserai que les bibliothèques fournies par le vendeur, je ne joue jamais directement les bits, sauf si je n'ai pas d'autre choix. Cela rend le code lisible et améliore le débogage.
  • Je regarde les boucles et autres choses, en particulier dans ISR, pour m'assurer qu'elles sont assez rapides.
  • Je garde toujours quelques GPIO à portée de main pour mesurer les choses, le changement de contexte, le temps d'exécution ISR, etc.

La liste continue, je suis probablement en dessous de la moyenne en termes de programmation logicielle, je suis sûr qu'il existe de meilleures pratiques.

Franc
la source
3
+1 pour "vous pouvez utiliser les paradigmes OO si vous le souhaitez". Ce que vous devez vérifier à la porte n'est pas la conception OO. OOD est juste une philosophie qui vous encourage à garder le code et les données associés ensemble. Ce que vous devez laisser derrière, c'est la façon dont OO est implémenté dans les systèmes d'entreprise, avec plusieurs couches d'abstraction, d'inversion de contrôle et tout ce jazz. La tâche de votre firmware est de piloter le matériel, c'est tout.
drxzcl
7

Je fais les deux, alors voici mon point de vue.

Je pense que la compétence la plus importante de loin intégrée est votre capacité de débogage. L'état d'esprit requis est très différent en ce sens que beaucoup d'autres peuvent mal tourner, et vous devez être très ouvert à considérer toutes les différentes manières dont ce que vous essayez de faire peut mal tourner.

C'est le plus gros problème pour les nouveaux développeurs embarqués. Les PC ont tendance à avoir plus de difficultés, car ils ont l'habitude de travailler pour eux. Ils auront tendance à perdre beaucoup de temps à chercher des outils pour faire des choses à leur place (indice: il n'y en a pas beaucoup). Il y a beaucoup de têtes qui se cognent les murs encore et encore, sans savoir quoi faire d'autre. Si vous sentez que vous êtes coincé, reculez et déterminez si vous pouvez identifier tout ce qui pourrait mal se passer. Parcourez systématiquement votre liste de problèmes potentiels jusqu'à ce que vous la découvriez. Il découle directement de ce processus que vous devez limiter l'étendue des problèmes en ne changeant pas trop à la fois.

Les personnes embarquées expérimentées ont tendance à tenir le débogage pour acquis ... la plupart des personnes qui ne peuvent pas bien le faire ne durent pas longtemps (ou travaillent dans de grandes entreprises qui acceptent simplement que "le micrologiciel est difficile" comme réponse pour expliquer pourquoi une certaine fonctionnalité a des années de retard)

Vous travaillez sur du code qui s'exécute sur un système externe à votre système de développement, avec différents degrés de visibilité sur votre cible d'une plateforme à l'autre. Si vous êtes sous votre contrôle, demandez des aides au développement pour augmenter cette visibilité dans votre système cible. Utilisez des ports série de débogage, une sortie de débogage de banging, le fameux voyant clignotant, etc. J'ai vu des gens lutter pendant des années littéralement plus longtemps que nécessaire simplement parce qu'ils n'ont jamais pris la peine de configurer / apprendre à utiliser un lien de débogueur JTAG approprié.

Il est beaucoup plus important de savoir exactement quelles ressources vous avez par rapport à un PC. Lisez attentivement les fiches techniques. Considérez le «coût» des ressources de tout ce que vous essayez de faire. Apprenez des astuces de débogage axées sur les ressources, comme remplir l'espace de la pile avec une valeur magique pour suivre l'utilisation de la pile.

Bien qu'un certain degré de compétence de débogage soit requis pour le PC et les logiciels embarqués, c'est beaucoup plus important avec l'embarqué.

Darron
la source
5

Je suppose que votre expérience C ++ est basée sur PC.

Une erreur souvent commise par les programmeurs passant du PC au microcontrôleur est qu'ils ne réalisent pas à quel point les ressources peuvent être limitées . Sur un PC, personne ne vous arrêtera lorsque vous créez une table avec 100 000 entrées ou que vous écrivez un programme qui se compile en 1 Mo de code machine.
Il y a des microcontrôleurs qui ont une richesse de ressources mémoire, surtout dans le haut de gamme, mais c'est encore loin de ce à quoi vous serez habitué. Pour un projet de loisir, vous pouvez probablement toujours opter pour le maximum, mais dans un projet professionnel, vous serez souvent obligé de travailler avec un appareil plus petit car il est moins cher .
Sur un projet, je travaillais avec une TI MSP430F1101. 1 Ko de mémoire de programme, 128 octets de configuration Flash, 128 octets de RAM. Le programme ne cadrait pas dans le 1K, j'ai donc dû écrire une fonction de 23 octets dans la configuration Flash. Avec ces petits contrôleurs, vous calculez par octet . À une autre occasion, la mémoire du programme était de 4 octets trop petite. Le patron ne me laissait pas utiliser le contrôleur avec plus de mémoire, mais à la place, j'ai dû optimiser un code machine déjà optimisé (il était déjà écrit dans l'assembleur) pour s'adapter aux 4 octets supplémentaires. Vous obtenez l'image.

Selon la plate-forme sur laquelle vous travaillez, vous devrez gérer des E / S de très bas niveau . Certains environnements de développement ont des fonctions pour écrire sur un écran LCD, mais sur d'autres, vous êtes seul et devrez lire la fiche technique de l'écran LCD du début à la fin pour savoir comment le contrôler.
Vous devrez peut-être contrôler un relais, c'est plus facile qu'un écran LCD, mais cela vous obligera à aller au niveau du registre du microcontrôleur. Encore une fois une fiche technique ou un manuel d'utilisation. Vous devrez apprendre à connaître la structure du microcontrôleur, que vous trouverez dans un schéma fonctionnel, à nouveau dans la fiche technique. À l'époque du microprocesseur, nous parlions d'un modèle de programmation, qui était essentiellement une liste de registres du processeur. Les microcontrôleurs d'aujourd'hui sont si complexes qu'une description de tous les registres peut prendre le meilleur parti d'une fiche technique de 100 pages. IIRC vient de décrire le module d'horloge pour le MSP430 était de 25 pages.

Vous devrez souvent gérer la gestion des événements en temps réel . Une interruption que vous devez gérer dans un délai de 10 , par exemple, et pendant celle-ci, une autre interruption nécessite la même précision de synchronisation. μ

Microcontrôleurs sont souvent programmées en C . Le C ++ est plutôt gourmand en ressources, donc c'est généralement le cas. (La plupart des implémentations C ++ pour microcontrôleurs offrent un sous-ensemble limité de C ++.) Comme je l'ai dit, selon la plate-forme, vous pouvez disposer d'une vaste bibliothèque de fonctions qui pourraient vous faire gagner un peu de temps de développement. Cela vaut la peine de prendre du temps pour l'étudier, cela peut vous faire gagner beaucoup de temps plus tard si vous savez ce qui est disponible.

stevenvh
la source
J'ai écrit des jeux pour l'Atari 2600, qui est une plate-forme plutôt limitée; mon premier jeu publié était essentiellement du code 4K (puisque j'avais un chariot 32K, j'ai ajouté quelques goodies supplémentaires, mais la version 4K était entièrement jouable); La RAM est de 128 octets. Je trouve intéressant de considérer que l'année où j'ai écrit ce jeu (2005), d'autres jeux ont été publiés qui étaient, littéralement, un million de fois plus gros.
supercat
@supercat - Oui, mais c'était à prévoir, en 2005, l'Atari 2600 avait déjà 200 ans! Je n'ai jamais joué à des jeux d'action comme les FPS, mais quand je regarde ce qui est nécessaire pour les jouer, un GPU beaucoup plus puissant que votre CPU, à la fois par programme et électriquement, je ne peux m'empêcher de secouer la tête :-). J'ai joué aux échecs (Sargon) sur un 16k TRS-80 IIRC. Flight Simulator de mon frère n'avait pas besoin de plus.
stevenvh
Pas tout à fait 200 ans. Il a fait ses débuts en 1977, il n'était donc même pas de 30. Bien que je convienne que c'était il y a des éons en termes technologiques, je suis toujours époustouflé par le fait qu'il n'y a pas seulement une augmentation de cent fois, ni une augmentation de mille fois , mais une augmentation de MILLION fois de la RAM et de la taille du code. La vitesse n'a pas beaucoup augmenté, car le 2600 était à 1,19 MHz et les nouveaux systèmes ne sont que dans la plage des basses fréquences. Ils peuvent faire beaucoup plus par cycle que le 2600 (qui pourrait - et devait - générer 1/76 d'une ligne vidéo à chaque cycle), mais je ne pense pas qu'ils soient 1 000 000 x plus rapides.
supercat
3

La «programmation matérielle» peut signifier beaucoup de choses. Programmer une toute petite puce (pensez 10F200, 512 instructions, quelques octets de RAM) peut être presque comme concevoir un circuit électronique. D'un autre côté, la programmation d'un gros microcontrôleur Cortex (1 Mo FLASH, 64 Ko de RAM) peut être un peu comme la programmation PC / GUI, en utilisant une grande boîte à outils GUI. À mon humble avis, un bon programmeur intégré / en temps réel a besoin de compétences à la fois du côté de l'ingénierie logicielle et de la conception des circuits. Pour les plus grands uC, C ++ est un bon choix de langage, pour les très petits, C pourrait être le seul choix. La connaissance de l'assemblage peut être utile, mais je ne recommanderais pas de faire des projets sérieux entièrement en assemblage.

J'ai fait un travail sérieux et intégré avec des gens des deux côtés (SWI et EE). Je préfère généralement les personnes SWI, à condition qu'elles aient une certaine expérience de la programmation multithread.

Votre question vous donne l'impression de vous plonger dans la programmation intégrée. Par tous les moyens, faites-le. Pour les aspects de bas niveau (interface entre les périphériques de votre puce et le matériel qui l'entoure), vous devrez acquérir de nouvelles compétences, mais c'est juste beaucoup de travail sans beaucoup de nouveaux concepts. Pour les couches supérieures de vos projets, vous pouvez tirer parti de vos connaissances existantes.

Wouter van Ooijen
la source
1

Pour chaque méthode de bibliothèque Arduino que vous appelez, il existe une richesse de code C / C ++ qui le rend possible, il est simplement bien emballé pour que vous puissiez l'utiliser comme API. Jetez un œil au code source d'arduino dans le répertoire hardware / arduino / * et vous verrez tout le C / C ++ écrit pour vous qui interagit directement avec les registres du microcontrôleur AVR. Si votre objectif est d'apprendre à écrire des trucs comme ça (directement pour le matériel), alors il y a beaucoup à couvrir. Si votre objectif est de faire fonctionner quelque chose à l'aide de leurs bibliothèques, il n'y aura peut-être pas grand-chose à dire, car la plupart du travail acharné est fait pour vous et leurs bibliothèques et leur environnement de développement sont très faciles à utiliser.

Quelques règles de base cependant lorsque vous travaillez avec des appareils à ressources limitées qui pourraient s'appliquer à l'environnement Arduino ou à d'autres:

Soyez conscient de la quantité de mémoire que vous utilisez. La taille du code (qui va à la mémoire flash) et l'utilisation de la RAM statique (constantes dans votre code qui existeront toujours dans la RAM). Je dirais que l'utilisation de la RAM statique est un peu plus importante au début, car il est facile de passer en revue. Il n'est pas rare que vous ayez seulement 1000 octets avec lesquels travailler pour votre pile, votre tas et vos constantes. Soyez prudent dans la façon dont vous le dépensez, évitez donc des choses comme de longs tableaux d'entiers (4 octets chacun) lorsque des octets ou des caractères non signés (1 octet chacun) suffiront. Une autre réponse ici couvre très bien d'autres points importants, donc je m'arrêterai ici, je voulais principalement faire comprendre qu'il y a beaucoup à couvrir si vous n'utilisez pas la bibliothèque Arduino et n'écrivez pas vos propres bibliothèques C.

Jon L
la source
0

En ce qui concerne la programmation du microcontrôleur par rapport à la programmation OOP, ils ne sont pas quelque chose d'opposé. Il est vrai que toutes les bibliothèques des fournisseurs sont en simple C, mais toutes les plates-formes prennent également en charge le C ++ OOP. Les développeurs peuvent créer et créer des bibliothèques de haut niveau C ++ et des micrologiciels de périphériques en plus de cela. Le bon exemple est les bibliothèques Arduino, officielles et créées par l'utilisateur - principalement des classes C ++. Peut-être que tous les avantages de la POO ne peuvent pas être pleinement utilisés dans un environnement embarqué, mais les avantages bien connus C ++ vs C sont également valables ici.

En ce qui concerne l'état d'esprit et la réflexion, comme indiqué dans d'autres réponses, les microcontrôleurs sont des plates-formes très limitées en ressources (spécialement en RAM, moins en vitesse) - des choses comme l'allocation dynamique de mémoire, les exceptions C ++ sont généralement exclues. Étant donné que le bon matériel est choisi, il est facile d'adopter ces limitations et d'utiliser d'autres techniques (également largement utilisées sur d'autres plateformes).

À mon avis, le défi le plus difficile pourrait être une autre dimension supplémentaire trouvée dans la programmation intégrée - le timing. En effet, les logiciels embarqués traitent généralement beaucoup d'événements en temps réel, de protocoles strictement synchronisés pour piloter le matériel périphérique et les tâches générales elles-mêmes (il s'agit également de parallèles dans d'autres plates-formes "de haut niveau", comme les applications multithreads).

Soyez prêt à lire beaucoup de fiches techniques lorsque vous traitez avec du nouveau matériel - je suppose que cela pourrait être lié à la partie de la question "état d'esprit" :) Une certaine connaissance de l'EE et du matériel serait certainement nécessaire.

Je voudrais également noter que de nos jours, le développement de logiciels embarqués ne nécessite pas de langage d'assemblage. En fait, Java (BTW c'est OOP par défaut) est déjà là et devient plus fort (au moins pour certaines classes d'appareils embarqués, par exemple les appareils IoT, il pourrait avoir un avenir très brillant).

Flanker
la source
En termes de préoccupations, ceux autour de la (ré) allocation dynamique de mémoire ont tendance à être un plus grand obstacle à l'OO traditionnel que le timing .
Chris Stratton
Peut-être que tu as raison. Mais il y a des gens qui ont programmé dans les années 80-90 pour le logiciel MSDOS en mode réel, avec 64K (segment de mémoire de données) de RAM disponible et pour eux c'était "naturel". Peut-être que MSDOS PC était un environnement plus "embarqué" qu'aujourd'hui STM32F4 :)
Flanker
Le STM32F4 a généralement plus de mémoire programme sous forme de flash, mais le PC est généralement livré avec beaucoup plus de mémoire RAM pour stocker les objets d'exécution mutables. Alors que tout le pointeur éloigné forcé par l'adressage segmenté était pénible, les deux manquent d'une véritable MMU, et cela va être encore plus une préoccupation sur le système avec moins de RAM, qui est le STM32F4. De même, les temps de fonctionnement des PC étaient généralement plus courts et les taux de défaillance acceptables plus élevés.
Chris Stratton