Manual

do

Maker

.

com

RTOS - Nuttx no BluePill (STM32F103-Minimum board)

RTOS - Nuttx no BluePill (STM32F103-Minimum board)

Em 2007 lembro de ter participado de uma palestra no FISL, junto ao Marcelo Barros. Nessa ocasião, conheci o Alan Carvalho, que também palestrou no FISL8 com o tema "Linux BIOS" - uma BIOS livre baseada em Linux. Foi incrível a apresentação, a galera aplaudiu de pé. Nos hospedamos juntos em um hotel na época, mantivemos contato e recentemente li um artigo do Alan, que encontrei pelo Linkedin. Trata-se do Nuttx.

Atenção: As versões mais recentes já não estão no mesmo repositório e diversas coisas mudaram com o passar dos anos. Pinout, wiring, recursos e outras informações desse artigo ainda são importantes, mas procure por NuttX na caixa de pesquisa para ver os artigos mais atuais, a partir de Novembro de 2021.

O Alan fez o port do Nuttx para a STM32F103CBT6, que ainda escreverei a respeito dela.

Atualmente Nuttx roda em ESP32 também. O sistema é interessante, porém depende de um aprendizado mais dedicado.

Se quiser conhecer o blog do Alan, dê uma passada clicando nesse link. Ele escreve seus tutoriais em inglês, se você não tiver dificuldade com o idioma, será bastante prazerosa a visita.

O que é o Nuttx

O Nuttx é um sistema operacional de tempo real (RTOS) de 2007, hoje em um estágio bastante avançado e adotado por gigantes do mercado. Mas não é "apenas" um RTOS; é um RTOS POSIX! Se você conhece o padrão Portable Operating System Interface, já deve estar compreendendo a excelência desse RTOS. Ele possui um shell, a partir do qual é possível digitar comandos como em um console tradicional. Programar para ele não exige conhecimento em uma API específica, uma vez que existe o padrão de portabilidade, incluindo algumas bibliotecas que facilitam a criação de programas.

Plataformas

Graças ao formato do sistema, ele pode ser incluído em diferentes arquiteturas, em controladoras com pouquíssimos recursos, mas também em placas com muitíssimos recursos, pois possui inclusive suporte a interface de video. Não vou ficar escrevendo muito a respeito porque realmente um especialista nesse sistema é o Alan, mas comecei a brincar com o sistema para futuramente utilizá-lo no ESP32.

Hoje esse sistema já funciona no ESP32, mas ainda está em um estado primitivo e o primeiro passo que estou dando é compilá-lo para uma placa baratinha;

STM32F103C8T6

Essa placa é uma ARM 32bits Cortex M3, roda à 72MHz, tem 64 ou 128KB de flash, com 20KB de SRAM. Ela trabalha em 3v3, portanto não é tolerante a 5V. Possui montes de recursos, 2 interfaces I2C, 3 USARTs, 2 SPI, CAN e, claro, a USB.

Onde comprar

Custando menos que um Arduino UNO (!), você pode adquirí-la na Autocore Robótica e iniciar suas experiências em um sistema operacional de tempo real sem gastar muito pra isso. Não é incrível? E garanto, a experiência vale muito a pena. Ainda mais que futuramente passarei a utilizar esse sistema no ESP32 e se você estiver ambientado com esse RTOS nessa board, não terá o mínimo trabalho em utilizá-lo no ESP32 quando quiser investir em um.

Compilar o Nuttx

O procedimento é bastante parecido para qualquer uma das arquiteturas suportadas. Basicamente, devemos compilar o sistema para gerar o firmware e então gravá-lo na board.

nuttx_configs.webp

Preparando o ambiente

Como sempre cito, só uso Linux e o procedimento é todo em Linux. Primeiramente, devemos instalar os pacotes e suas dependências.

sudo su
apt-get update
apt-get install gcc-arm-none-eabi gdb-arm-none-eabi gperf \
libncurses5-dev flex bison git

As dependências relacionadas a esses pacotes devem ser automaticamente supridas. Agora precisamos ter no sistema o kconfig-frontends, para que possamos utilizar a interface de configuração do Nuttx. Para centralizar toda a configuração, sugiro que crie os diretórios abaixo, entre nele e faça o processo de clonagem do repositório, seguido pela cópia para o sistema:

