Cirurgia para aumentar o buffer da porta serial do IDE Arduino





Não sou um grande fã da infraestrutura do Arduino. Sim, hoje já temos mais opções - por exemplo, pro IDE e Platform IO . No entanto, sempre sinto azia com o IDE original. E só apreciei toda a sua extensão no dia anterior, quando quis fazer algo muito simples: aumentar o buffer de recepção da porta serial ATmega32. No final, encontrei uma solução que pode ajudá-lo com outros problemas também - então, mesmo que você não precise especificamente desse recurso, pode ser útil ver o que exatamente eu fiz.



Essa experiência me deixou uma dupla impressão. Por um lado, desprezo este editor indefinido por esconder muito de mim e fornecer poucas ferramentas úteis. Por outro lado, fiquei impressionado com o quão flexível ele é quando você se aprofunda nos detalhes de sua estrutura interna.



Primeiro, você provavelmente está perguntando por que estou usando um IDE. Resumindo, eu não uso. No entanto, se você fizer algo que outras pessoas usarão, é quase impossível ignorar. Independentemente de como você configurar seu próprio IDE, assim que seu código ficar online, alguém tentará usá-lo com o IDE. Certa vez, escrevi sobre um computador baseado no Z80 de $ 4 . Raramente tenho tempo para construir sobre o que estou escrevendo, mas realmente queria tentar construir este pequeno computador. Por um tempo, tudo ficou meio desmontado, e então eles me enviaram um pagamento por ele. Eu o recebi e - como você deve ter adivinhado - ainda estava meio desmontado. Mas finalmente encontrei tempo para terminar o projeto e baixei o CP / M.







O único problema com o projeto era a falta de boas opções para transferir dados dele para o PC e vice-versa. Parecia que a melhor coisa a fazer era criar arquivos hexadecimais Intel e copiá-los / colá-los através do terminal. Eu queria algo melhor e acabei em uma toca de coelho na manhã de sábado. Como resultado, descobri uma maneira de adicionar meus próprios itens de menu ao IDE do Arduino para editar as configurações do compilador dependendo do hardware usado no projeto. Vale a pena aprender este truque, pois pode ser útil fora desta tarefa específica.



Problema: limitação do tamanho do buffer da porta serial do Arduino



Não vou incomodá-lo com detalhes sobre como fazer o quadro funcionar, pois você só se interessará se tiver um. Todos os detalhes estão na discussão em Hackaday.io se você realmente precisar deles . Como resultado, o buffer da porta serial do Arduino não era grande o suficiente para que a transmissão por meio do XModem fosse considerada confiável. Tudo parecia funcionar com o buffer padrão de 64 bytes, mas o XModem está enviando mais dados e é fácil imaginar o estouro do buffer.



Pode ser difícil atualizar um buffer? Por outro lado, essa é uma tarefa trivial. Por outro lado, é muito difícil, porque suas ferramentas estão se esforçando muito para ajudá-lo.



Kit de ferramentas



O projeto do pequeno computador usa o chip Z80 real e ATMega32A para quase todas as funções auxiliares. Ele fornece velocidade de clock, porta serial, armazenamento, etc. No entanto, o Arduino IDE não oferece suporte direto para ATMega32A, portanto, você deve instalar uma caixa de ferramentas para fazer isso. A situação exigia MightyCore , então eu o usei.



As bibliotecas de porta serial são configuradas com instruções #define para que você possa corrigir o tamanho do buffer. Por padrão, se nada estiver configurado, você obterá valores com base na quantidade de RAM disponível:



#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


Fazendo mudanças



É simples, não é? Defina os símbolos antes de carregar HardwareSerial.h. Merda - esse arquivo é carregado no Arduino.h. O SP deseja adicioná-lo ao seu programa e faz com que ele inicialize primeiro. Parece que algumas versões do IDE verificaram se você já o ativou para não reativá-lo, mas a versão 1.8.5 não. Talvez eu possa passar algumas configurações para o compilador? Não. Pelo menos não por meio do IDE.



