Iniziare con DevOps per Sistemi Embedded utilizzando l'ATmega328P

Ari Mahpour
|  Creato: maggio 29, 2024  |  Aggiornato: luglio 1, 2024
Iniziare con DevOps per Sistemi Embedded utilizzando l'ATmega328P

DevOps e le metodologie Agile hanno trasformato lo sviluppo software enfatizzando la collaborazione, l'automazione e il miglioramento continuo. Applicare i principi DevOps ai miei progetti e disegni è stato un cambiamento radicale, migliorando l'efficienza e l'affidabilità. In questo articolo, andremo a vedere come impostare un flusso di lavoro di integrazione continua (CI) per un progetto di sistemi embedded esistente che utilizza il microcontrollore ATmega328P. Alla fine di questo articolo, vedrai come queste pratiche possono semplificare il tuo processo di sviluppo e fornire prodotti di qualità superiore.

Comprendere DevOps e Agile per i Sistemi Embedded

DevOps è un insieme di pratiche, popolarizzato nel mondo del software, che collega lo sviluppo software (Dev) e le operazioni IT (Ops) in un flusso continuo. Nel mondo del software, era comune sviluppare software e "lanciarlo oltre il muro" alle persone delle operazioni per il dispiegamento ai clienti. DevOps ha introdotto un modo non solo per abbattere quel muro ma per automatizzare l'intero processo da un capo all'altro. Nel mondo dell'hardware troviamo somiglianze tra lo sviluppo del prodotto e la produzione, lanciando costantemente il design "oltre il muro" ai nostri team di ingegneria di produzione per assicurarsi che tutto sia pronto per la produzione.

Nel design di prodotti embedded dobbiamo ancora far passare il nostro software attraverso la produzione ma ci troviamo di fronte alla sfida di muoverci più velocemente che mai e di consegnare alla massima qualità possibile. Con i principi DevOps miriamo a risolvere alcune di queste sfide.

  • Dipendenze Hardware: I sistemi embedded dipendono dall'hardware e da specifiche revisioni di quei PCB. Questo può rendere complessi i test e il dispiegamento se non semplificati per essere automatizzati e altamente scalabili. Le pratiche DevOps aiutano ad automatizzare questi processi utilizzando la stessa configurazione sia per l'hardware che per il software e inserendoli in sistemi di integrazione continua (CI) automatizzati.
  • Lunghi Tempi di Costruzione: Configurare la costruzione del software embedded può essere difficile e risultare in lunghi tempi di costruzione. La CI automatizza e velocizza questo processo scaricando le costruzioni sul cloud utilizzando istanze più potenti a cui gli sviluppatori normalmente non hanno accesso.
  • Test Manuali: I test su hardware reale sono essenziali ma spesso manuali, noiosi e richiedono molto tempo. L'automazione attraverso i test hardware-in-the-loop (HIL) migliora l'efficienza e l'accuratezza e può essere delegata a un setup di apparecchiature di test automatizzate configurate con il tuo sistema CI.

Applicando i principi DevOps siamo in grado di iterare rapidamente utilizzando le metodologie Agile all'interno del paradigma costruisci-testa-distribuisci per ogni ulteriore funzionalità che desideriamo rilasciare in produzione.

Come Funziona Tutto

“Costruire, testare e distribuire” è un insieme comune di parole che spesso sentirete quando si discute di DevOps. Nei sistemi embedded facciamo la stessa cosa poiché anche il nostro deployment va in produzione (e poi al cliente finale). Nel repository del progetto utilizziamo Gitlab CI per guidare il nostro workflow end-to-end per Embedded DevOps. Utilizziamo quello che viene chiamato “pipelines” per creare lavori che raggiungono determinati compiti come compilare il software, eseguire test sul target o rilasciarlo come un pacchetto ufficiale. In Gitlab, una pipeline è una collezione di lavori che vengono eseguiti in una sequenza come questa:

Esempio di pipeline

Figura 1: Esempio di pipeline utilizzata con il workflow DevOps ATmega328P in Gitlab

Ecco una suddivisione dello script CI (.gitlab-ci.yml file) per darvi un'idea di come funziona.

  • Docker: Come discusso in Containerizzazione degli ambienti di build e runtime per il testing Hardware in the Loop, questa fase costruisce immagini Docker per creare un ambiente consistente per costruire, testare e flashare il codice. Questo assicura che il processo di build sia riproducibile su macchine e architetture diverse (come un PC desktop rispetto a un Raspberry Pi).
  • Test: Questa fase esegue test unitari per verificare che il tuo codice faccia quello che intendi fare. I test automatizzati sono veloci e importanti quando si modifica o si rifattorizza il codice esistente.
  • Build: Questa fase compila il codice sorgente in binari. In questo progetto genera artefatti come file .elf e .hex, che sono utilizzati per flashare il chip ATmega328P.
  • HIL (Hardware-in-the-Loop): Questa fase coinvolge il test del software su hardware reale per assicurarsi che funzioni correttamente in condizioni reali. Carica il software sull'hardware ed esegue test per verificare che la funzionalità che abbiamo progettato funzioni effettivamente sul prodotto finale.
  • Deploy: Questa fase gestisce la pubblicazione degli artefatti costruiti su un registro di pacchetti, rendendoli disponibili per l'uso.
  • Release: Questa fase crea una nuova release del software, automatizzando il processo di consegna per assicurare aggiornamenti rapidi e affidabili. Questo è ciò che il team di produzione utilizzerebbe per recuperare la versione del software necessaria per il loro intero assemblaggio del prodotto.

