¿Cómo organizar la estructura de mis proyectos Arduino para facilitar el control de la fuente?


75

Ha pasado mucho tiempo que he estado buscando una buena respuesta a esta pregunta.

Típicamente, cualquier proyecto de Arduino pero el más simple incluirá:

  • El archivo de código fuente principal MyProject.ino
  • Bibliotecas específicas del proyecto ( MyProjectLibrary1.h, MyProjectLibrary1.cpp...)
  • Bibliotecas de terceros (generalmente de código abierto gratuito, agregadas manualmente al directorio de bibliotecas Arduino)
  • Esquemas, diagramas de PCB
  • Documentación
  • ...

Todo esto hace que sea difícil mantener todo el código y el documento de un proyecto en Gestión del código fuente (por ejemplo, en Subversion, Git o GitHub).

Administrar el control de origen de su proyecto significa administrar la versión de todos los archivos utilizados por el proyecto, incluidas las bibliotecas de terceros.

Ahora, para un solo proyecto, necesito definir una estructura de directorio que:

  • Incluye todos los archivos del proyecto como se describe arriba
  • Puedo comprometerme completamente con una herramienta de administración del código fuente (incluidas las dependencias de terceros)
  • Puedo pagar en cualquier lugar de mi disco duro y construir el proyecto desde allí (¿tiene que ser una única ubicación impuesta por Arduino IDE)
  • Puedo comprimir un archivo autónomo que puedo enviar a un amigo para que lo construya lo más fácilmente posible (sin descarga manual adicional)

Lo que encuentro particularmente complicado con los proyectos de Arduino es la gestión de dependencias de bibliotecas externas. Los desarrolladores de proyectos Java tienen repositorios expertos para eso y eso ayuda mucho en la gestión de todos los departamentos externos. Pero no tenemos un sistema equivalente para las bibliotecas Arduino.

Me interesaría saber cómo otros creadores de proyectos de Arduino abordan estos aspectos en sus propios proyectos.

También tenga en cuenta que estoy abierto a cambiar mi proceso de desarrollo, incluido mi IDE (actualmente uso Eclipse con el complemento Arduino la mayor parte del tiempo, y luego me aseguro de que mis proyectos también puedan funcionar directamente con el IDE de Arduino).


También he estado luchando con esto. Tengo dos proyectos que necesitan diferentes versiones de una biblioteca externa, y actualmente están fuera del control de versiones.
Cybergibbons

1
Tenga en cuenta para futuras investigaciones que esos son los administradores de paquetes . JavaScript obtuvo Node.js / npm y bower, PHP consiguió PEAR y Composer, etc.
kaiser

Respuestas:


30

Mi forma de organizar un proyecto arduino es bastante simple, todos mis proyectos son repositorios git para que haya al menos lo siguiente:

Prefiero usar mi editor favorito y un Makefile que he creado para trabajar en la mayoría de los casos de uso (e incluso mejoré el que voy a compartir pronto).

Para las bibliotecas, prefiero mantenerlos como sus propios repositorios y usar git submodule para incluirlos en el proyecto. Como muchas bibliotecas escritas por la comunidad se comparten como repositorios git, esa es una buena solución genérica. Luego, dentro del Makefile, solo tengo que agregar la ruta de las bibliotecas que quiero incluir en la variable LOCALLIBS .

Aunque, para algunos proyectos, tiene sentido encapsular las bibliotecas en una biblioteca de capa de abstracción de hardware diseñada para el proyecto, entonces prefiero usar una ruta como:

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

Sin embargo, con arduino 1.5.xa se ofrece una nueva forma de especificar bibliotecas , que ofrecerá una forma de crear y construir proyectos arduino de la misma manera que ya lo hacemos con pipy y virtualenv en python, es decir, usted define el conjunto de bibliotecas que necesita y ellos descargar


Estaba trabajando en una respuesta similar. ¡Me ganaste!
asheeshr

