Cirugía para aumentar el búfer del puerto serie del Arduino IDE





No soy un gran fanático de la infraestructura de Arduino. Sí, hoy ya tenemos más opciones, por ejemplo, Pro IDE y Platform IO . Sin embargo, siempre tengo acidez estomacal por el IDE original. Y aprecié todo su alcance solo el día anterior, cuando quise hacer algo muy simple: aumentar el búfer de recepción del puerto serie ATmega32. Al final, se me ocurrió una solución que también puede ayudarlo con otros problemas, por lo que incluso si no necesita específicamente esta función, puede que le resulte útil ver qué hice exactamente.



Esta experiencia me dejó una doble impresión. Por un lado, desprecio a este editor indescriptible por ocultarme demasiado y proporcionar muy pocas herramientas útiles. Por otro lado, me impresionó lo flexible que es cuando se profundiza en los detalles de su estructura interna.



Primero, probablemente pregunte por qué estoy usando un IDE. En resumen, no lo uso. Sin embargo, si haces algo que otros usarán, es casi imposible ignorarlo. Independientemente de cómo configure su propio IDE, tan pronto como su código esté en línea, alguien intentará usarlo con el IDE. Una vez escribí sobre una computadora basada en Z80 de $ 4 . Rara vez tengo tiempo para construir lo que estoy escribiendo, pero realmente quería intentar construir esta pequeña computadora. Durante un tiempo todo estuvo medio desmontado y luego me enviaron un pago por él. Lo recibí y, como habrás adivinado, todavía estaba un poco desarmado. Pero finalmente encontré el tiempo para terminar el proyecto y descargué CP / M.







El único problema con el proyecto fue la falta de buenas opciones para transferir datos desde él a la PC y viceversa. Parecía que lo mejor que podía hacer era crear archivos hexadecimales de Intel y copiarlos / pegarlos a través del terminal. Quería algo mejor y terminé en una madriguera de conejo el sábado por la mañana. Como resultado, se me ocurrió una forma de agregar mis propios elementos de menú al IDE de Arduino para editar la configuración del compilador según el hardware utilizado en el proyecto. Vale la pena aprender este truco, ya que puede ser útil fuera de esta tarea en particular.



Problema: límite de tamaño del búfer del puerto serie Arduino



No te molestaré con detalles sobre cómo hacer que el tablero funcione, ya que solo te interesará si tienes uno. Todos los detalles están en la discusión en Hackaday.io si realmente lo necesita. Como resultado, el búfer del puerto serie Arduino no era lo suficientemente grande para que la transmisión a través de XModem se considerara confiable. Todo parecía funcionar con el búfer predeterminado de 64 bytes, pero XModem está enviando más datos y es fácil imaginar que el búfer se desborde.



¿Qué tan difícil puede ser actualizar un búfer? Por otro lado, esta es una tarea trivial. Por otro lado, es muy difícil, porque tus herramientas se esfuerzan mucho por ayudarte.



Set de herramientas



El proyecto de computadora pequeña utiliza el chip Z80 real y ATMega32A para casi todas las funciones auxiliares. Proporciona velocidad de reloj, puerto serie, almacenamiento, etc. Sin embargo, el IDE de Arduino no es compatible directamente con ATMega32A, por lo que debe instalar una caja de herramientas para hacer esto. La situación requería MightyCore , así que lo usé.



Las bibliotecas de puertos serie están configuradas con declaraciones #define para que pueda corregir el tamaño del búfer. De forma predeterminada, si no se configura nada, obtendrá valores basados ​​en la cantidad de RAM disponible:



#if !defined(SERIAL_TX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif
#endif
#if !defined(SERIAL_RX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_RX_BUFFER_SIZE 64
#endif
#endif


Haciendo cambios



Es simple, ¿no? Defina los símbolos antes de cargar HardwareSerial.h. Mierda, este archivo está cargado en Arduino.h. El SP quiere agregarlo a su programa y lo hace arrancar primero. Parece que algunas versiones del IDE verificaron si ya lo había habilitado para no volver a habilitarlo, pero la versión 1.8.5 no lo hace. ¿Quizás pueda pasar algunas configuraciones al compilador? No Al menos no a través del IDE.



