Développeur Rust embarqué : no_std, FFI avec le C et contraintes temps réel

Le Rust embarqué se joue sans bibliothèque standard, sans système d'exploitation ou juste à côté de lui, et presque toujours avec du C déjà en place. Le niveau se voit vite à la façon de gérer la mémoire sans allocateur et de partager une donnée avec une interruption.

Recevoir la fiche complète

Mis à jour le Par l'équipe Delectus5 min de lecture

La fiche Développeur Rust système / embarqué : technologies, chaîne du poste, une question et la grille d'évaluation

Un développeur Rust système ou embarqué écrit le firmware d'un microcontrôleur en no_std, des pilotes, ou des services qui tournent sous un Linux embarqué construit avec Yocto. Les questions d'entretien d'un développeur Rust embarqué portent sur ce qui change par rapport au Rust serveur : pas de tas par défaut, des interruptions, des registres matériels et une cohabitation durable avec du code C.

Les offres publiées en France sont rares et associent presque toujours Rust à C ou C++, Yocto et Linux embarqué, avec des bus comme CAN ou I2C. Un profil Rust venu du back-end connaît très bien le langage et Tokio, mais n'a souvent jamais écrit de gestionnaire de panic ni lu un registre. À l'inverse, un développeur C embarqué qui s'est mis à Rust connaît la cible et doit montrer qu'il sait encadrer son code unsafe.

Demandez un projet sur une vraie carte : quelle puce, quel framework (RTIC, Embassy ou rien), quel outil pour flasher et déboguer. Le PDF contient un cas de 20 minutes sur la réécriture en Rust d'un module C qui décode des trames CAN.

L'écosystème Rust embarqué, de la puce à Linux

Rust no_std et core

En embarqué, le programme se passe de la bibliothèque standard et n'utilise que core, qui ne suppose ni système d'exploitation ni allocateur. Pas de Vec, pas de String, pas de threads : les structures ont une taille fixe connue à la compilation. Le crate alloc peut être ajouté avec un allocateur si le projet l'accepte.

cortex-m-rt, PAC et HAL

cortex-m-rt fournit le démarrage, la table des vecteurs et le point d'entrée sur les processeurs ARM Cortex-M. La PAC, générée depuis le fichier SVD du fabricant, donne accès aux registres. La HAL ajoute une interface plus simple pour les GPIO, l'UART ou l'I2C d'une famille de puces.

embedded-hal 1.0

Un ensemble de traits communs (I2C, SPI, GPIO, délais) publié en version 1.0 en janvier 2024, avec des variantes async et des utilitaires de partage de bus. Un pilote écrit sur ces traits fonctionne sur toute puce dont la HAL les implémente, et même sous Linux.

Embassy et RTIC

Deux façons d'organiser un firmware. Embassy fournit un exécuteur async et des HAL pour plusieurs familles de microcontrôleurs. RTIC planifie les tâches sur les priorités des interruptions et vérifie à la compilation l'accès aux ressources partagées. Certains projets n'utilisent ni l'un ni l'autre.

probe-rs et defmt

probe-rs flashe, lance et débogue un programme sur la carte à travers une sonde. defmt est un système de logs très léger : le microcontrôleur envoie des valeurs brutes et le formatage se fait sur le poste. Un candidat qui a travaillé sur une vraie carte les cite spontanément.

bindgen, cbindgen et cc

Les outils de la frontière avec le C. bindgen génère les déclarations Rust depuis un en-tête C, cbindgen fait l'inverse pour exposer du Rust au C, et le crate cc compile des sources C depuis Cargo. Dans un projet existant, une bonne part du travail se passe à cet endroit.

Yocto et Linux embarqué

Sous Linux embarqué, le service Rust est intégré à l'image par une recette Yocto qui utilise la classe cargo d'OpenEmbedded-Core, avec des dépendances figées pour un build sans réseau. linux-embedded-hal permet de réutiliser les pilotes embedded-hal sur Linux. Le Rust dans le noyau n'est plus considéré comme expérimental depuis décembre 2025.

Ferrocene et normes de sûreté

Ferrocene est une distribution du compilateur Rust qualifiée pour l'ISO 26262 (automobile, jusqu'à ASIL D), l'IEC 61508 (jusqu'à SIL 3) et l'IEC 62304 (dispositifs médicaux, classe C). Sur un projet soumis à ces normes, demandez quelle toolchain a été utilisée et comment le code unsafe a été justifié.