+1 ¡Gracias! De esta manera se ve bastante interesante. Tendré que intentarlo esta semana (sin embargo, primero tengo que ver cómo configurar las cosas de Makefile).
jfpoilpret

@AsheeshR si su respuesta fue similar, eso significa que todavía tiene algunas diferencias, ¿verdad? ¡Me interesaría saber sobre estos!
jfpoilpret

En realidad, los principales cambios que vendrán con la próxima versión de mi Makefile serán la capacidad de flashusar un programador o uploadusar el gestor de arranque. Además de manejar la fusión del gestor de arranque con firmware. También escribí un set de fusibles en el makefile.
zmo

@zmo recompensa merecida, aunque su solución Makefile no puede funcionar en mi situación (usando Windows pero no especifiqué ese punto). Pero estoy convencido de que usar una de las soluciones de archivo MAKE existentes es el camino a seguir. Una vez que haya encontrado uno que funcione para mí, publicaré mi respuesta aquí.
jfpoilpret

23

La forma más sencilla de hacer esto es copiar el encabezado y los archivos de código de la biblioteca en su directorio fuente e incluirlos.

myproject/
    myproject.ino
    somelib.h
    somelib.cpp

En tu código, puedes hacer include "somelib.h"

La desventaja de esto es que las bibliotecas deben estar en la misma carpeta, no en subcarpetas, por lo que hace que su directorio se vea desordenado.


Con respecto a la estructura de directorios de todo mi proyecto, incluidos los esquemas y la documentación, la mía generalmente se ve así:

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
    ...

Otro inconveniente es que tendré que copiar las mismas bibliotecas en muchos proyectos. Además, ¿no está claro para mí si pones TUS bibliotecas allí o también bibliotecas de terceros?
jfpoilpret

Primer punto: eso no es realmente un inconveniente, es solo un efecto secundario de mantener las bibliotecas y la fuente del proyecto juntas como quisiera con el control de versiones. ¿Qué pasa si otro proyecto necesita una versión actualizada de la biblioteca? ¿Qué pasa si lo modificaste? Segundo punto: ambos funcionarán.
sachleen

1
Yo no. El IDE de Arduino es bastante limitado en muchos aspectos. Es posible que desee buscar un mejor entorno para trabajar que tenga un mejor soporte para esto. La gente ha creado archivos personalizados que también le permiten importar bibliotecas de otras fuentes.
sachleen

1
Esta no es una buena manera de organizar proyectos desde el punto de vista de las licencias de software. Si incluye bibliotecas de terceros en su proyecto, que pueden tener diferentes licencias, puede estar violando tan pronto como comience a compartir el archivo del proyecto. Las diferentes licencias de código abierto generalmente no son compatibles entre sí.
asheeshr

3
@AsheeshR tener todos sus archivos en un directorio para que el IDE de arduino no se queje no es una buena forma de organizar proyectos. Es solo una manera. Siéntase libre de proponer una mejor solución. No conozco uno que todavía te permita usar el software Arduino.
sachleen

20

Los submódulos de Git son extremadamente poderosos cuando se trata de organizar múltiples repositorios anidados. El manejo de múltiples bibliotecas de diferentes fuentes, e incluso el manejo de partes de su propio proyecto que pueden almacenarse en diferentes fuentes se vuelve fácil con submódulos git.

Estructura de directorios

Una forma de organizar sus proyectos sería:

  • projectA - Directorio de padres

    • projectA - Directorio del código fuente que contiene el código Arduino

      1. proyectoA.ino
      2. header.h
      3. implementación.cpp
    • docs - Su directorio principal de documentación

    • esquemas : estos pueden mantenerse por separado en un repositorio Git separado o parte del mismo repositorio

    • libs : contendrá las bibliotecas de terceros.

      1. libA: estos pueden mantenerse como repositorios de terceros
      2. libC - ...
    • licencia

    • LÉAME

    • Makefile : necesario para manejar dependencias entre directorios

Flujo de trabajo

