Buildroot è un insieme di script utilizzati per costruire un root file system o un ambiente di lavoro per un determinato target e tra questi AVR non poteva certo mancare: come inserire una scheda custom in buildroot? Eccovi le risposte.
Ogni sviluppatore ha la possibilità di definirsi il proprio ambiente di lavoro. Senza la possibilità di utilizzare sistemi di tipo automatico diventa estremamente difficile intervenire su ogni fase impostando in modo appropriato ogni opzione per ciascun tool di sviluppo. Buildroot è un ottimo strumento di lavoro che permette di definire la nostra applicazione in modo estremamente semplice e diretto senza per questo conoscere ogni dettaglio di ciascuna fase. Esiste anche da diverso tempo la possibilità di utilizzare una versione di Buildroot per ambiente Atmel, in modo particolare per la linea dei processori AVR.
A volte può essere necessario intervenire sul tool per aggiungere, magari, una nostra board. In questo caso è necessario interagire direttamente con il cosiddetto buildroot build system al fine di inserire le definizioni utili per rintracciare e configurare direttamente la nuova scheda. Disporre di una custom board è utile al file di poter interagire direttamente con il proprio progetto: una definizione di questo tipo deve anche contenere le patch specifiche della board e la configurazione del Buildroot. Buildroot è costituito da diversi script, makefile e kconfig. Kconfig risulta molto utile per interfacciarsi in modo grafico con le configurazioni del sistema. I diversi makefile disponibili in Buildroot utilizzano i diversi script presenti al fine di configurare correttamente l’ambiente di lavoro. Buildroot può essere utilizzato con diverse toolchain. L’intero sistema, una volta che il kernel Linux con le relative librerie di supporto è stato compilato correttamente, combina tutte le applicazioni con le librerie necessarie e, insieme al kernel, ricava un file immagine di sistema. Una volta terminata la fase di generazione dell’oggetto, l’immagine può essere inserita sul target attraverso un opportuno programmatore. In definitiva, Buildroot è un insieme di makefile che permettono di automatizzare il processo di building di una toolchain di cross compilazione e un root filesystem per un sistema embedded. Ogni distribuzione di buildroot adotta un’opportuna struttura gerarchica dove ogni cartella ha un preciso ruolo all’interno della distribuzione stessa, a questo riguardo la tabella 1 mostra il significato di ogni cartella. Per questa ragione se volessimo inserire un nuovo target, ad esempio basata su processore Atmel, dobbiamo inserire una nuova definizione nella struttura gerarchica /target/device. In sostanza occorre, per prima cosa, creare una struttura e una serie di file in grado di definire le indicazioni della nostra board e associare a questa tutti i riferimenti in fatto di configurazione. È necessario creare una cartella rispettando la gerarchia target/device/ e avendo cura di identificare la società o l’organizzazione a cui facciamo parte, ad esempio:
/target/device/nostra_organizzazione o
/target/device/nostra_board o ancora
/target/device/yourcompany
In seguito occorre aggiungere alcuni statement nel file “target/device/Config.in” al fine di identificare la nostra nuova board (“/target/device/nostra_organizzazione/Config.in”, o “/target/device/Atmel/Config.in”), listato 2. È opportuno, magari, utilizzare una definizione già presente e modificare i vari campi contenuti. Nella cartella “/target/device/nostra_organizzazione” occorre poi definire la cartella del nostro progetto. In questo modo è possibile utilizzare la cartella al fine di contenere ogni riferimento alla nostra custom board all’interno di Buildroot. Successivamente inserire nel file “/target/device/nostra_organizzazione/Config.in” le seguenti linee:
menuconfig BR2_TARGET_COMPANY bool “Company projects” if BR2_TARGET_COMPANY config BR2_TARGET_COMPANY_PROJECT_ FOOBAR bool “Support for Company project Foobar” help This option enables support for Company project Foobar endif
Attenzione alle diverse label perché devono essere utilizzate rispecchiando le definizioni reali del nostro progetto. In seguito è necessario anche creare il file “target/device/nostra_board/Makefile.in” con la seguente linea di codice:
ifeq ($(BR2_TARGET_COMPANY_PROJECT_ FOOBAR),y) include target/device/yourcompany/project- foobar/Makefile.in endif
Può anche risultare utile definire una variabile BOARD_PATH.
Successivamente, è necessario anche creare il file in “target/device/yourcompany/project-foobar/Makefile.in”, con project-foobar si deve identificare il nostro target.
Una variabile BOARD_PATH può essere utile per trattare il campo “target/device/yourcompany/project-foobar” semplificando così le definizioni, allo stesso modo della variabile TARGET_SKELETON. Finalmente in “target/device/yourcompany/project-foobar/” è ora possibile definire il file di configurazione per il kernel, Busybox o uClibc.
DEFINIRE LA NOSTRA CUSTOM BOARD
Cominciamo a dare un nome logico alla nostra board, come ad esempio avrboardnew o avrboardnew-base. In questo modo tutti i file associati alla board saranno inseriti nella struttura gerarchica “target/device/Atmel/avrboardnew” o “target/device/Atmel/avrboardnew-base”. Con Buildroot possiamo realizzare le configurazioni da utilizzare per la definizione di Linux e Busybox. Ricordiamo che Busybox è un’insieme di tool Linux, da ls a echo, strutturati in un unico eseguibile al fine di ridurre lo spazio occupato. Il kernel di Linux ha la necessità di utilizzare una valida configurazione della board. La configurazione è presente nella sezione dei file sorgenti del kernel con l’estensione “.config”. Possiamo anche non utilizzare questa configurazione la costruircene una. Per questa ragione, una volta configurato di nuovo il kernel, è necessario copiare il file verso la cartella di definizione del target e rinominare il file in una forma del tipo “versione_linux.config”, in questo modo: “2.6.25.10.config”. Per eseguire la configurazione del kernel in Buildroot è necessario invocare il comando:
make linux26-menuconfig
Non solo, è anche possibile utilizzare la configurazione di default ottenuta dalla distribuzione del kernel. In questo caso è necessario modificare la configurazione di Buildroot. Secondo l’ambiente di sviluppo possiamo selezionare un determinato tool che si intende utilizzare all’interno del nostro sistema target. Per fare questo è necessario ricorrere ad un file di configurazione. La presenza del file “busybox.config” permette di svolgere questa funzionalità. Per inserire o togliere specifici tool all’interno di buildroot è necessario modificare il file di configurazione in modo opportuno secondo le proprie esigenze. Per eseguire la configurazione Busybox in Buildroot è necessario invocare il seguente comando:
Make busybox-menuconfig
Il nostro target può avere l’esigenza di utilizzare un root filesystem. A questo proposito è disponibile una configurazione modello, skeloton, nella cartella “target_skeleton/”: è possibile inserire nuove cartelle e file semplicemente copiandole in root file system. È anche possibile impostare gli attributi dei file e creare file speciali utilizzando il file device_table.txt, a questo proposito il listato 2 mostra la definizione di una partizione JFFS2. Il file deve essere modificato in modo opportuno al fine di inserire e modificare gli attributi o creare file speciali. Siamo passati così a definire il nostro makefile che deve essere utilizzato per la nostra board. Dobbiamo intervenire nel file “makefile.in” cambiando i percorsi per i riferimenti alla board, rimuovere atngw100-base da BR2_TARGET_AVR32_ATNGW100_BASE e ATNGW100_BASE_PATH e sostituire con il nome della nostra board. Dopo aver apportato tutte le necessarie modifiche occorre anche aggiornare la definizione:
ifeq ($(BR2_TARGET_AVR32_ATNGW100_BASE), y) ATNGW100_BASE_PATH=target/ device/Atmel/atngw100-base TARGET_SKELETON=$(ATNGW100_BASE_ PATH)/target_skeleton TARGET_DEVICE_TABLE=$(ATNGW100 _BASE_PATH)/device_table.txt endif
A questo punto passiamo a configurare la nostra board nel sistema. Ovvero, Buildroot può accedere alla configurazione di scheda e selezionarla attraverso le definizioni del sistema. Per fare questo è necessario aggiungere una entry nel file di configurazione nel file “target/device/Atmel/AVR32_Config.in”, listato 2. In questo file dobbiamo definire un meccanismo che permettere alla board di essere selezionabile dal menu. Una volta aperto il file AVR32_Config.in (listato 1) cerchiamo una definizione già presente tra la label choice e endchoice, come:
config BR2_TARGET_AVR32_ATNGW100_BASE - bool “Atmel AVR32 basic network gateway board support” depends BR2_at32ap7000 select BR2_PACKAGE_LINUX help Very simple configuration for the Atmel AVR32 Network Gateway Board.
A questo punto sostituiamo “BR2_TARGET_AVR32_ATNGW100_BASE” con la nostra definizione, o meglio con l’identificatore della nostra board come “BR2_TARGET_AVR32_YOUR_BOARD_NAME”. Possiamo anche aggiungere una descrizione dopo la label bool, in questo caso abbiamo inserito il messaggio “Atmel AVR32 basic network gateway board support”. La keyword depens identifica il corretto target device selezionato dal nostro sistema target. La definizione mostra anche l’inserimento della keyword select con “BR2_PACKAGE_LINUX” perché la scelta è necessaria per abilitare i package di Linux. Infine, la keyword help è utilizzata per offrire una descrizione dettagliata della board. Questa descrizione è visualizzata nel system menu. A questo punto la nostra custom board è disponibile nel menu dell’intergaccia grafica di kconfig sotto la label “Board Support Options -> Atmel Device Support -> Development board support”, così come pone in evidenza la figura 2.
config BR2_TARGET_AVR32_ATNGW100_BASE bool “Atmel AVR32 basic network gateway board support” depends on BR2_at32ap7000 select BR2_PACKAGE_LINUX help Very simple configuration for the Atmel AVR32 Network Gateway Board.
Listato 1 – AVR32_config.in |
config BR2_BOARD_NAME string default “atstk100x-nand” if BR2_TARGET_AVR32_ATSTK1005 default “atstk100x-nand” if BR2_TARGET_AVR32_ATSTK1006 default “atngw100” if BR2_TARGET_AVR32_ATNGW100 default “atngw100-base” if BR2_TARGET_AVR32_ATNGW100_BASE
Listato 2 – target/device/Atmel/Config.in |
Per ultima cosa dobbiamo modificare il file “target/device/Atmel/Config.in” intervenendo su BR2_BOARD_NAME al fine di impostare il nome corretto della board. Secondo le indicazioni del nostro progetto, il nome corretto è quello presente nella struttura “target/device/Atmel”, la nostra custom board. Così:
config BR2_BOARD_NAME string … default “atngw100-base” if BR2_TARGET_ AVR32_ATNGW100_BASE
A questo punto, come utltimo passo, è necessario creare la nostra configurazione con Buildroot con il comando seguente in relazione al nome della board:
run make atngw100_defconfig