Eu tentei muitas coisas. Eu queria, é claro, apenas mudar as bibliotecas principais. Mas isso não é bom. Posteriormente, você pode precisar das configurações padrão. Se você atualizar a caixa de ferramentas, todas as atualizações serão perdidas. Eu queria evitar isso. Alguém na Internet aconselhou fazer uma cópia dos arquivos da plataforma e modificá-los. Não é uma solução perfeita.



Verificando as suposições com



Pude ver que o que eu estava fazendo não estava funcionando, pois estava inserindo temporariamente as instruções #if e #error em HardwareSerial.cpp. Por exemplo:



#if SERIAL_RX_BUFFER_SIZE==256
#error 256
#endif


Agora, se o erro 256 travar durante a compilação, sei que o tamanho está definido. Se não, o sistema resiste às minhas mudanças.



Troca: adicionar configurações aos menus de nível de quadro



Eu realmente queria encontrar uma maneira de alterar as configurações apenas em um projeto específico e, assim, definir o tamanho do buffer serial. Eu não tive sucesso. Mas consegui mudar o boards.txt do Mighty Core. Sim, terei que garantir que as atualizações não substituam minhas edições, mas são simples, e se algo estiver faltando no arquivo, será óbvio.







Obviamente, isso acontecerá porque criei um menu para o IDE, que só aparece ao usar o ATMega32 para Mighty Core. Um dos tamanhos de buffer predefinidos pode ser selecionado no menu.



Para alcançar este resultado, você precisa realizar três etapas:



  1. Diga ao IDE que você tem um novo item de menu e descreva sua aparência.
  2. O novo item deve alterar as configurações do compilador.
  3. Como o sistema existente também altera as configurações do compilador, você precisa ter certeza de que eles não serão corrompidos.


O primeiro passo é fácil. Meu arquivo boards.txt estava em ~ / .arduino15 / packages / MightyCore / hardware / avr / 2.0.5 / boards.txt. Quase no topo há uma lista de itens do menu e, no final, adicionei o meu:



# 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)


Em seguida, movi as linhas para baixo e adicionei meu menu na frente da configuração 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


Estrutura do menu



Você pode ver que o objeto 32.menu agrupa todos os itens juntos para um determinado processador. Em seguida, vem nossa chave de menu (SerialBuf). Isso é seguido por teclas exclusivas para cada item do menu. É importante não reutilizá-los. Se, por exemplo, você tiver duas chaves SB64, apenas uma delas funcionará.



Se você atribuir um sinal de igual a esta tecla, poderá atribuir texto a este item de menu. Por exemplo, "Padrão" ou "64/64". Você também pode adicionar uma propriedade à chave e ela será atribuída quando o item for ativado.



Se, por exemplo, selecionar 256/256, o compilador configura a propriedade compilerSB.c.extra_flags. Por que eu criei esse nome para a propriedade, você vai entender um pouco mais tarde.



Coexistência pacífica



A propriedade compilerSB.c.extra_flags não está presente. Corretamente, é chamado de compiler.c.extra_flags. No entanto, a configuração do Mighty Core LTO usa a mesma chave. Portanto, era importante que o novo menu aparecesse primeiro e também definisse uma propriedade falsa. Então você precisa corrigir o 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


A principal mudança é que cada conjunto de sinalizadores é adicionado ao menu predefinido. Isso adiciona todos os sinalizadores à propriedade correta, compiler.c.extra_flags.



Eu configurei a interceptação de erro para todos os casos para garantir que tudo seja atribuído corretamente.



Personalização para você



Claro, você pode alterar as opções se precisar de algo diferente. Você também pode usar esse truque para definir outros parâmetros antes que o arquivo Arduino.h obtenha o controle. Há documentação sobre como configurar vários parâmetros da plataforma, incluindo boards.txt.



Pode ser melhor criar meu próprio arquivo boards.txt separado com as mesmas informações, mas então eu teria que levar o resto do Mighty Core comigo. Em vez disso, acabei de salvar uma cópia desse arquivo como boards.txt.custom e, se meu menu desaparecer, compararei seu conteúdo com boards.txt para ver o que mudou.



Naturalmente, se você não precisa lidar com o suporte de pessoas que usam o IDE, pode simplesmente esquecê-lo. Melhor usar o Pro IDE, mesmo com algumas de suas desvantagens. Bem, você sempre pode consultar Platform.io.



Veja também:






All Articles