Seguiría su ciclo normal de hacer cambios, agregar y confirmar en lo que respecta al repositorio principal. Las cosas se ponen interesantes con los sub-repositorios.

Tiene la opción de agregar un repositorio en el directorio principal de su repositorio principal. Esto significa que cualquier parte de la estructura de su directorio, es decir, documentos, esquemas, etc. puede mantenerse como un repositorio separado y actualizarse continuamente desde.

Puedes hacer esto usando el git submodule add <repo.git>comando. Para mantenerlo actualizado, puede usarlo git submodule update <path>.

Cuando se trata de mantener múltiples bibliotecas de terceros dentro de su repositorio de modo que cada una pueda controlarse por sí misma o cada una se pueda mantener actualizada si es necesario, ¡git submodule nuevamente le salva el día!

Para agregar una tercera parte en repo libs , utilice el comando git submodule add <lib1.git> libs/lib1. Luego, para mantener la biblioteca en un punto fijo en el ciclo de lanzamiento, verifique la biblioteca y realice una confirmación. Para mantener la biblioteca actualizada, use el comando git submodule update <path>.

Ahora, puede mantener múltiples repositorios dentro de un repositorio principal, así como múltiples bibliotecas de terceros en sus etapas independientes de lanzamiento.

Enfoque de directorio único versus

Si bien el enfoque de directorio único es el más simple, no es posible controlar partes de un directorio sin mucho dolor. Por lo tanto, el enfoque simple no puede acomodar diferentes repositorios con diferentes estados en el proyecto.

Este enfoque permite mantener múltiples repositorios, pero trae la necesidad de un Makefile para manejar el proceso de compilación y enlace.

Dependiendo de la complejidad de su proyecto, se puede seleccionar el enfoque óptimo.


1
+1, pero solo como nota al margen: los submódulos de Git son bastante inestables y probablemente pierden el rumbo. No hace ninguna diferencia si se utiliza un solo directorio o múltiplos (como vendor, node_modules, etc.). Git los hace referencia y lo rastrea.
kaiser

"No hay diferencia si usa un solo directorio o múltiples (como proveedor, nodo_módulos, etc.)". No entendí esta parte. ¿Podrías dar más detalles?
asheeshr

17

Este es el camino que finalmente decidí seguir para mis proyectos.

Arduino-CMake

La primera decisión importante que tomé fue la elección de una herramienta de compilación que pudiera funcionar para mi entorno (Windows) pero no se limitara a ella (quiero que mis proyectos sean fácilmente reutilizables por otras personas).

He probado varias herramientas de código abierto para hacer Arduino:

  • Makefile de Guyzmo (sugerido por @zmo answer): este es solo un Makefile estándar hecho a mano para las compilaciones de Arduino; Este es un Makefile de Unix, pero hay un buen puerto de Unix Make para Windows ; Aún así, desafortunadamente este Makefile funciona solo para Unix, por supuesto, podría adaptarse para Windows, pero quería una herramienta que funcionara "fuera de la caja".
  • Arduino-Makefile (sugerido por @adnues answer): este es un proyecto más avanzado, basado en Unix Makefile, que pretende ser fácilmente reutilizable por todos los proyectos de Arduino; está documentado como trabajando en Mac, Linux y Windows, pero el soporte de Windows demostró ser incorrecto en mis primeros experimentos (muchas dependencias en el shell Unix).
  • Graduino (no sugerido por ninguna respuesta): esta herramienta de compilación se basa en la conocidaherramienta de compilación de gradle delmundo maravilloso ; la herramienta parece bastante bien hecha pero requiere un poco (poco) conocimiento maravilloso / gradle, y tiene muy poca documentación; Decidí no hacerlo debido a la carga de instalar groovy y gradle solo por eso (me gustaría evitar demasiados requisitos previos para las personas que desean construir mis proyectos en sus entornos).
  • Arduino-CMake (no sugerido por ninguna respuesta): esto parece lo mejor de todo, tiene una larga historia, tiene muchos partidarios y mantenedores, está muy bien documentado, viene con ejemplos simples y también tiene algunas buenas publicaciones de blog tutoriales en el Web, por ejemplo, aquí y allá . Se basa en CMake , una "Marca multiplataforma".