Dettagli Fini

Ci sono alcuni dettagli minori che portano questo workflow da un'implementazione DevOps basilare a un sistema che funziona senza intoppi, ben documentato e facilmente osservabile. Ci sono alcuni dettagli sottili all'interno del workflow CI che sono importanti da sottolineare.

  • Versionamento Semantico: Impostare una versione, sia tramite un meccanismo automatizzato che manualmente, è estremamente importante per il ciclo di rilascio, specialmente quando si lavora con la produzione. Come esempio, questo viene impostato come una variabile all'interno dello script CI e poi utilizzato nei lavori di pubblicazione e rilascio.
  • Logica di costruzione Docker: Noterete che c'è un blocco di logica che viene utilizzato per le costruzioni dei container Docker:

 


if [ "$CI_COMMIT_REF_SLUG" == "$CI_DEFAULT_BRANCH" ]; then

  export IMAGE_TAG=$CI_REGISTRY_IMAGE/$IMAGE_TYPE:latest

else

  export IMAGE_TAG=$CI_REGISTRY_IMAGE/$IMAGE_TYPE:$CI_COMMIT_REF_SLUG

fi

 

Questa logica prepara il terreno affinché il nostro tag “latest” utilizzi solo l'immagine Docker costruita sul ramo principale (cioè dopo che una richiesta di merge è stata approvata con successo). Questo garantisce che solo le richieste di merge riuscite pubblichino l'immagine docker più recente e migliore da cui tutti e ogni pipeline attingono.

  • Report e Copertura: Nei moderni sistemi CI come Gitlab siamo in grado di estrarre e visualizzare report di test e copertura all'interno delle nostre richieste di merge e pipeline. Ad esempio, in questa richiesta di merge abbiamo catturato la copertura del codice:
Copertura del codice all'interno di una richiesta di merge

Figura 2: Copertura del codice all'interno di una richiesta di merge

In questo screenshot, Gitlab riassume i test eseguiti sul target utilizzando hardware in loop:

Riepilogo dei test per i test eseguiti sul target

Figura 3: Riepilogo dei test per i test eseguiti sul target

Alla fine, una volta che il nostro codice è stato validato sia con test unitari sia sul target, le fasi di pubblicazione e rilascio generano un bel pacchetto che può essere consumato dal team di produzione:

Rilascio del pacchetto software

Figura 4: Rilascio del pacchetto software

Con tutti questi passaggi automatizzati possiamo rilasciare una nuova funzionalità in modo iterativo seguendo un approccio Agile. Non c'è bisogno di sviluppare molte funzionalità, inviarle al dipartimento QA e poi una revisione per il rilascio del pacchetto da parte del team di produzione. Tutto qui avviene in un unico flusso di lavoro ed è completamente automatizzato.

Conclusione

In questo articolo, abbiamo esplorato come le metodologie DevOps e Agile possono essere applicate allo sviluppo di sistemi embedded, specificamente utilizzando il microcontrollore ATmega328P. Abbiamo discusso i benefici dell'implementazione di un flusso di lavoro CI in Gitlab, che include automazione, tempi di costruzione più rapidi e test efficienti. Decomponendo lo script CI e spiegando ogni fase, abbiamo mostrato come creare un processo di sviluppo robusto e snello che aumenta l'efficienza e la qualità del prodotto. Seguendo questa guida pratica (e il codice sorgente all'interno del repository) dovresti essere in grado di configurare anche tu il tuo flusso di lavoro Embedded DevOps.

Il codice sorgente del progetto può essere trovato qui:https://gitlab.com/embedded-designs/atmega328p-serial-led-control.

Sull'Autore

Sull'Autore

Ari è un ingegnere con una solida esperienza nei campi di progettazione, produzione, collaudo e integrazione di sistemi elettrici, meccanici e software. Ama riunire gli ingegneri addetti alla progettazione, alla verifica e al collaudo e farli lavorare insieme come un'unità affiatata.

Risorse correlate

Documentazione Tecnica Correlata

Tornare alla Pagina Iniziale
Thank you, you are now subscribed to updates.