Come organizzare la struttura dei miei progetti Arduino per un facile controllo del codice sorgente?


75

È da molto tempo che cerco una buona risposta a questa domanda.

In genere, qualsiasi progetto Arduino ma il più semplice includerà:

  • Il file principale del codice sorgente MyProject.ino
  • Librerie specifiche per il progetto ( MyProjectLibrary1.h, MyProjectLibrary1.cpp...)
  • Librerie di terze parti (generalmente open source gratuito, aggiunte manualmente alla directory delle librerie di Arduino)
  • Schemi, schemi PCB
  • Documentazione
  • ...

Tutto ciò rende difficile mantenere l'intero codice e il documento di un progetto in Gestione del codice sorgente (ad esempio su Subversion, Git o GitHub).

Gestire il controllo del codice sorgente del progetto significa gestire la versione di tutti i file utilizzati dal progetto, comprese le librerie di terze parti.

Ora per un singolo progetto, devo definire una struttura di directory che:

  • Include tutti i file di progetto come descritto sopra
  • Posso impegnarmi completamente in uno strumento di gestione del codice sorgente (comprese dipendenze di terze parti)
  • Posso effettuare il checkout in qualsiasi punto del mio disco rigido e creare il progetto da lì (deve essere un unico percorso come imposto dall'IDE di Arduino)
  • Posso comprimere in un archivio autonomo che posso inviare a un amico per farlo costruire il più facilmente possibile (nessun download manuale aggiuntivo)

Ciò che trovo particolarmente complicato con i progetti Arduino è la gestione delle dipendenze delle librerie esterne. Progetti Java sviluppatori hanno Maven repository per questo e che aiuta molto nella gestione di tutte le dipendenze esterne. Ma non abbiamo un sistema equivalente per le librerie Arduino.

Sarei interessato a sapere come altri creatori di progetti Arduino affrontano questi aspetti nei propri progetti.

Inoltre, sono aperto a cambiare il mio processo di sviluppo, incluso il mio IDE (attualmente utilizzo Eclipse con il plug-in Arduino per la maggior parte del tempo, e quindi mi assicuro che i miei progetti possano funzionare anche direttamente con l'IDE Arduino).


Ho anche lottato con questo. Ho due progetti che richiedono versioni diverse di una libreria esterna e attualmente sono fuori dal controllo della versione.
Cybergibbons,

1
Si noti che per ulteriori ricerche si tratta di gestori di pacchetti . JavaScript ha Node.js / npm e bower, PHP ha PEAR e Composer, ecc.
Kaiser

Risposte:


30

Il mio modo di organizzare un progetto Arduino è abbastanza semplice, tutti i miei progetti sono repository git in modo che ci sia almeno il seguente:

Ho una preferenza usando il mio editor preferito e un Makefile che ho creato per lavorare con la maggior parte dei casi d'uso (e ho persino migliorato quello che condividerò presto).

Per le biblioteche, preferisco tenerli come propri repository e usare git submodule per includerli nel progetto. Poiché molte librerie scritte dalla community sono condivise come repository git, questa è una buona soluzione generica. Quindi, all'interno del Makefile, devo solo aggiungere il percorso delle librerie che voglio includere nella variabile LOCALLIBS .

Sebbene, per alcuni progetti, abbia senso incapsulare le librerie in una libreria di livelli di astrazione hardware creata per il progetto, preferisco usare un percorso come:

  • project
    • project.ino
    • Makefile
    • project_hal_lib
      • library1
      • library2
      • library3
      • ...

Tuttavia, con arduino 1.5.xa viene offerto un nuovo modo per specificare le librerie , che offrirà un modo per creare e costruire progetti arduino nello stesso modo in cui facciamo già con pipy e virtualenv in Python, cioè tu definisci il set di librerie di cui hai bisogno e loro essere scaricato.


Stavo lavorando su una risposta simile. Mi hai battuto sul tempo!
asheeshr,

+1 Grazie! In questo modo sembra abbastanza interessante. Dovrò provarlo questa settimana (devo prima verificare come impostare prima le cose di Makefile).
jfpoilpret,

@AsheeshR se la tua risposta è stata simile, significa che ha ancora delle differenze, giusto? Sarei interessato a sapere di questi!
jfpoilpret,

in realtà le principali modifiche che verranno con la prossima versione del mio Makefile saranno la possibilità di flashusare un programmatore o uploadusare il bootloader. Oltre a gestire l'unione del bootloader con il firmware. Ho anche scritto un setter di fusibili nel makefile.
zmo

@zmo bounty meritava, anche se la tua soluzione Makefile non può funzionare nella mia situazione (usando Windows ma non ho specificato quel punto). Ma sono convinto che utilizzare una delle soluzioni di makefile esistenti disponibili sia la strada da percorrere. Una volta trovata una delle mie opere, posterò qui la mia risposta.
jfpoilpret,

23

Il modo più semplice per farlo è copiare i file di intestazione e di codice della libreria nella directory di origine e includerli.

myproject/
    myproject.ino
    somelib.h
    somelib.cpp

Nel tuo codice, puoi farlo include "somelib.h"

Il lato negativo di questo è che le librerie devono trovarsi nella stessa cartella, non nelle sottocartelle, quindi la tua directory appare disordinata.


Per quanto riguarda la struttura delle directory di tutto il mio progetto, compresi schemi e documentazione, il mio di solito appare così:

myproject/
  schematics/ - eagle files or whatever you may have
  docs/       - include relevant datasheets here
  test/       - any test cases or other code to test parts of the system.
  myproject/  - since Arduino code must be in a directory of the same name
    myproject.ino
    ...

Un altro aspetto negativo è che dovrò copiare le stesse librerie su molti progetti. Inoltre, non mi è chiaro se metti lì solo le tue librerie o anche librerie di terze parti?
jfpoilpret,

Primo punto: non è proprio un aspetto negativo, è solo un effetto collaterale di mantenere le librerie e la sorgente del progetto come desiderato con il controllo della versione. Cosa succede se un altro progetto necessita di una versione aggiornata della libreria? E se lo modificassi? Secondo punto: entrambi funzioneranno.
sachleen,

1
Io non. L'IDE di Arduino è abbastanza limitato in molti modi. Potresti voler cercare un ambiente migliore in cui lavorare che abbia un supporto migliore per questo. Le persone hanno creato file personalizzati che ti consentono di importare librerie anche da altre fonti.
sachleen,

1
Questo non è un buon modo per organizzare i progetti dal punto di vista delle licenze software. Se includi librerie di terze parti nel tuo progetto, che potrebbero avere licenze diverse, potresti averle violate non appena inizi a condividere il file di progetto. Diverse licenze open source non sono generalmente compatibili tra loro.
asheeshr,

3
@AsheeshR avere tutti i tuoi file in una directory in modo che l'IDE di Arduino non si lamenti non è un buon modo per organizzare i progetti. È solo un modo. Sentiti libero di proporre una soluzione migliore. Non ne conosco uno che ti permetta ancora di usare il software Arduino.
Sachleen,

20

I sottomoduli Git sono estremamente potenti quando si tratta di organizzare più repository nidificati. Gestire più librerie da fonti diverse e persino gestire parti del proprio progetto che possono essere archiviate su fonti diverse diventa facile con i sottomoduli git.

Struttura delle directory

Un modo per organizzare i tuoi progetti sarebbe:

  • projectA - Directory principale

    • projectA - Directory del codice sorgente contenente il codice Arduino

      1. projectA.ino
      2. header.h
      3. implementation.cpp
    • docs - La tua directory di documentazione principale

    • schemi - questi possono essere mantenuti separatamente su un repository Git separato o parte dello stesso repository

    • libs - Questo conterrà le tue librerie di terze parti.

      1. libA - Questi possono essere gestiti come repository di terze parti
      2. libC - ...
    • licenza

    • LEGGIMI

    • Makefile : necessario per gestire le dipendenze tra le directory

Flusso di lavoro

Seguiresti il ​​tuo normale ciclo di modifiche, aggiungere e impegnare per quanto riguarda il repository principale. Le cose si fanno interessanti con i sottopository.

Hai la possibilità di aggiungere un repository nella directory principale del tuo repository principale. Ciò significa che qualsiasi parte della struttura della directory, ad esempio documenti, schemi, ecc. Può essere gestita come un repository separato e continuamente aggiornata da.

Puoi farlo usando il git submodule add <repo.git>comando. Per tenerlo aggiornato, è possibile utilizzare git submodule update <path>.

Quando si tratta di mantenere più librerie di terze parti all'interno del proprio repository in modo tale che ognuna possa essere controllata in modo autonomo o, se necessario, ognuna può essere aggiornata, git submodule salva di nuovo la giornata!

Per aggiungere un terzo repo parte di librerie , utilizzare il comando git submodule add <lib1.git> libs/lib1. Quindi, per mantenere la libreria in un punto fisso nel ciclo di rilascio, controlla la libreria ed esegui un commit. Per mantenere la libreria aggiornata, utilizzare il comando git submodule update <path>.

Ora è possibile gestire più repository all'interno di un repository principale e più librerie di terze parti nelle loro fasi indipendenti di rilascio.

Contro approccio a directory singola

Mentre l' approccio a directory singola è il più semplice, non è possibile controllare le parti di una directory senza troppe difficoltà. Quindi, l'approccio semplice non riesce ad accogliere repository diversi con stati diversi nel progetto.

Questo approccio consente di mantenere più repository ma richiede la necessità di un Makefile per gestire il processo di compilazione e collegamento.

A seconda della complessità del progetto, è possibile selezionare l'approccio ottimale.


1
+1, ma proprio come un sidenote: i sottomoduli Git sono piuttosto instabili e probabilmente tracce libere. Non fa differenza se si utilizza una singola directory o multipli (come vendor, node_modulese così via). Git li fa riferimento e ne tiene traccia.
Kaiser

"Non fa alcuna differenza se usi una singola directory o multipli (come vendor, node_modules, ecc.)." Non ho capito questa parte. Potresti elaborare?
asheeshr

17

Ecco come ho finalmente deciso di seguire i miei progetti.

Arduino CMake

La prima decisione importante che ho preso è stata la scelta di uno strumento di compilazione che potesse funzionare per il mio ambiente (Windows) ma non si limitasse ad esso (voglio che i miei progetti siano facilmente riutilizzabili da altre persone).

Ho testato vari strumenti di creazione di Arduino open source:

  • Guyzmo Makefile (suggerito da @zmo answer): questo è solo un Makefile standard realizzato a mano per le build di Arduino; questo è un Makefile Unix ma c'è una buona porta di Unix make per Windows ; tuttavia, purtroppo, questo Makefile funziona solo per Unix, ovviamente potrebbe essere adattato per Windows, ma volevo uno strumento che funzioni "out of the box".
  • Arduino-Makefile (suggerito da @adnues answer): questo è un progetto più avanzato, basato su Unix Makefile, che mira a essere facilmente riutilizzabile da tutti i progetti Arduino; è documentato come funzionante su Mac, Linux e Windows, ma il supporto di Windows si è rivelato errato nei miei primi esperimenti (molte dipendenze dalla shell Unix).
  • Graduino (non suggerito da nessuna risposta): questo strumento di costruzione si basa sul notostrumento di creazione di gradi delmondo groovy ; lo strumento sembra abbastanza ben fatto ma richiede un po 'di conoscenza (poco) groovy / gradle e ha solo poca documentazione; Ho deciso di non seguirlo a causa dell'onere di installare groovy e gradle solo per questo (vorrei evitare troppi pre-requisiti per le persone che vogliono costruire i miei progetti sui loro ambienti).
  • Arduino-CMake (non suggerito da nessuna risposta): questo sembra il migliore di tutti, ha una lunga storia, ha molti sostenitori e manutentori, è molto ben documentato, viene fornito con semplici esempi e ha anche alcuni buoni post sul blog tutorial sul Web, ad esempio qua e . Si basa su CMake , un "Make multipiattaforma".

Ho anche trovato ArduinoDevel , un altro strumento di compilazione di Arduino, che non ho sperimentato, in grado di generare file Unix o file formica build.xml ; quello sembrava interessante ma un po 'limitato in termini di funzionalità.

Alla fine ho deciso di andare con Arduino-CMake :

  • è stato facile da configurare: basta installare CMake sul proprio computer e copiare Arduino-CMake in una directory che è facilmente accessibile (attraverso percorsi relativi) dalle directory dei progetti.
  • gli esempi hanno funzionato per me (ho appena seguito i commenti nel CMakeLists.txtfile di configurazione per adattare le proprietà necessarie per il mio ambiente, ad esempio tipo Arduino, porta seriale)
  • puoi organizzare i tuoi progetti come preferisci
  • può generare file di configurazione per vari strumenti di compilazione (ho testato solo Unix Makefile ), inclusi i progetti Eclipse .
  • nella generazione generata, vengono creati diversi target per supportare:

    • compilazione di librerie
    • compilazione di programmi
    • caricamento del programma su schede
    • lancio del monitor seriale
    • e alcuni altri non ho ancora testato

Struttura del progetto

Poiché Arduono-CMake non impone alcuna struttura di directory per il tuo progetto, puoi scegliere quella che si adatta meglio a te.

Ecco cosa ho fatto personalmente (che richiede ancora ulteriore affinamento, ma ora sono contento):

inserisci qui la descrizione dell'immagine

Ho deciso di mettere tutti i miei progetti in una arduino-stuffdirectory comune (che mi impegno a github nel suo insieme, so di poter usare i sottomoduli git per una migliore organizzazione su github, ma non ho ancora avuto il tempo di controllarlo).

arduino-stuff ha il seguente contenuto:

  • build: è una directory in cui cmake e make genereranno tutto il loro materiale (makefile, cache, file oggetto ...); questo non si impegna a github
  • cmake: quello è solo una copia (non modificata) della directory cmake di Arduino-CMake . Questo va su github in modo che sia più facile per qualcuno che vuole costruire i miei progetti
  • CMakeLists.txt: questa è la configurazione "globale" di CMake che dichiara tutte le impostazioni predefinite per il mio ambiente (scheda, porta seriale) e l'elenco delle sottodirectory target di build
  • TaskManager: questo è il mio primo progetto basato su Arduino-CMake, questa è una libreria con esempi; questa idrectory contiene anche una CMakeLists.txtche indica gli obiettivi del progetto

Punti da migliorare

La soluzione attuale non è perfetta però. Tra i miglioramenti che vedo (è piuttosto per il progetto Arduino-CMake includere questi miglioramenti se lo ritengono opportuno):

  • Funzionalità per copiare una directory della libreria dal progetto corrente nella directory delle librerie di Arduino
  • Funzionalità per caricare una libreria su github
  • Funzionalità per scaricare una libreria da github

2
Hai già provato PlatformIO? Potrebbe non essere stato in giro quando stavi facendo questa domanda .. platformio.org
ohhorob

4
MyProject
|_MyProject
  |_MyProject.ino
  |_data
  |  |_documentation 
  |  |_PCB
  |  |_schematics
  |_src
     |_MyProjectLibrary1
     |_ThirdPartyLibrary

Cartella MyProject (repository root)

Il motivo per cui suggerisco la MyProjectcartella radice apparentemente ridondante è che hai menzionato usando GitHub. Quando scarichi (anziché clonare) il contenuto di un repository GitHub, il nome del ramo o del tag viene aggiunto al nome del repository (ad es.MyProject-master). L'IDE Arduino richiede che il nome della cartella di schizzo corrisponda al nome del file di schizzo. Se si apre un file .ino che si trova in una cartella che non corrisponde al nome dello schizzo richiesto dall'IDE di Arduino, si crea una cartella di schizzo con nome appropriato e si sposta lo schizzo in quella cartella. Oltre a non essere un'ottima esperienza iniziale per l'utente, il problema maggiore è che l'IDE di Arduino potrebbe non copiare tutti gli altri file associati nella cartella appena creata, il che potrebbe impedire la compilazione del programma. Inserendo lo schizzo in una sottocartella si evita che GitHub modifichi il nome della cartella dello schizzo.

Se la cosa del nome del file GitHub non è un problema per te, la cartella radice ridondante non è necessaria.

cartella dati

Ti consiglio di usare la datasottocartella per i tuoi file non di codice perché l'IDE di Arduino ha un trattamento speciale per le sottocartelle con quel nome. Essi vengono copiati nella nuova posizione quando si esegue un File> Salva con nome ... . Le sottocartelle di qualsiasi altro nome non lo sono.

cartella src

La srcsottocartella ha la proprietà speciale di consentire la compilazione ricorsiva . Ciò significa che puoi lasciare le librerie in quella cartella e includerle dal tuo schizzo in questo modo:

#include "src/MyProjectLibrary1/MyProjectLibrary1.h"
#include "src/ThirdPartyLibrary/ThirdPartyLibrary.h"

È supportata anche la struttura di cartelle in formato Libreria Arduino 1.5 , è necessario solo modificare le #includedichiarazioni di conseguenza.

Si noti che solo Arduino IDE 1.6.10 (arduino-builder 1.3.19) e versioni successive supportano la compilazione di schizzi ricorsivi.

Purtroppo alcune librerie utilizzano la #includesintassi errata per le inclusioni di file locali (ad es. #include <ThirdPartyLibrary.h>Anziché #include "ThirdPartyLibrary.h"). Funziona ancora quando la libreria è installata in una delle librariescartelle di Arduino ma non funziona quando la libreria è in bundle con lo schizzo. Pertanto alcune librerie potrebbero richiedere modifiche minori per utilizzare in questo modo.

Preferisco di gran lunga questo all'alternativa di scaricare tutti i file di libreria nella radice della cartella dello schizzo perché è disordinato e ogni file di libreria verrà mostrato nell'IDE di Arduino come schede quando si apre lo schizzo (Naturalmente qualsiasi file sorgente che si esegue desidera essere modificabile dall'IDE di Arduino deve essere inserito nella cartella principale dello schizzo).

Essere in grado di utilizzare le librerie in bundle sul posto è anche in linea con un altro dei tuoi obiettivi:

invia ad un amico per farlo costruire il più facilmente possibile

La rimozione del requisito di installazione manuale delle librerie semplifica notevolmente l'utilizzo del progetto.

Ciò eviterà anche ogni possibilità di conflitto con altre versioni di file di libreria con lo stesso nome che possono essere precedentemente installati.


3

È possibile utilizzare il makefile https://github.com/sudar/Arduino-Makefile per compilare i codici Arduino. Non hai necessariamente bisogno dell'IDE.


1
Ho provato, ma sfortunatamente funzionerà solo su macchine Unix e ho bisogno del supporto di Windows. Attualmente sto valutando un altro progetto basato su CMake ma non ho ancora finito. Pubblicherò una risposta quando avrò deciso uno strumento.
jfpoilpret,

0

Probabilmente molto tardi al gioco, ma è una domanda abbastanza popolare a cui rispondere con metodi leggermente diversi rispetto a quelli già pubblicati.

Se è necessario mantenere la compatibilità con Arduino IDE direttamente, è possibile utilizzare qualcosa di simile a quello che ho descritto qui:

https://gitlab.com/mikealger/ExampleArduinoProjectStructure/tree/master/ExampleSketchBook

Ho basato la maggior parte di questo fuori le note di Arduino - Struttura del progetto e processo di compilazione , e alcuni suggerimenti che ho raccolto nel corso degli anni.

Non so davvero perché sia ​​così difficile da trovare direttamente tramite le pagine di Arduino, sembra sciocco proveniente da un background semi-professionale che il processo di compilazione è così ottuso.

buona fortuna là fuori


Il link gitlab sembra non funzionare
Greenonline

strano funziona senza il collegamento diretto? ie gitlab.com/mikealger/ExampleArduinoProjectStructure
Mike Alger

In realtà entrambi i collegamenti funzionano in Firefox, ma nessuno dei due funziona nella mia versione obsoleta di Chrome 49.0.2623.112 (64 bit). Niente di cui preoccuparsi, immagino. :-)
Greenonline
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.