También he encontrado ArduinoDevel , otra herramienta de compilación de Arduino, que no he experimentado, que puede generar archivos Unix Makefiles o archivos ant build.xml ; ese parecía interesante pero un poco limitado en términos de funcionalidad.

Finalmente decidí ir con Arduino-CMake :

  • fue fácil de configurar: simplemente instale CMake en su máquina y copie Arduino-CMake en algún directorio que sea fácilmente accesible (a través de rutas relativas) desde los directorios de sus proyectos.
  • los ejemplos salieron de la caja para mí (solo seguí los comentarios en el CMakeLists.txtarchivo de configuración para adaptar las propiedades que necesitaba para mi entorno, por ejemplo, tipo Arduino, puerto serie)
  • puedes organizar tus proyectos como quieras
  • puede generar archivos de configuración para varias herramientas de compilación (aunque solo he probado Unix Makefiles ), incluidos los proyectos de Eclipse .
  • en la marca generada, se crean varios objetivos para admitir:

    • construir bibliotecas
    • programas de construcción
    • programa subir a los tableros
    • lanzamiento del monitor en serie
    • y algunos otros que aún no he probado

Estructura del proyecto

Dado que Arduono-CMake no impone ninguna estructura de directorio para su proyecto, puede elegir el que más le convenga.

Esto es lo que he hecho personalmente (que todavía requiere un mayor refinamiento, pero estoy contento con eso ahora):

ingrese la descripción de la imagen aquí

He decidido poner todos mis proyectos en un arduino-stuffdirectorio común (que me comprometo con github en su conjunto, sé que podría usar los submódulos git para una mejor organización en github, pero aún no tuve tiempo de verificarlo).

arduino-stuff tiene el siguiente contenido:

  • build: ese es un directorio donde cmake y make generarán todas sus cosas (makefiles, caché, archivos de objetos ...); este no se compromete con github
  • cmake: esa es solo una copia (no modificada) del directorio Arduino-CMake cmake . Este se pone en github para que sea más fácil para alguien que quiera construir mis proyectos
  • CMakeLists.txt: esa es la configuración CMake "global" que declara todos los valores predeterminados para mi entorno (placa, puerto serie) y la lista de subdirectorios de destino de compilación
  • TaskManager: este es mi primer proyecto basado en Arduino-CMake, este es una biblioteca con ejemplos; este idrectory también contiene un CMakeLists.txtque establece los objetivos para el proyecto

Puntos para mejorar

Sin embargo, la solución actual no es perfecta. Entre las mejoras que veo (eso es más bien para que el proyecto Arduino-CMake incluya estas mejoras si lo consideran conveniente):

  • Característica para copiar un directorio de biblioteca del proyecto actual al directorio de bibliotecas Arduino
  • Característica para subir una biblioteca a github
  • Característica para descargar una biblioteca de github

2
¿Ya has probado PlatformIO? Es posible que no haya existido cuando hacía esta pregunta .. platformio.org
ohhorob

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

Carpeta MyProject (raíz del repositorio)

La razón por la que sugiero la MyProjectcarpeta raíz aparentemente redundante es que mencionaste el uso de GitHub. Cuando descarga (en lugar de clonar) el contenido de un repositorio de GitHub, el nombre de la rama o etiqueta se agrega al nombre del repositorio (p. Ej.MyProject-master) El IDE de Arduino requiere que el nombre de la carpeta de croquis coincida con el nombre del archivo de croquis. Si abre un archivo .ino que está en una carpeta que no coincide con el nombre del boceto, el IDE de Arduino le solicita que cree una carpeta de bocetos con el nombre apropiado y mueva el boceto a esa carpeta. Además de que esto no es una experiencia inicial muy buena para el usuario, el mayor problema es que el IDE de Arduino no puede copiar todos los demás archivos asociados a la carpeta recién creada, lo que podría hacer que el programa ya no se compile. Al colocar el boceto en una subcarpeta, evita que GitHub altere el nombre de la carpeta del boceto.