Le poste recouvre deux situations. Sur microcontrôleur, le développeur écrit un firmware no_std, souvent avec Embassy ou RTIC, et travaille au plus près des registres, des interruptions et de la mémoire. Sous Linux embarqué, il écrit des services ou des outils système en Rust, intégrés à une image Yocto, à côté de C et de C++ existants. Dans les deux cas, la frontière avec le C compte autant que le langage. Sur les logiciels soumis à une norme de sûreté, s'ajoutent la qualification de la toolchain et la justification du code unsafe. Il n'existe pas de certification Rust qui fasse référence : l'expérience sur une carte réelle se vérifie en entretien.

Points techniques à valider chez un développeur Rust embarqué

  • Programmation no_std et gestion mémoire
  • Interruptions, concurrence et temps réel
  • Code unsafe et accès au matériel
  • Interopérabilité FFI avec le C
  • Pilotes embedded-hal et intégration Yocto
  • Tests, outillage et sûreté de fonctionnement

Questions d'entretien Rust embarqué, avec la réponse attendue

Chaque question vient avec ce qu'une bonne réponse contient et le signal qui doit vous alerter. Pas besoin d'être technique pour les poser : écoutez si le candidat raconte du vécu.

  1. Question 1 · confirmé

    Votre firmware tourne sur un Cortex-M avec 64 Ko de RAM et sans allocateur. Comment gérez-vous un tampon dont la taille varie d'un message à l'autre ?

    Une bonne réponseAvec #![no_std], seul core est disponible : pas de Vec ni de String. Il fixe une capacité maximale connue à la compilation, avec des collections à capacité fixe comme heapless::Vec<u8, N>, un tampon circulaire ou un tableau statique dimensionné par des const generics. Il dit ce qui se passe quand un message dépasse la capacité (erreur renvoyée, message tronqué ou rejeté) et vérifie l'occupation mémoire au link, avec le fichier memory.x et la taille des sections.

    Signal d'alerteVec::new() « comme d'habitude », sans savoir que std n'existe pas sur la cible, ou un allocateur ajouté sans réfléchir à la fragmentation.

  2. Question 2 · confirmé

    Une routine d'interruption et la boucle principale modifient le même compteur. Comment le partagez-vous en Rust ?

    Une bonne réponsePas de static mut accédé librement : en édition 2024, le lint static_mut_refs refuse par défaut d'en prendre une référence. Un atomique (AtomicU32 avec fetch_add) si la cible le permet, en sachant qu'un Cortex-M0 n'a pas d'opération compare-and-swap et qu'il faut alors portable-atomic ou une section critique. Pour une donnée plus grosse, Mutex<RefCell<T>> avec critical_section::with, ou les ressources partagées de RTIC, protégées par priorité plafond sans masquer toutes les interruptions.

    Signal d'alertestatic mut dans un bloc unsafe « parce que ça marche sur le banc », sans voir la lecture-modification-écriture qui peut être interrompue.

  3. Question 3 · confirmé

    Il faut appeler depuis Rust une bibliothèque C existante qui alloue une structure et la libère avec sa propre fonction. Comment l'intégrez-vous ?

    Une bonne réponsebindgen génère les déclarations depuis l'en-tête C, dans un build.rs ou une fois pour toutes, et le crate cc compile la bibliothèque si elle est fournie en sources. En édition 2024, le bloc s'écrit unsafe extern "C". Il enveloppe le pointeur dans un type Rust qui le possède, vérifie le pointeur nul à la création et appelle la fonction de libération du C dans Drop. Le reste du code n'utilise que ce type sûr, et un panic ne doit jamais traverser la frontière vers le C.

    Signal d'alerteLe pointeur brut passé partout dans le code Rust, ou une libération par Box::from_raw d'une mémoire allouée par le C.

  4. Question 4 · confirmé

    Vous écrivez le pilote d'un capteur I2C qui doit tourner sur deux microcontrôleurs de fabricants différents. Comment le rendez-vous portable ?

    Une bonne réponseLe pilote est générique sur le trait embedded_hal::i2c::I2c de embedded-hal 1.0, sortie en janvier 2024, et éventuellement sur sa version async de embedded-hal-async. Il ne touche à aucun registre du microcontrôleur : chaque HAL de fabricant fournit l'implémentation. Les erreurs du bus remontent dans un type d'erreur du pilote. Les tests tournent sur le poste avec embedded-hal-mock, qui simule les échanges attendus.

    Signal d'alerteUn pilote écrit directement sur les registres d'un microcontrôleur, à réécrire pour le second, ou dépendant de la HAL d'un seul fabricant.

  5. Question 5 · confirmé

    Le produit tourne sous un Linux embarqué construit avec Yocto. Comment intégrez-vous un service Rust dans l'image ?

    Une bonne réponseUne recette qui hérite de la classe cargo d'OpenEmbedded-Core. Les dépendances listées dans le Cargo.lock deviennent des entrées SRC_URI, générées avec la classe cargo-update-recipe-crates (bitbake -c update_crates), pour que le build fonctionne sans accès réseau et reste reproductible. La version de rustc est celle fournie par la couche, à vérifier face au rust-version du projet. Puis une unité systemd, et un profil release réglé pour la taille (lto, strip, panic = "abort" si le service l'accepte).

    Signal d'alerteLe binaire compilé sur le poste du développeur et copié dans l'image, ou un build qui télécharge des crates pendant la construction.

