Questo articolo inaugura una serie di brevi pezzi tecnici su un argomento particolarmente in voga negli ultimi anni:
La transizione da sistemi embedded microcontroller-based a sistemi embedded Linux-based.
I motivi di questo cambiamento sono molteplici: tra essi possiamo citare la limitatezza delle risorse sui sistemi basati su microcontrollore e la sempre maggiore necessità di connettività e sicurezza.
Certamente esistono moltissime applicazioni la cui natura real-time suggerisce il mantenimento di un’architettura a microcontrollore con sistemi real-time proprietari; ma, nella maggioranza dei casi, la mancanza di necessità di un RTOS (Real-Time Operating System), fa spostare l’ago della bilancia decisamente verso la scelta di un sistema Linux-based.
I want a root filesystem!
The root filesystem is the filesystem that is contained on the same partition on which the root directory is located, and it is the filesystem on which all the other filesystems are mounted (i.e., logically attached to the system) as the system is booted up[1].
[1] www.linfo.org/root_filesystem.html
Una volta stabilito che il nostro sistema deve utilizzare un root filesystem Linux, la domanda da porsi è: qual è il modo migliore per crearlo?
Le possibilità sono varie:
- Multistrap (creare un filesystem a partire da una distribuzione esistente – ad esempio Debian)
- Buildroot
- Yocto
- Altre soluzioni fatte-in-casa
Come spesso accade di fronte a domande di questo tipo, la risposta non è e non può essere definitiva: ognuno di questi sistemi (eccetto la soluzione fatta-in-casa, certamente da evitare) presenta vantaggi e svantaggi, e la scelta può quindi rivelarsi funzione delle preferenze personali e – soprattutto – dei requisiti di progetto.
Yocto e sistemi embedded: la nostra scelta
Le motivazioni della nostra scelta sono poche, ma inappuntabili:
- Ampia disponibilità sul mercato di prodotti (ad esempio SOM – System on Module solutions) forniti di SDK e BSP Yocto.
- Necessità di integrare componenti Yocto esistenti forniti dal cliente.
- Elevata manutenibilità ed estensibilità.
Di fatto, tutti e tre i punti sono riconducibili alla struttura a layers – comunemente detti meta-layers – di Yocto:
- I produttori forniscono SDK e BSP sotto forma di Yocto meta-layer (ad esempio meta-intel).
- I clienti detengono i propri Yocto meta-layer che astraggono dall’hardware per implementare funzionalità comuni a diversi prodotti (ad esempio la gestione degli utenti, degli aggiornamenti, etc).
- I meta-layers sono la base per estensibilità e manutenibilità di sistemi complessi, garantendo una netta separazione tra i diversi componenti.
Ad esempio, il layer meta-intel è un parent-layer che contiene layers per le diverse BSP Intel supportate, mentre il layer meta-qt contiene i metadati per l’integrazione delle librerie QT.
A META-LAYER CONTAINS THE META DATA. META-DATA MEANS CONF, CLASSES, AND RECIPES.
Un meta-layer non contiene dati (in primis files sorgenti), ma i metadati necessari per generare il set di componenti forniti dal layer.
Yocto: Il progetto
Una corretta organizzazione a layers consente di ottenere un progetto facilmente manutenibile ed estensibile, che può anche essere rapidamente compilato per architetture diverse.
Vediamo un progetto di esempio definito genericamente come segue:
- Hardware: HMI (piattaforma Intel-based a 32 bits dotata di schermo LCD e touchscreen)
- Cliente: ACME
- Dominio: Vehicle Localization System
- Requisiti: esecuzione di applicativi grafici QT 5
Omettiamo gli steps necessari per il setup dell’ambiente Yocto: un quick-start per la versione 2.6 (Thud) può essere trovato al link: https://www.yoctoproject.org/software-overview/layers/bsps/thud-261-cascade-lake/.
Per il progetto di cui sopra, utilizzando Yocto 2.6, la struttura di directory derivante dovrebbe essere:
├── bitbake
├── documentation
├── meta
├── meta-hmi
├── meta-intel
├── meta-openembedded
├── meta-poky
├── meta-qt5
├── meta-selftest
├── meta-skeleton
├── meta-acme-localization
├── meta-yocto-bsp
├── oe-init-build-env
└── scripts
I layers sui quali ci vogliamo soffermare sono:
- meta-intel: supporto per l’hardware Intel
- meta-qt5: supporto per le QT 5 (5.11 su Thud)
- meta-hmi: layer proprietario – supporto per il sistema specifico:
- kernel da usare e sua configurazione
- supporto touchscreen e backlight
- inclusione QT5
- meta-acme-localization: layer proprietario – ricette cliente per la creazione di un rootfs generico per dispositivi utilizzati nel dominio applicativo.
Volendo portare il nostro progetto ad un nuovo device, ad esempio HMI2 (64 bits), sarà sufficiente rimpiazzare il layer meta-hmi con un layer meta-hmi2 configurato per hardware 64 bits.
Per concludere questa breve introduzione su Yocto e sistemi embedded, riportiamo il concetto fondamentale da tenere sempre presente nella customizzazione dei layers:
NO DIRECT MODIFICATIONS ON COMMUNITY LAYERS.
Ogni modifica diretta ai layer esistenti deve essere fatta solo sui layers proprietari: questo vuol dire che ogni modifica necessaria ai layers esterni deve essere effettuata mediante i meccanismi consentiti (ad esempio il bbappend) a partire dai layers proprietari, ma mai facendo branches e commits sui repository esterni.
Questo eviterà di mantenere pericolosi branch dei layers esterni, e consentirà di migrare il proprio progetto a versioni successive di Yocto in modo abbastanza semplice.
Nel prossimo articolo sul nostro Blog vedremo meglio l’integrazione di layers con repo.