Contexte :
Ingénieur junior R&D en électronique ( le seul EE de l'entreprise ) - le matériel et le codage ne sont pas le problème. Mon plus gros problème est d'avoir une bonne vue d'ensemble du projet et par où commencer.
Jusqu'à présent, je n'ai fait que des projets logiciels mineurs (moins de 500 lignes de code), mais je ne peux pas m'imaginer faire des projets plus importants sans perdre la vue d'ensemble de la fonctionnalité ou le manque de fonctionnalité.
Comment structurez-vous le mieux / quels outils utilisez-vous pour structurer les grands systèmes logiciels embarqués?
Ce que je fais actuellement :
Je commence généralement par esquisser la fonctionnalité du projet. Il peut s'agir d'un à plusieurs organigrammes en couches ou de diagrammes associés (schémas fonctionnels, etc.) et faire des recherches sur les composants / puces. Ensuite, je passe directement au codage (échec rapide, je suppose) tout en référençant les fiches techniques / Internet, en codant une fonctionnalité à la fois et en la testant avec des données factices, ou un test similaire. Il pourrait s'agir d'écrire des données sur une puce MEM, puis si cela fonctionne, il pourrait s'agir d'un pilote SPI entre la puce principale et la puce MEM.
Quelle réponse je cherche :
Rien? Vraiment. Je vais trier ce que je trouve sensé. Il peut s'agir d'un livre, d'un article, d'une expérience personnelle, de recommandations, etc.
Je suis très intéressé de savoir comment les personnes âgées abordent ce problème.
modifier
Tout d'abord, merci de partager vos années d'expérience! Toutes les réponses sont très appréciées. Ma prise de ceci est;
- Créez un document de spécification clair et précis.
- Créez un document de conception de logiciel. (Quelque chose que j'ajouterai maintenant) Modèles de doc de conception
- Pensez aux modules à quel point cela peut sembler redondant. (Quelque chose sur lequel je dois me concentrer davantage)
- Suivez une norme de codage pour structurer les fichiers d'en-tête / source. (Jamais fait cela) Norme Barr Group C
- Concentrez-vous d'abord sur la création des implémentations de bas niveau. (Communication etc.)
- Mettez en œuvre des modèles de conception dans la mesure du possible / sensé. Modèles de conception
- Configurer quelque chose pour le contrôle des révisions (Github etc. - jamais utilisé autant)
- Recherche intégration continue / déploiement continu (quelque chose de nouveau sur lequel je suis tombé) bases de CI et CD
Réponses:
Plusieurs aspects influencent le degré de détail de la structuration des besoins d'un projet. Pour moi, l'un des principaux facteurs est de savoir si je suis le seul codeur (ce qui semble être le cas pour vous lorsque vous écrivez, vous êtes le seul EE) ou s'il y en a d'autres impliqués. Ensuite, il y a la question de ce que signifie réellement «grand». Habituellement, je divise le processus de conception en plusieurs étapes:
Définition des exigences Si vous obtenez des spécifications logicielles appropriées pour travailler avec beaucoup de planification, c'est déjà fait. Si vous n'avez que des exigences vagues, la première chose que vous devez faire est de trier ce que le client veut réellement (parfois, il ne sait pas vraiment en premier lieu). Je sais qu'il est tentant de passer directement au codage, mais cela présente le risque de manquer une fonctionnalité importante qui n'était peut-être pas évidente en premier lieu et ne peut pas être facilement insérée dans votre code quelque part au milieu du développement.
Limites du système et maintenabilité Dans les systèmes embarqués, vous avez souvent certaines interfaces système, certaines vers l'extérieur (opérateur) mais aussi à l'intérieur. Définissez-les bien et essayez de maintenir les dépendances aussi basses que possible, cela simplifiera l'ingénierie et la maintenabilité continues. Également commenter / documenter le code si nécessaire, vous ne savez jamais qui d'autre devra travailler avec lui, (s) il sera heureux de ne pas avoir à creuser une douzaine de couches de code avant de savoir réellement ce que fait une fonction.
Définir des tâches vérifiables Surtout si d'autres développeurs travaillent sur la même base de code, il est inévitable de définir des tâches (fonctionnalités) claires et les interfaces requises entre elles. Dans la mesure du possible, les fonctionnalités individuelles doivent être testées / vérifiées indépendamment des autres, c'est là que vous avez besoin des interfaces bien définies pour pouvoir définir vos cas de test.
Une fonctionnalité après l'autre Les gens aiment le progrès, donc si vous avez une variété de tâches, ils travaillent généralement sur tout ce qui promet le plus de progrès. J'essaie généralement de terminer une tâche et de la mettre dans un état vérifié et testé avant de commencer avec la suivante. Cela permet à votre code d'être testé par d'autres et de ne pas oublier quelque chose.
Contrôle des révisions Au cours de la vie d'un projet, vous avez parfois besoin de versions plus anciennes, peut-être pour identifier un bogue introduit avec une nouvelle version ou simplement pour construire un appareil qui se comporte exactement de la même manière que celui que vous avez expédié il y a 3 ans. Assurez-vous que votre code contient des révisions de construction et des balises claires. Git est définitivement votre ami ici.
la source
Humpawumpa a écrit une excellente réponse ! Je veux juste compléter certains de ses points, mais comme c'est trop long pour être un commentaire, je vais écrire une réponse séparée.
J'étais une fois dans la position du PO - pas le seul EE, mais le seul EE qui avait fait du développement de microcontrôleurs dans une petite entreprise.
Je ne saurais trop insister sur l'importance de la modularité , même si vous êtes le seul développeur. C'est la seule façon de rester sain d'esprit à mesure que le projet se développe. Vous devez être strict sur l'écriture de modules qui ne gèrent qu'un seul concept fonctionnel chacun, et garder leurs interfaces externes aussi minimes que possible. Les modules de haut niveau correspondront aux exigences fonctionnelles, tandis que les modules de bas niveau auront des liens étroits avec les ressources matérielles (c'est-à-dire les pilotes de périphériques).
J'ai passé beaucoup de temps à maintenir un diagramme de flux de données détaillé 1 , qui montrait précisément comment les différents modules partageaient des informations. Certaines fonctionnalités auront des exigences très différentes en termes de performances en temps réel; assurez-vous de savoir comment le partage d'informations affecte cela. Le diagramme avait des limites tracées à travers lui qui séparaient le code sans interruption des divers domaines déclenchés par interruption.
1 Très différent d'un organigramme axé sur le flux de contrôle .
la source
Pour tout grand projet, je le planifie comme si plusieurs développeurs étaient impliqués même si j'ai l'intention de faire le tout moi-même.
Les raisons sont simples:
1 Complexité. Un grand projet comportera toujours des complexités. La planification du projet comme s'il y avait plusieurs équipes impliquées signifie que la complexité a été prise en compte et documentée . Le nombre de fois où j'ai vu de grands projets rencontrer des problèmes est élevé et généralement parce que quelque chose «a glissé entre les mailles du filet». N'oubliez pas que l'assemblage mécanique doit également être pris en compte et pas seulement pour la taille de la boîte - aura-t-il besoin de dissipateurs thermiques? La boîte doit-elle être mise à la terre pour des raisons de sécurité? Il y a beaucoup de questions dans cette seule catégorie.
2 Exigences. En supposant que plusieurs personnes sont impliquées, les exigences de haut niveau (que je conteste souvent car elles peuvent entraîner une complexité et des coûts inutiles) doivent être décomposées en différentes tâches plus petites requises et réalisables (qui pourraient être transmises à une autre équipe dans une organisation plus grande). ) plutôt que de simplement regarder une seule goutte.
3 Partitionnement. Il existe deux principaux types de partitionnement; fonctionnalité matérielle et matériel / logiciel. Le premier type consiste à déterminer quels blocs fonctionnels distincts (mais communicants) doivent être présents. Le second est un compromis entre du matériel et des logiciels plus simples (parfois), mais gardez à l'esprit que le simple fait de déplacer plus de choses vers le logiciel ne résoudra pas nécessairement un problème matériel. Passer davantage aux logiciels peut en fait augmenter considérablement la complexité matérielle dans certaines circonstances (plus de puissance de traitement, interfaces plus complexes et plus).
4 Interfaces. Le processus de partitionnement aidera à définir les interfaces internes; les interfaces externes font généralement partie des exigences globales (mais pas toujours). Il existe de nombreuses façons pour différentes parties d'un système de coopérer, ce qui peut être un protocole de communication complexe ou simplement une bonne / mauvaise signalisation.
5 Vérification. Il s'agit d'un mélange de tests de bas niveau (pour le matériel et les pilotes) et de niveau système. La réalisation du projet dans des blocs bien définis permet une vérification robuste (qui peut être effectuée par analyse ou test réel et est généralement un mélange des deux; les mises à jour des conceptions peuvent utiliser des arguments de similitude).
6 Normes. J'utilise des normes de codage et de dessin comme s'il s'agissait d'une équipe plus importante. J'utilise le groupe Barr normes de codage car elles ne sont pas trop onéreuses mais empêchent de nombreuses classes de bogues dans le code. Pour la documentation de sortie PCB, je suis IPC-D-326 (qui appelle IPC-D-325) car c'est une méthode éprouvée de communiquer mon intention aux fabricants et assembleurs de PCB. Cela peut sembler étrange, mais avoir la discipline de suivre un certain nombre de normes signifie que la qualité est constante.
7 Contrôle de version. J'utilise le contrôle de révision pour toutes les parties du projet (système, matériel, logiciel. Mécanique, exigences de test - tout). Les outils de CAO que j'utilise prennent en charge des versions telles que tous les logiciels et les outils de génération FPGA.
J'ai travaillé sur de nombreux projets intégrés (comme beaucoup de gens expérimentés ici) et la taille des équipes varie de 1 (moi-même) à des dizaines (ou des centaines sur un ensemble particulier de projets) répartis dans plusieurs disciplines et parfois dans d'autres régions géographiquement éloignées. des sites. En utilisant la même approche globale (qui est connue pour fonctionner), je peux prendre une tâche particulière dans un isolement relatif et la terminer et la tester soigneusement en tant que partie autonome du projet plus vaste. Cela signifie également que je peux soumettre certaines choses à l'occasion si nécessaire.
Faire toutes ces choses ajoute un peu de temps d'avance mais est finalement un itinéraire plus rapide pour les systèmes embarqués complexes.
la source
Les autres réponses donnent de nombreux bons conseils. En voici deux que j'ai trouvées les plus importantes dans ma carrière en développement intégré:
C'est ce dont vous avez besoin pour faire du développement de style "d'intégration continue" sur des systèmes embarqués. Il y aura toujours une quantité de code trop étroitement liée au matériel pour les tests automatiques, mais essayez de la minimiser. Vous pouvez aller assez loin en utilisant des données simulées ou des captures de données à partir de matériel réel, que vous introduisez ensuite dans le système de test.
la source
Pour ajouter aux réponses existantes ...
Je pars toujours de bas en haut. De par la conception de votre matériel, vous savez ce que sont vos E / S. Commencez par créer des modules de pilotes qui encapsulent ces E / S, afin que votre code de haut niveau n'ait pas à en savoir trop sur les éléments de bas niveau.
Lorsque vous créez des interfaces de bas niveau, vous avez bien sûr besoin d'un faisceau de test. Si vous le concevez pour vous connecter au PC dès le départ (peut-être avec un port RS-232, peut-être USB, peut-être telnet sur Ethernet), vous pouvez garder cette interface de faisceau de test en place pendant que vous créez votre application. Vous pouvez continuer à ajouter plus de crochets de harnais de test au fur et à mesure que l'application prend forme, ce qui vous permettra également de tester votre code en régression au fur et à mesure.
la source
J'ai tendance à penser en quatre questions. Les deux premiers appartiennent au début d'un projet de systèmes, les deux suivants vers la fin.
Veulent-ils vraiment le système? Le système résoudra-t-il le problème des clients, à une échelle de temps et de coût qu'ils accepteront? Un problème courant est la construction de systèmes que le client n'utilisera pas.
Pouvons-nous réellement construire ce système? Sera-t-il possible de fournir les performances, la précision, la consommation d'énergie nécessaires, ...?
La création de premiers prototypes est un bon moyen de répondre à ces deux premières questions. L'atténuation des risques est extrêmement importante dans les premières phases.
Les deux questions suivantes sont plus ciblées sur les phases ultérieures du projet:
avons-nous fini? Tout conçu, codé, testé, livré
Utilisent-ils réellement le système?
la source