#não esteja como root por enquanto
cd
mkdir -p nx/misc
cd nx/misc
git clone https://github.com/nekromant/kconfig-frontends-debian.git
cd kconfig-frontends-debian
sudo cp -r debian/kconfig-frontends/usr/ /
cd ~/nx

Download do Nuttx

Pegue os dois pacotes; appsnuttx. Eu baixei a versão 7.23, sinta-se a vontade para pegar uma mais atual ou mais antiga nesse link.

Minha sugestão é que baixe-a ou copie-a para o diretório nx recém criado. Depois, descomprima os pacotes.

cd ~/nx
#tendo-os aqui, basta descomprimir
ls *.gz|while read line; do tar xvzf $line; done

Selecionando a placa

Agora é hora de configurar o sistema para compilação. Entre no diretório nuttx-7.23**/tools** e execute o script de configuração.

cd nuttx-7.23/tools
./configure.sh -l stm32f103-minimum/nsh

As boards podem ser vistas no diretório ~/nx/nuttx-7.23/configs. Dentro desse diretório tem as configurações possíveis. O nsh é o NuttShell. É aí que a coisa começa ficar interessante. Ele pode ser utilizado com saída para stdUSB-serial ou telnet para o console. Múltiplas sessões são permitidas. Veremos detalhes sobre o nsh mais adiante. Quanto às boards suportadas, é só dar uma olhada na imagem mais acima.

nuttx-configure.webp

Executar o front-end

Agora é só certificar-se de que em Build Setup está selecionada a opção Build Host Platform (Linux) e em System Type está selecionada a opção Toolchain Selection (Generic GNU EABI toolchain under Linux (or other POSIX environment)). Eu adicionei o suporte a USB.

nuttx-make_menuconfig.webp

No submenu I2C eu optei por criar uma interface i/dev/i2c[N] para transferir dados entre aplicação ou para fazer debug, ainda não testei. Mas essa opção não é própria para comunicação entre dispositivos, não é necessário selecioná-la.

Ao concluir, selecione e depois . Depois, basta compilar:

make

O resultado da compilação é um arquivo chamado nuttx e nuttx.bin, o primeiro do tipo ELF, o segundo é identificado apenas como data:

nuttx-firmware.webp

Maple Mini pinout

Não menos importante, o pinout dessa board. Atente-se aos pinos B9B10, tratando-se da comunicação serial.

stm32_pinout.jpg

Flashing

Pra fazer flashing será necessário, bem; um gravador. Talvez você esteja pensando:

"Mas não é uma plaquinha barata? Se eu comprar o gravador, vai ficar o preço de um Arduino UNO então".

Verdade. Se você comprar ambos, ficará no preço de um Arduino. Mas se você comprar duas, três, quatro STM32, usará o mesmo gravador. E ele grava tanto da família STM8 como a STM32. Continua valendo a pena, hum?

Atenção

Se você for conectar o gravador e a porta USB ao mesmo tempo, não coloque o VCC do gravador na placa, ok?

ST-Link V2 wiring

Esse gravador é fácil de encontrar no Mercado Livre e é barato. Precisamos conectar 3 fios:

ProgramadorSTM32
GroundGND
SWDIODIO
SWCLKDCLK

Se a board for energizada a partir do programador, lembre-se de não conectá-lo à porta usb. Após conectar, identifique a porta serial criada pelo sistema veja mais adiante como criar a porta serial para o stlink no sistema).

Configurar  ST-Link V2 no Debian

Primeiramente, eu não encontrei pacote pré-compilado, mas sei que tem. De qualquer modo, basta clonar o repositório da ferramenta e compilar. Além disso, alguns comandos extras serão necessários até que o sistema esteja funcional. Não conecte o St-Link V2 ainda.

git clone https://github.com/texane/stlink.git
cd stlink
make build

O binário vai ficar em build/Release e se chama st-flash. Para instalá-lo no sistema, precisamos (além do comando make instal****l) fazer o carregamento da biblioteca.

sudo make install
sudo ldconfig

O processo ainda não terminou. Precisamos adicionar as regras para que o udev atue adequadamente na criação do dispositivo para o stlink.

De dentro do diretório stlink, copie as regras para /etc/udev/rules.d:

