QUAND J'AI TRAVAILLÉ SUR UN PROJET : « Nous ne devrions pas avoir peur de recommencer » – une interview avec David Markesic, ingénieur logiciel embarqué senior
Comment savoir quand un retour au lancement est la bonne décision ? Afin de mener un projet à son terme de manière efficace et dans les délais, quelle est la meilleure approche pour ne pas perdre de vue la perspective tout au long du projet ?
Lisez un entretien avec David Markesic, notre ingénieur logiciel embarqué senior basé en Zagreb bureau depuis 2021. Dans un échange animé par Marija Jurina, notre spécialiste de l'Employer Branding, David se confie sur son parcours dans ce domaine, les leçons apprises et pourquoi il est parfois acceptable de remettre un projet à zéro.
Marija Jurina : Bonjour David, c'est un plaisir de vous avoir pour partager vos connaissances et votre expérience. Pour commencer, depuis combien de temps travaillez-vous en tant qu'ingénieur embarqué et comment êtes-vous arrivé dans ce domaine de l'informatique ?
David Markesic : Bonjour, merci de m'avoir invité, je suis ravi d'être ici et de partager mon parcours professionnel. Cette année, cela fera 8 ans que je travaille comme ingénieur embarqué. Au départ, j'ai commencé comme ingénieur matériel, mais j'ai toujours touché au logiciel embarqué dans le but de donner vie au matériel. Cette passion s'est développée naturellement au cours de ma carrière et a rapidement évolué vers le développement logiciel embarqué à part entière.
Je comprends que dans l'un de vos projets précédents, vous avez rencontré un défi intéressant de communication entre le modem 3G et le microcontrôleur (MCU). Pour partager un exemple concret, pouvez-vous nous expliquer quelle était l'idée initiale et le besoin dans ce cas ?
Oui, je serais heureux de développer. L'idée initiale était d'utiliser un modem 3G comme source de réveil pour le MCU via Internet. Pour développer brièvement — le modem 3G devait maintenir la connexion à Internet active pendant que le MCU était hors ligne et ne réveiller le MCU qu'en cas d'erreur de connexion ou de demande de réveil. La raison réside dans le fait que nous devions réduire la consommation d'énergie de la batterie lorsque l'appareil était éteint. Le MCU était uniquement utilisé pour configurer la connexion Internet au réseau mobile et la connexion au serveur utilisé pour les demandes de réveil. La communication (configuration et échange de données) était effectuée à l'aide de commandes AT. Pour une configuration correcte du modem 3G, qui couvrirait tous les cas d'utilisation, une séquence de configuration assez complexe avec de nombreuses décisions différentes basées sur les réponses du modem 3G était nécessaire. Ainsi, j'ai été chargé de créer un analyseur approprié pour les commandes AT qui pourrait gérer toutes les complexités du cas d'utilisation.
Que fallait-il pour simplifier la prise de décision à partir des réponses du modem 3G ?
La communication du modem 3G était effectuée via UART à l'aide de commandes AT. Afin de configurer correctement le modem 3G pour maintenir une connexion Internet fiable, le parseur devait gérer des séquences complexes de commandes AT qui devaient être envoyées, reçues et traitées. Dans ce cas, la réponse était constituée de chaînes contenant un mélange de chaînes et de nombres. Ainsi, le parseur que j'ai développé devait remplir une double fonction : d'une part, il devait être capable d'analyser les nombres contenus dans les chaînes pour les convertir en nombres natifs (entiers), et d'autre part, il devait pouvoir effectuer une extraction de chaînes à partir des réponses.
Qu'y avait-il de distinctif dans l'architecture du parser que vous avez développé ?
Je dirais que la distinction réside dans le fait que le parseur n'a pas tenté d'utiliser la correspondance de motifs ou les expressions régulières (regex) sur les chaînes, mais a plutôt analysé les réponses caractère par caractère. Cette approche m'a permis d'éviter les opérations coûteuses en temps sur les chaînes jusqu'à ce qu'un traitement de chaîne soit nécessaire. Ainsi, au lieu d'effectuer une extraction de chaîne, seuls les index étaient stockés.
Après la tokenisation, plusieurs étapes distinctes ont suivi. D'abord, le nom a été reconnu, puis le type de réponse, après quoi l'extraction et la conversion des données ont été effectuées si nécessaire.
Il convient de mentionner que nous avons ainsi également obtenu une vérification complète et intégrée des erreurs dans les réponses reçues. En substance, comme l'analyseur parcourt une liste de tokens, il sait quel type de tokens attendre, ou plutôt quels tokens sont valides d'après la spécification des commandes et réponses AT pour le modem 3G, ce qui facilite la gestion des erreurs. Ces étapes, couplées à l'API de composition des commandes AT, nous ont permis de créer et de modifier facilement les séquences de commandes pour un développement rapide et une approche plus agile des problèmes découverts en cours de route. Je tiens à souligner que l'API de lecture des données à partir des réponses et l'API de composition des commandes formaient un quasi-langage de programmation particulièrement adapté au traitement des commandes AT.

