Tout est dans le titre… au taf je bosse avecdes composants pilotes via rs 232/485, et j'ai eu l'idee (saugrenue, a priori, mais je n'arrive ni a me persuader de l'abandonner, ni a me convaincre que l'idee est bonne…) que ca pourrait etre interessant de piloter ces cartes semi intelligentes via des pilotes dedies… Du coup, voici un peu les points qui m'empechent de me decider:
- du code bas niveau, ce n'est pas accessible par tout le monde pour la maintenance,
- mais ce n'est pas cense etre change regulierement (on doit intervenir physiquement pour remplacer les cartes),
- sauf que l'existant, aussi bancal, non-evolutif, soit-il fonctionne:
- tant bien que mal, et plutot mal que bien
- l'ensemble est code en cpp que j'aime,
- mais interagir avec des fichiers dans /dev simplifierais l'usage d'autres langages moins delicats a maitriser…
Je pourrais continuer encore un peu je pense, mais voila: je debarque dans une boite qui a un historique de code d'a peu pres 2 ans, code fait dans des conditions extremes (cahier des charges a geometrie variable, pas moyen de tester in-situ, code par des gens encore a l'ecole, pas de bugtracker, (d)vcs adopte tardivement,….), les cartes (faites par un sous traitant) avec lesquelles on interagit vont etre ameliorees (pour corriger des bugs et ajouter des evolutions) voire remplacees (autres projets, autres besoins) et le protocole de communication avec les supervisions va etre ameliore (ocpp 1.5 partiel vers 1.6 pour les curieux) ce qui, vu l'etat du code, va necessiter des changements lourds de toute facon.
Du coup, je me suis dit que deplacer partie de l'existant vers des pilotes serait potentiellement interessant (notamment d'un point de vue fun…)… mais au fond est-ce pertinent?
Voila, j'aimerai vos avis du coup, quand et pourquoi implementer des pilotes, et user-space ou kernel-space?
D'avance, merci.
# Pour quelles applications ?
Posté par Obsidian . Évalué à 9.
Salut,
Concevoir puis implémenter des pilotes de périphériques est en soi une chose assez stimulante. C'est aussi une bonne occasion de plonger dans le code de bas niveau, voire carrément la programmation noyau et, en plus, les objectifs à atteindre sont relativement bien délimités : il s'agit en gros d'honorer une API (généralement déjà existante) dans sa totalité, pour permettre ensuite à des applications non spécifiquement écrites pour de pouvoir exploiter ton matériel à travers lesdits pilotes.
La première question est donc : qu'est-ce que tu pilotes, fût-ce via une liaison RS/232 ou 485 ? Il y des chances pour que ce soit en atelier, donc peut-être des machines outils… Et là encore, ça n'a d'intérêt que si ton pilote permet d'adapter l'utilisation du matériel à quelque chose de générique, ou à la limite à un niveau d'utilisation simplifié. Ça peut être intéressant également si tu as une grande gamme de matériels différents mais censés être, in fine, exploités de la même façon par l'utilisateur.
Par contre, si tu exploites du matériel spécifique dans un seul cas d'utilisation avec un logiciel dédié exclusivement, ça ne sert à rien d'intercaler un pilote entre les deux.
À priori user space quand même, surtout si c'est au travers d'une liaison RS/232 qui, elle, est déjà bien prise en charge par le kernel. Non seulement la programmation peut être un cauchemar à déboguer (si ton pilote plante, c'est tout le système qui s'écrase. Ça ne se finira pas en simple segfault…) mais en plus, il faudra faire des appels internes pour aller revendiquer temporairement l'interface qui est faite pour être appelée via des appels système utilisateur normaux. Ça compliquerait un développement qui est censé être facilité quand il fait en user space.
[^] # Re: Pour quelles applications ?
Posté par Anthony Jaguenaud . Évalué à 8.
Je suis d’accord avec ce que dit Obsidian.
Pour choisir si on fait un pilote ou pas, il faut voir quelle interface on veut.
Si ça se prête bien à un usage « device » bloc ou caractère, le pilote est intéressant.
S’il faut ajouter des appels système, c’est plus chiant et n’a aucun intérêt par rapport à une lib en espace utilisateur dans ton cas.
Dans l’intermédiaire, tu peux faire un device qui ne réagit que aux ioctl… mais je pense que c’est encore plus compliqué.
Or boulot, l’aspect driver permet de jouer avec et c’est sympas. Par contre, quand ça plante c’est plus compliqué à débbuguer.
[^] # Re: Pour quelles applications ?
Posté par freem . Évalué à 3.
Merci pour ces retours.
Malgré que ça me tentait pas mal, je pense que ce ne serait pas le plus pertinent du coup, ou du moins, pas encore, les diverses cartes à piloter me semblent avoir une interface trop hétéroclite du coup.
[^] # Re: Pour quelles applications ?
Posté par Obsidian . Évalué à 2.
Là, par contre, ça peut être intéressant de développer une couche d'abstraction au-dessus de tout ça.
[^] # Re: Pour quelles applications ?
Posté par freem . Évalué à 2.
C'est ce que j'aimerai faire, oui. Le problème c'est qu'entre une carte qui active/désactive des relais et lis des valeurs de capteurs, une autre qui permets la communication avec avec des voitures électriques (pour la charge, protocole ZE ready IIRC), et les autres qui vont arriver pour d'autres projets, j'ai un peu de mal à voir un tronc commun, d'autant qu'a l'heure actuelle on ne peux même pas savoir la version ou le rôle des cartes en les interrogeant (ce qui devrait changer prochainement vu que j'en ai émis l'idée et qu'il y avait de toute façons d'autres corrections à appliquer).
Du coup, il est très difficile de savoir (proprement) quelle cartes sont à quelles adresses sur le bus (dans le cas du 485) voire même sur quel bus (pour les divers 232 et 485).
Accessoirement, toutes les fonctionnalités sont dans un seul binaire, très difficile à maintenir, raison pour laquelle je me suis dit que déplacer le code lié au hard dans des pilotes serait une piste intéressante, pour débloater un peu le bouzin (qui n'est, bien sûr, absolument pas documenté).
[^] # Re: Pour quelles applications ?
Posté par Obsidian . Évalué à 3.
Effectivement.
Bon, comme on l'a dit, on développe un pilote pour un produit dès lors que ce produit réalise à sa manière une tâche qui est déjà connue et identifiée dans ses grandes lignes par l'utilisateur et/ou le système d'exploitation. Par exemple, si l'une de tes cartes était une imprimante, ça vaudrait le coup de l'associer à l'existant pour pouvoir automatiquement profiter des facilités de composition et de mise en page.
Ça reste une bonne idée en soi. C'est juste que ces modules ne seraient pas forcément des pilotes.
Tu peux déjà faire un distingo entre le côté matériel, de bas niveau, et le haut de la pile, c'est-à-dire son exploitation par l'utilisateur. Comment fonctionne globalement cette application à l'écran ? Est-ce qu'il y a juste un menu du style « 1. … 2. … 3. … 4. … 5. … » qui se contente de basculer vers une application distincte à chaque fois, ou est-ce que l'on a, par exemple, un tableau de bord qui serait toujours présent ?
Tu peux aussi t'inspirer d'OBD2 (le protocole de la prise diagnostic des voitures) qui, d'un côté, spécifie le protocole lui-même et, de l'autre, une quantité impressionnante de codes produits et des réponses qu'ils peuvent envoyer, sachant que chaque véhicule n'implémente qu'un petit sous-ensemble de cette liste (correspondant aux équipements réellement embarqués dans le véhicule). Et ensuite, tu regardes si, à chaque fois, tu peux inscrire une carte donnée dans ce cadre.
M'enfin cela ne reste que des pistes de réflexion. Il n'y a rien de pire qu'un standard écrit à l'arrache au départ et qu'il faut ensuite maintenir par compatibilité pendant des décennies (sans exagérer).
[^] # Re: Pour quelles applications ?
Posté par freem . Évalué à 3.
En effet. Je n'ai pensé aux pilotes qu'en second, ma première idée à été de refondre vers une architecture type client-serveur, qui permettrait d'isoler de manière claire les sections bas-niveau d'une part entre elles, et d'autre part du code de plus haut niveau.
Mais l'envie de jouer avec des pilotes est malgré tout assez forte :p
Pour ce qui est des écrans, à l'heure actuelle on est sur une interface type texte, oui, mais il est prévu de passer à un truc plus user-friendly.
Je le sais bien, c'est pour ça que j'ai posé cette question justement: je voulais avoir des éléments pour guider ma pensée avant d'agir bêtement et de risquer de finir avec un truc pire que l'existant (quoique, pour ça, il faudrait probablement que j'en fasse exprès…). Quant à la maintenance, le code à déjà au moins 2 ans, mais cumule à la fois les défauts de jeunesse et une dette technique impressionnante. Enfin, on m'a un peu expliquer les antécédents donc je peux comprendre, mais je n'ai pas trop envie de travailler avec un code aussi inutilement complexe, sachant qu'en plus je vais être le seul à intervenir dessus, théoriquement.
[^] # Re: Pour quelles applications ?
Posté par Obsidian . Évalué à 3.
En fait, sans surprise, je me reconnais beaucoup de mon parcours de développeur dans tes propos, et effectivement, avoir un bon prétexte pour étudier une certaine partie d'une technologie, est généralement le meilleur moyen de s'y mettre, tant au niveau de la motivation que du support de travail.
Pourtant, deux ans, ce n'est pas grand chose. :)
Faire du vrai nettoyage, voire du refactoring, et même in fine un plan de transition douce d'une techno à l'autre sans interruption de service sont des projets extrêmement intéressants en eux-mêmes, surtout avec des outils comme Git (une fois qu'on le maîtrise bien). À condition d'arriver à le faire admettre, comme on en parlait ailleurs. C'est toujours pénible quand on a un chef qui nous dit qu'on a pas le temps de tout ré-écrire quand on est face à une bouse infâme et qui donne ensuite l'ordre exact inverse une fois qu'on a fini d'appréhender la chose.
Que tu le nettoies ou que tu le refasses entièrement, profites-en pour le documenter. C'est une bonne occasion de le faire parce que tu ne seras pas poussé aux fesses pour sortir en temps et en heure un produit qui n'existe pas encore. Et tant qu'à faire, essaie de faire quelque chose qui soit auto-généré, donc soit du Doxygen, soit une page de référence interactive à la manière de celle d'Apache.
Je le dis d'expérience parce que pour avoir travaillé sur un gros projet interne à une compagnie, il m'a fallu beaucoup de temps pour m'approprier la chose et une fois cela fait, je n'avais plus le temps de documenter mes propres contributions. Pourtant, le leader initial du projet a eu le bon goût (parce qu'on lui a demandé) d'écrire un gros document dans un traitement de texte (écrit comme un livre, donc) pour présenter la chose. C'était bien, mais c'était assez rébarbatif à lire, c'était un cours presque déjà obsolète étant donné la rapidité des cycles de développement, et surtout : ce n'était de fait pas un « manuel », quelque chose qu'on pourrait directement ouvrir à la bonne page quand on travaille sur un point particulier du projet.
[^] # Re: Pour quelles applications ?
Posté par freem . Évalué à 2.
Même sans refactoring, je suis en train de documenter cette chose… pas le choix si je veux y voir ne serait-ce qu'un peu et éviter de tout péter au moindre commit… parce que la, c'est du boulot sans procédure d'install, sans description de quels ports sont ouverts et dans quels protocoles (tcp? udp?), sans API décente, avec du zombie de tous les côtés, et j'en oublie. J'ai même trouvé cet aprem une classe qui encapsule les sockets BSD et… euh… y'a un peu un membre qui n'est jamais écrit (sauf init, c'est déjà ça) mais donc la valeur est utilisée par listen, bind, accept et close. Youpi. Y'a un bug, c'est sûr, mais comment ça se fait que ça semble marcher en prod?
Et tu l'auras deviné: debug en prod: essayer de reproduire l'environnement de prod à base de VM risque de me prendre encore quelques heures, au bas mot.
Bref: je pleure.
C'est bien mon intention.
Généralement, j'utilise doxygen, mais contrairement à pas mal de choses que je vois, je me contente d'expliciter les pré-requis et post-conditions, avec quand nécessaire (je sais que tout le monde n'est pas d'accord, mais régulièrement les noms d'une fonction et de ses arguments se suffisent à eux-même) une description du rôle du code. Les "doc doxygen" dans lesquelles on peut lire "GetSize(): retourne le nombre d'éléments" me filent des boutons et sont malheureusement les plus répandues de mon expérience.
Après, l'auto-génération ne fait pas tout, surtout quand on a affaire à des usines à gaz dont l'architecture, n'en déplaise potentiellement aux auteurs, n'a jamais été pensée.
Faire du multi-thread parce que c'est la mode, c'est pas ce que j'appelle réfléchir à une archi pérenne et maintenable (dans un truc ou la performance n'est pas critique et ou donc utiliser des processus ou même simplement des IO bloquantes avec du polling aurait suffit tout en étant 1000 fois plus lisible)
Désolé pour la râlerie, mais là, j'avais besoin :/
Je ne commente généralement presque pas mon code, mais j'essaie au maximum d'en expliciter les contrats: le jour ou j'ai lu pour la 1ère fois ce dont il s'agit à changé à tout jamais ma façon de programmer, et honnêtement, je pense que ces quelques heures de lecture m'ont fait gagner bien des jours de debug :)
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.