Si el nombre del archivo GitHub no es un problema para usted, entonces la carpeta raíz redundante no es necesaria.

carpeta de datos

Recomiendo usar la datasubcarpeta para sus archivos sin código porque Arduino IDE tiene un tratamiento especial de las subcarpetas con ese nombre. Que se copian en la nueva ubicación cuando se hace una Archivo> Guardar como ... . Las subcarpetas de cualquier otro nombre no lo son.

carpeta src

La srcsubcarpeta tiene la propiedad especial de permitir la compilación recursiva . Esto significa que puede dejar las bibliotecas en esa carpeta e incluirlas desde su boceto de esta manera:

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

La estructura de carpetas del formato Arduino 1.5 Library también es compatible, solo necesita ajustar sus #includedeclaraciones en consecuencia.

Tenga en cuenta que solo Arduino IDE 1.6.10 (arduino-builder 1.3.19) y los más nuevos admiten la compilación de bocetos recursiva.

Desafortunadamente, algunas bibliotecas usan la #includesintaxis incorrecta para archivos locales incluidos (por ejemplo, en #include <ThirdPartyLibrary.h>lugar de #include "ThirdPartyLibrary.h"). Esto todavía funciona cuando la biblioteca está instalada en una de las librariescarpetas de Arduino, pero no funciona cuando la biblioteca está incluida en el boceto. Por lo tanto, algunas bibliotecas pueden requerir ediciones menores para usar de esta manera.

Prefiero esto a la alternativa de descargar todos los archivos de la biblioteca en la raíz de la carpeta del boceto porque eso es desordenado y cada archivo de la biblioteca se mostrará en el IDE de Arduino como pestañas cuando abra el boceto (por supuesto, cualquier archivo fuente que haga desea ser editable desde el IDE de Arduino debe colocarse en la carpeta raíz del boceto).

Poder usar las bibliotecas agrupadas en el lugar también está en línea con otro de sus objetivos:

enviar a un amigo para que construya lo más fácilmente posible

Eliminar el requisito de instalar bibliotecas manualmente hace que el proyecto sea mucho más fácil de usar.

Esto también evitará cualquier posibilidad de conflicto con otras versiones de archivos de biblioteca del mismo nombre que puedan estar instalados previamente.


3

Podrías usar el makefile https://github.com/sudar/Arduino-Makefile para compilar códigos Arduino. No necesariamente necesita el IDE.


1
Lo he intentado pero desafortunadamente solo funcionará en máquinas Unix y necesito soporte de Windows. Actualmente estoy evaluando otro proyecto basado en CMake pero aún no he terminado con él. Publicaré una respuesta cuando me haya decidido por una herramienta.
jfpoilpret

0

Probablemente sea muy tarde para el juego, pero es una pregunta lo suficientemente popular como para responder usando métodos ligeramente diferentes a los publicados.

Si necesita mantener la compatibilidad con Arduino IDE directamente, puede usar algo como el que describí aquí:

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

Basé la mayor parte de esto en las notas de Arduino - Estructura del proyecto y proceso de construcción , y algunos consejos que he recogido a lo largo de los años.

Realmente no sé por qué esto es tan difícil de encontrar a través de las páginas de Arduino directamente, parece una tontería venir de un entorno semi profesional que el proceso de construcción es tan obtuso.

la mejor de las suertes


El enlace de gitlab parece estar roto
Greenonline

extraño funciona sin el enlace directo? es decir, gitlab.com/mikealger/ExampleArduinoProjectStructure
Mike Alger

En realidad, ambos enlaces funcionan en Firefox, pero ninguno funciona en mi versión desactualizada de Chrome 49.0.2623.112 (64 bits). Nada de qué preocuparse, supongo. :-)
Greenonline