Qu'est-ce qui a pris le plus de temps dans le processus de recherche de la solution ?
L'élément le plus chronophage a été la tentative de créer une séquence de commandes robuste qui couvrirait tous les différents cas d'usage et cas limites, ainsi que la courbe d'apprentissage abrupte concernant les réseaux mobiles. De plus, l'un des défis majeurs résidait également dans le fait que la première tentative de communication avec un modem 3G s'appuyait sur un traitement de réponses simple utilisant les fonctions intégrées, qui se contentaient de faire correspondre les formats des réponses attendues et de renvoyer les paramètres sous forme de chaînes de caractères. Cela affectait et compliquait grandement le traitement des données et la prise de décision. L'analyse du cas d'usage et des exigences m'a conduit à conclure que la séquence elle-même était trop complexe et que d'éventuelles modifications futures seraient très difficiles à gérer si nous nous appuyions uniquement sur les fonctions intégrées. En substance, la méthode initiale était à la fois trop simple pour le cas d'usage et non pérenne. Ainsi, après mûre réflexion, il a été décidé d'abandonner la méthode de correspondance de chaînes et de rechercher puis de mettre en œuvre une approche différente. Afin de rendre la méthode aussi robuste que possible et également pérenne, il a été décidé que la meilleure voie à suivre serait de remplacer l'ancienne approche par l'approche de tokenisation de chaînes, que j'ai décrite ci-dessus.
Qu'est-ce qui aurait pu aider plus tôt dans le processus de développement pour accélérer les choses ?
Je pense qu'il aurait été bénéfique d'être plus précis et détaillé dans la composition des exigences afin que la planification de l'architecture logicielle puisse être réalisée plus efficacement. Une bonne base sous la forme d'exigences claires et concises est cruciale pour la planification et, en fin de compte, pour la rapidité du processus de développement. D'après mon expérience, une bonne préparation, une attention portée aux cas limites et des recherches rigoureuses, en tenant compte à la fois des limites des fonctions intégrées et de la pérennisation future, bien que cela semble chronophage, aboutissent globalement à un processus de développement plus court.
Merci pour cet échange et ce partage ! Si vous pouviez donner un seul conseil à vos collègues développeurs sur la manière de trouver des solutions plus facilement, quel serait-il ?
Je dirais que nous devons toujours garder à l'esprit l'objectif final, bien entendu. Mais les idées issues d'autres domaines de l'informatique peuvent parfois être applicables si elles sont adaptées à nos problématiques ; il faut donc assurément sortir des sentiers battus et s'efforcer de suivre autant que possible les différentes recherches et idées.
De plus, d'après notre expérience, nous ne devons pas avoir peur de repartir de zéro. Il est parfois plus bénéfique d'abandonner l'approche actuelle, quel que soit l'avancement du processus de développement, et d'essayer une autre voie qui répondra aux problèmes identifiés, permettra une maintenance plus facile et engendrera moins de dette technique.
Vous recherchez de nouvelles opportunités de carrière ? Découvrez les postes ouverts en Croatie !


FAQ
Un ingénieur système se concentre sur la manière dont les différentes parties d'un système interagissent et sur la façon dont les données circulent entre elles. Le rôle implique de comprendre la structure, les dépendances et le comportement à l'échelle du système entier plutôt que des composants individuels.
L'ingénierie système aide à définir comment les entrées sont interprétées, traitées et transformées en sorties pertinentes. Elle garantit que chaque étape – de l'analyse des données à la réponse finale – est cohérente et alignée sur les exigences du système.
En structurant les processus et en définissant des règles claires, l'ingénierie des systèmes rend les systèmes complexes plus faciles à comprendre et à maintenir. Elle introduit de l'ordre dans les interactions entre les composants et réduit le risque d'incohérences.
L'ingénierie des systèmes exige une approche holistique. Elle combine la compréhension technique avec la capacité de voir comment différents éléments se connectent et s'influencent mutuellement au sein d'un système plus large.
arrow_circle_right Contactez-nous
Vous envisagez votre prochaine étape dans la tech ?
Nous sommes toujours ouverts à la collaboration avec des experts de premier plan.
Envoyez-nous votre CV et nous vous contacterons dès qu'un nouveau poste correspondant à vos compétences et à votre expérience sera disponible.
arrow_circle_right Autres articles