cp etc/udev/rules.d/* /etc/udev/rules.d/

Feito isso, recarregue o udev:

sudo udevadm control --reload-rules
sudo udevadm trigger

O próximo passo é criar o grupo stlinke adicionar seu usuário a esse grupo:

sudo groupadd stlink
sudo usermode -G stlink $USER

Maple Mini  - bootloader

Se estiver procurando por um bootloader, você pode ir a esse link e baixá-lo de lá, mas não vamos entrar nessas questões agora, ok? No momento, o objetivo é subir o Nuttx.

O comando é simples, pode receber parâmetros e aumentar a complexidade. Apenas para dar uma prévia, finalizaremos com:

st-flash write nuttx.bin 0x8000000

Comando pelo GDB

Ainda não executei, com certeza no formato em que está abaixo não funciona, mas já é uma referência que não vou deixar passar porque pretendo utilizar dessa forma também:

arm-none-eabi-gdb nuttx
target extended-remote /dev/ttyACM0
mon swdp_scan
attach 1
load
kill

Utilizei a porta serial /dev/ttyACM0 mas obviamente você deverá indicar a porta criada pelo seu sistema.

Quis mostrar os dois comandos separados porque mais adiante você verá uma combinação do debugger com o flasher.

Dificuldade para identificar a porta no Linux?

Uma das formas de saber a porta criada é monitorar o log do sistema:

**sudo tail -f /var/log/messages**

Esse comando é interrompível com Ctrl+C. Se o seu sistema não utiliza o messages, você pode conectar o dispositivo e então digitar:

**sudo dmesg**

A porta deverá aparecer nas últimas linhas da saída desse comando.

Outra maneira é fazer a listagem antes de conectar a placa e também depois. Se não tiver outro dispositivo conectado à porta USB, a identificação será mais fácil.

**ls /dev/tty\***

Fazer backup do firmware atual

Esse comando pode eventualmente ser dispensado caso já tenha um backup ou ainda, caso já tenha feito a operação demasiadas vezes.

**st-flash --reset read bkp\_stlink.bin 0x8000000 0x20000**

Isso gerará o arquivo bkp_stlink.bin.

Hello World

Para subir seu primeiro teste, faça o seguinte processo:

**git clone https://github.com/fishpepper/OpenGround.git
cd OpenGround
make
make flash**

É um bom teste inicial, ainda mais se sua placa veio (ou está) sem o blink, mas você pode preferir subir direto o sistema, seguindo os próximos passos.

Subir o Nuttx ou retornar do backup

O procedimento serve para fazer flashing, seja do Nuttx ou outro firmware, como o de backup.

**st-flash write nuttx.bin 0x8000000**

O primeiro comando abre o GDB e executa uma conexão remota ao dispositivo um shell conectado ao GDB e em outro terminal executamos o st-flash.

maple_mini-flashing.webp

Primeiro contato com o sistema

O processo pode ter parecido longo, mas é simples. Fiz em um Debian "iStrash" e em um Linux Mint, ambos com a mesma rotina e não tive surpresas. Agora você tem um ambiente de compilação pronto, daqui em diante faremos os tutoriais utilizando o que já temos e tudo será bem simples e rápido!

Fazendo a primeira conexão

Apesar de colocar tudo isso pra funcionar, ainda tenho dúvidas em relação ao bootloader, que devo discorrer a respeito no próximo artigo, mas como esse já está bastante longo e coloca todas as coisas do ambiente pra funcionar, decidi publicar antes que vire um livro.

A conexão serial pode ser feita nos pinos B9 e B10 para TX e RX, respectivamente. Não podemos nos esquecer de colocar também o GND. Nesse momento já podemos estar alimentando a board pela porta USB (e já com o gravador desligado).

No momento estou com os meus 2 FTDIs em uso, mas no próximo artigo já devo mostrar um pouco do sistema operacional. Eu não sei se o shell responde na porta serial, preciso testar. Supondo que funcione, fazemos uma conexão serial que abrirá o prompt do NuttShell. Fora isso, temos que apreciar um pouco do debugger, e aí que começa a segunda parte da diversão, acompanhe!

Inscreva-se no nosso canal Manual do Maker no YouTube.

Também estamos no Instagram.

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.