He probado muchas cosas. Quería, por supuesto, solo cambiar las bibliotecas principales. Pero esto no es bueno. Más tarde, es posible que necesite la configuración predeterminada. Si actualiza la caja de herramientas, se perderán todas las actualizaciones. Quería evitar esto. Alguien en Internet aconsejó hacer una copia de los archivos de la plataforma y modificarlos. No es una solución perfecta.



Verificando las suposiciones con



Pude ver que lo que estaba haciendo no funcionaba ya que estaba insertando temporalmente declaraciones #if y #error en HardwareSerial.cpp. Por ejemplo:



#if SERIAL_RX_BUFFER_SIZE==256
#error 256
#endif


Ahora, si el error 256 falla al compilar, sé que el tamaño está configurado. Si no es así, el sistema se resiste a mis cambios.



Compensación: agregar configuraciones a los menús de nivel de tablero



Tenía muchas ganas de encontrar una forma de cambiar la configuración solo en un proyecto específico, y así establecer el tamaño del búfer en serie. No lo logré. Pero logré cambiar boards.txt de Mighty Core. Sí, tendré que asegurarme de que las actualizaciones no sobrescriban mis ediciones, pero son simples, y si falta algo en el archivo, será obvio.







Obviamente esto será porque he creado un menú para el IDE, que solo aparece cuando se usa ATMega32 para Mighty Core. Se puede seleccionar uno de los tamaños de búfer predeterminados en el menú.



Para lograr este resultado, debe seguir tres pasos:



  1. Dígale al IDE que tiene un nuevo elemento de menú y describa cómo se ve.
  2. El nuevo elemento debería cambiar la configuración del compilador.
  3. Dado que el sistema existente también cambia la configuración del compilador, debe asegurarse de que no se corrompan.


El primer paso es sencillo. Mi archivo boards.txt estaba en ~ / .arduino15 / packages / MightyCore / hardware / avr / 2.0.5 / boards.txt. Casi en la parte superior hay una lista de elementos del menú, y al final agregué la mía:



# Menu options
menu.clock=Clock
menu.BOD=BOD
menu.LTO=Compiler LTO
menu.variant=Variant
menu.pinout=Pinout
menu.bootloader=Bootloader
menu.SerialBuf=Serial Port Buffers (RX/TX)


Luego moví las líneas hacia abajo y agregué mi menú frente a la configuración LTO existente para ATMega32:



32.menu.SerialBuf.disabled=Default
32.menu.SerialBuf.disabled.compilerSB.c.extra_flags=
32.menu.SerialBuf.disabled.compilerSB.cpp.extra_flags=
 
32.menu.SerialBuf.SB64=64/64
32.menu.SerialBuf.SB64.compilerSB.c.extra_flags=-DSERIAL_RX_BUFFER_SIZE=64 -DSERIAL_TX_BUFFER_SIZE=64
32.menu.SerialBuf.SB64.compilerSB.cpp.extra_flags=-DSERIAL_RX_BUFFER_SIZE=64 -DSERIAL_TX_BUFFER_SIZE=64
 
32.menu.SerialBuf.SB128=128/128
32.menu.SerialBuf.SB128.compilerSB.c.extra_flags=-DSERIAL_RX_BUFFER_SIZE=128 -DSERIAL_TX_BUFFER_SIZE=128
32.menu.SerialBuf.SB128.compilerSB.cpp.extra_flags=-DSERIAL_RX_BUFFER_SIZE=128 -DSERIAL_TX_BUFFER_SIZE=128
 
32.menu.SerialBuf.SB12864=128/64
32.menu.SerialBuf.SB12864.compilerSB.c.extra_flags=-DSERIAL_RX_BUFFER_SIZE=128 -DSERIAL_TX_BUFFER_SIZE=64
32.menu.SerialBuf.SB12864.compilerSB.cpp.extra_flags=-DSERIAL_RX_BUFFER_SIZE=128 -DSERIAL_TX_BUFFER_SIZE=64
 
32.menu.SerialBuf.SB256=256/256
32.menu.SerialBuf.SB256.compilerSB.c.extra_flags=-DSERIAL_RX_BUFFER_SIZE=256 -DSERIAL_TX_BUFFER_SIZE=256
32.menu.SerialBuf.SB256.compilerSB.cpp.extra_flags=-DSERIAL_RX_BUFFER_SIZE=256 -DSERIAL_TX_BUFFER_SIZE=256
 