Recevez la fiche d'entretien complète en PDF

La fiche pour mener l'entretien de bout en bout, prête à imprimer ou à partager avec le manager.

  • 30 questions sur 6 axes, avec la bonne réponse, le signal d'alerte et la relance
  • Le niveau visé pour chaque question
  • Une mise en situation de 20 minutes et ce qu'on attend du candidat
  • La grille d'évaluation de 1 à 4, axe par axe

Ce que les recruteurs demandent sur les profils Rust embarqué

Que manque-t-il à un développeur Rust back-end pour travailler en embarqué ?

Il connaît l'ownership, les traits et la gestion d'erreurs, ce qui fait gagner du temps. Il lui manque le reste : no_std, absence d'allocateur, interruptions, registres, lecture d'une datasheet et usage d'une sonde de débogage. Avec un bon accompagnement, la transition se fait, mais elle demande des mois. Vérifiez s'il a déjà fait tourner du code sur une carte, même dans un projet personnel, et demandez-lui comment il partagerait une donnée avec une interruption.

Faut-il préférer un développeur C embarqué qui apprend Rust ?

C'est souvent le profil le plus rapide à rendre productif, parce qu'il connaît la cible, les bus et les contraintes de temps. Le risque est d'écrire du C en syntaxe Rust, avec des pointeurs bruts et des static mut partout. Montrez-lui un bout de code avec un accès partagé à une interruption et demandez-lui comment il le rendrait sûr. Sa réponse dit s'il a compris le modèle de propriété ou s'il le contourne.

Comment évaluer un candidat Rust embarqué sur du code réel ?

Un test technique court en entretien, sur du code fourni : un pilote I2C écrit directement sur les registres d'une puce, à rendre générique sur embedded-hal, ou un module avec un static mut partagé avec une interruption, à corriger. Si vous avez une carte de développement, faites flasher un programme avec probe-rs. Vingt à trente minutes suffisent pour voir si la personne a déjà travaillé sur du matériel réel.

Rust est-il accepté sur les projets soumis à des normes de sûreté ?

Oui, avec une toolchain qualifiée. Ferrocene est qualifié pour l'ISO 26262 jusqu'à ASIL D, l'IEC 61508 jusqu'à SIL 3 et l'IEC 62304 classe C. Le reste du dossier ne change pas : exigences, traçabilité, tests et analyse des dépendances. Sur ce type de poste, demandez au candidat comment il a justifié le code unsafe et les crates tierces. L'expérience d'un processus de certification compte autant que la maîtrise du langage.

Pour structurer vos autres entretiens, consultez aussi nos pages sur les questions d'entretien de recrutement, la méthode de l'entretien structuré et la grille d'évaluation d'entretien.

Les fiches voisines

Toutes les fiches →

Voyez Delectus sur vos propres offres.

Commencez gratuitement. Passez à l'échelle quand vous êtes prêt.

Demander une démo

Votre ATS, connecté à Delectus

  • Workable
  • Teamtailor
  • iCIMS
  • Lever
  • SmartRecruiters
  • Jobvite
  • Greenhouse
  • Pinpoint