32.menu.SerialBuf.SB25664=256/64
32.menu.SerialBuf.SB25664.compilerSB.c.extra_flags=-DSERIAL_RX_BUFFER_SIZE=256 -DSERIAL_TX_BUFFER_SIZE=64
32.menu.SerialBuf.SB25664.compilerSB.cpp.extra_flags=-DSERIAL_RX_BUFFER_SIZE=256 -DSERIAL_TX_BUFFER_SIZE=64
 
32.menu.SerialBuf.SB25632=256/32
32.menu.SerialBuf.SB25632.compilerSB.c.extra_flags=-DSERIAL_RX_BUFFER_SIZE=256 -DSERIAL_TX_BUFFER_SIZE=32
32.menu.SerialBuf.SB25632.compilerSB.cpp.extra_flags=-DSERIAL_RX_BUFFER_SIZE=256 -DSERIAL_TX_BUFFER_SIZE=32


Estructura del menú



Puede ver que el objeto 32.menu agrupa todos los elementos para un procesador determinado. Luego viene nuestra tecla de menú (SerialBuf). A esto le siguen teclas únicas para cada elemento del menú. Es importante no reutilizarlos. Si, por ejemplo, tiene dos llaves SB64, solo una de ellas funcionará.



Si asigna un signo igual a esta tecla, puede asignar texto a este elemento del menú. Por ejemplo, "Predeterminado" o "64/64". También puede agregar una propiedad a la clave y se asignará cuando se active el elemento.



Si, por ejemplo, selecciona 256/256, el compilador establece la propiedad compilerSB.c.extra_flags. Por qué se me ocurrió ese nombre para la propiedad, lo entenderá un poco más tarde.



Coexistencia pacífica



La propiedad compilerSB.c.extra_flags no está presente. Correctamente se llama compiler.c.extra_flags. Sin embargo, la configuración de Mighty Core LTO usa la misma clave. Por lo tanto, era importante que el nuevo menú apareciera primero y también estableciera una propiedad falsa. Entonces necesitas corregir el código LTO:



# Compiler link time optimization
32.menu.LTO.Os=LTO disabled
32.menu.LTO.Os.compiler.c.extra_flags={compilerSB.c.extra_flags}
32.menu.LTO.Os.compiler.c.elf.extra_flags=
32.menu.LTO.Os.compiler.cpp.extra_flags={compilerSB.cpp.extra_flags}
32.menu.LTO.Os.ltoarcmd=avr-ar
 
32.menu.LTO.Os_flto=LTO enabled
32.menu.LTO.Os_flto.compiler.c.extra_flags={compilerSB.c.extra_flags} -Wextra -flto -g
32.menu.LTO.Os_flto.compiler.c.elf.extra_flags=-w -flto -g
32.menu.LTO.Os_flto.compiler.cpp.extra_flags={compilerSB.cpp.extra_flags} -Wextra -flto -g
32.menu.LTO.Os_flto.ltoarcmd=avr-gcc-ar


El cambio principal es que cada conjunto de banderas se agrega al menú predeterminado. Esto agrega todas las banderas a la propiedad correcta, compiler.c.extra_flags.



Configuré la captura de errores para todos los casos para asegurarme de que todo esté asignado correctamente.



Personalización para ti



Por supuesto, puede cambiar las opciones si necesita algo diferente. También puede usar este truco para establecer otros parámetros antes de que el archivo Arduino.h obtenga el control. Hay documentación sobre cómo configurar varios parámetros de la plataforma, incluido boards.txt.



Podría ser mejor crear mi propio archivo boards.txt separado con la misma información, pero luego tendría que llevarme el resto de Mighty Core. En cambio, acabo de guardar una copia de este archivo como boards.txt.custom, y si mi menú desaparece, simplemente compararé su contenido con boards.txt para ver qué ha cambiado.



Naturalmente, si no necesita tratar con personas de apoyo que utilizan el IDE, simplemente puede olvidarse de él. Es mejor usar el IDE Pro, incluso con algunas de sus desventajas. Bueno, siempre puedes consultar Platform.io.



Ver también:






All Articles