sexta-feira, 26 de novembro de 2021

NuttX em Detalhes no U-BLOX NINA W106

O objetivo deste BLOG é demonstrar como é possível utilizar o NuttX para programação do U-BLOX NINA W106. Foi utilizado o EVK U-BLOX NINA W106.

Testado no Ubuntu 20
EVK U-BLOX NINA W106


NuttX: O sistema operacional para a Internet das Coisas.

NuttX é um sistema operacional em tempo real (RTOS) com ênfase na conformidade de padrões e pequeno footprint. Escaláveis de ambientes microcontroladores de 8 bits a 32 bits, os principais padrões de governo em NuttX são os padrões Posix e ANSI. ApIs padrão adicionais do Unix e de outros RTOS comuns (como o VxWorks) são adotadas para funcionalidades não disponíveis sob esses padrões, ou para funcionalidades que não são apropriadas para ambientes profundamente incorporados (como fork()).

Apache NuttX é um esforço em incubação na Apache Software Foundation (ASF), patrocinada pela Incubadora. A incubação é necessária de todos os projetos recém-aceitos até que uma nova revisão indique que o processo de infraestrutura, comunicação e tomada de decisão se estabilizou de forma consistente com outros projetos ASF bem-sucedidos. Embora o status de incubação não seja necessariamente um reflexo da completude ou estabilidade do código, ele indica que o projeto ainda não foi totalmente endossado pela ASF.

NuttX é um sistema operacional incorporado em tempo real (RTOS). Seus objetivos são:

Rich Feature OS Set
O objetivo é fornecer implementações da maioria das interfaces padrão do SISTEMA OPERACIONAL POSIX para oferecer suporte a um ambiente de desenvolvimento rico e multi-threaded para processadores profundamente incorporados.

Não é um objetivo fornecer o nível de recursos do SO como os fornecidos pelo Linux. Para trabalhar com MCUs menores, a pequena footprint deve ser mais importante do que um conjunto de recursos extenso. Mas a conformidade padrão é mais importante do que uma pequena footprint. Certamente um RTOS menor poderia ser produzido ignorando padrões. Pense no NuttX é um pequeno trabalho linux com um conjunto de recursos muito reduzido.

Altamente escalável
Totalmente escalável de minúsculo (8 bits) a moderado incorporado (64 bits). A escalabilidade com conjunto de recursos ricos é realizada com: Muitos arquivos de origem minúsculos, link de bibliotecas estáticas, altamente configurável, uso de símbolos fracos quando disponíveis.

Conformidade de padrões
A NuttX se esforça para alcançar um alto grau de conformidade de padrões. As principais normas de governo são as normas POSIX e ANSI. ApIs padrão adicionais do Unix e de outros RTOS comuns são adotadas para funcionalidades não disponíveis sob esses padrões ou para funcionalidades que não são apropriadas para os RTOS profundamente incorporados (como fork()).

Devido a essa conformidade de padrões, o software desenvolvido sob outros OSs padrão (como o Linux) deve ser portado facilmente para NuttX.

Tempo Real Totalmente preventivo; prioridade fixa, round-robin, e agendamento "esporádico".

Licença Apache não restritiva totalmente aberta.

GNU Toolchains Compatíveis com as cadeias de ferramentas GNU baseadas no buildroot disponível para download para fornecer um ambiente completo de desenvolvimento para muitas arquiteturas.

Colocando Nuttx no U-BLOX NINA W106

O link abaixo, é roteiro Básico para que você possa preparar o ambiente para programar o U-BLOX NINA W106 com o NuttX


    Dependências
$sudo apt install \
bison flex gettext texinfo libncurses5-dev libncursesw5-dev \
gperf automake libtool pkg-config build-essential gperf genromfs \
libgmp-dev libmpc-dev libmpfr-dev libisl-dev binutils-dev libelf-dev \
libexpat-dev gcc-multilib g++-multilib picocom u-boot-tools util-linux
Nota 1: O NuttX utiliza um sistema de build semelhante ao do Kernel do Linux (https://www.kernel.org/doc/html/latest/kbuild/index.html). Ele utiliza o kconfig-frontends como seu sistema de configuração. O repositório tools.git é utilizado para instalar este pacote. Porém se você estiver usando o Ubuntu 19.10 ou mais recente, estas distribuições já contém o pacote, mas de qualquer forma, instale.

$ sudo apt-get install kconfig-frontends


Nota 2: Outra dependência para o processo do NuttX com o ESP32 é o ESP-IDF (Espressif IoT Development Framework). Este framework é nativo do ESP e mantido pela Espressif. Ele compreende um conjunto de códigos como drivers, APIs, scripts, ferramental para compilar e fazer upload do firmware e o FreeRTOS customizado. Neste ponto, uma observação conceitual é muito importante, o NuttX não usa o FreeRTOS em nenhuma camada interna, apenas algumas ferramentas auxiliares que compõem o IDF serão utilizadas para geração do binário e gravação.
Download do NuttX
$ mkdir nuttx
$ cd nuttx
$ git clone https://github.com/apache/incubator-nuttx.git nuttx
$ git clone https://github.com/apache/incubator-nuttx-apps apps
O Ubuntu e o Debian ainda fornecem o Python 2.7 como o interpretador padrão, mas alguns 
pacotes necessários podem estar faltando para distribuições mais recentes. Python 3 é
recomendado e pode ser instalado da seguinte maneira:
 
$ sudo apt-get install python3 python3-pip python3-setuptool sudo update-alternatives --install /usr/bin/python python /usr/bin/python3
 Instale agora o ESP-IDF (ESP32 TOOLS, LIBS, ETC) manualmente
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/linux-setup.html
(ESP-IDF) extrair
mkdir -p ~/esp
cd ~/esp
git clone --recursive https://github.com/espressif/esp-idf.git

osboxes@osboxes:~$ cd esp/
osboxes@osboxes:~/esp$ cd esp-idf/
osboxes@osboxes:~/esp/esp-idf$ ./install.sh
Detecting the Python interpreter
Checking "python" ...
/home/osboxes/esp/esp-idf/tools/detect_python.sh: line 16: python: command not found
Checking "python3" ...
Python 3.8.5
"python3" has been detected
Installing ESP-IDF tools
Installing tools: xtensa-esp32-elf, xtensa-esp32s2-elf, xtensa-esp32s3-elf, riscv32-esp-elf, esp32ulp-elf, esp32s2ulp-elf, openocd-esp32
Installing xtensa-esp32-elf@esp-2020r3-8.4.0
Downloading xtensa-esp32-elf-gcc8_4_0-esp-2020r3-linux-amd64.tar.gz to /home/osboxes/.espressif/dist/xtensa-esp32-elf-gcc8_4_0-esp-2020r3-linux-amd64.tar.gz.tmp
Done
Extracting /home/osboxes/.espressif/dist/xtensa-esp32-elf-gcc8_4_0-esp-2020r3-linux-amd64.tar.gz to /home/osboxes/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0
Installing xtensa-esp32s2-elf@esp-2020r3-8.4.0
Downloading xtensa-esp32s2-elf-gcc8_4_0-esp-2020r3-linux-amd64.tar.gz to /home/osboxes/.espressif/dist/xtensa-esp32s2-elf-gcc8_4_0-esp-2020r3-linux-amd64.tar.gz.tmp
Done
.
.
.
 $ cd nuttx
$ make -C tools/esp32/ ${HOME}/esp/esp-idf
Após a instalação do IDF, ou caso já possua o IDF instalado, execute o
seguinte comando para ativar o ambiente virtual que foi configurado na
instalação. Sempre que for realizar o build do NuttX, será necessário
ativar este ambiente.
$. ${HOME}/esp/esp-idf/export.sh
No presente momento, o NuttX utiliza 2 binários gerados através do
IDF: o bootloader e a tabela de partição. Ainda dentro do diretório
/nutxtx/nuttx/, faça o download destes binários pré configurados:
$ wget -O bootloader.bin https://github.com/saramonteiro/esp32_binaries_nuttx/blob/main/bootloader.bin?raw=true
$ wget -O partitions.bin https://github.com/saramonteiro/esp32_binaries_nuttx/blob/main/partitions.bin?raw=true

Mantenha-se no diretório do NuttX e execute o script de configuração para criar um arquivo de configuração para o
U-BLOX NINA W106. 

$ make distclean
uttX has not been configured!
To configure the project:
  tools/configure.sh <config>
For a list of available configurations:
  tools/configure.sh -L
$ ./tools/configure.sh esp32-devkitc:nsh 
 

Finalmente, faça o build e confirme em seguida que o firmware binário foi gerado:
$ make
osboxes@osboxes:~/nuttx/nuttx$ make
Create .version
Create version.h
LN: include/arch/board to /home/osboxes/nuttx/nuttx/boards/xtensa/esp32/esp32-devkitc/include
make[1]: Entering directory '/home/osboxes/nuttx/nuttx/libs/libxx'
make[1]: Leaving directory '/home/osboxes/nuttx/nuttx/libs/libxx'
make[1]: Nothing to be done for 'dirlinks'. make[1]: Entering directory '/home/osboxes/nuttx/nuttx/boards'
make[1]: Entering directory '/home/osboxes/nuttx/nuttx/openamp'
make[1]: Nothing to be done for 'dirlinks'. make[1]: Leaving directory '/home/osboxes/nuttx/nuttx/boards' make[1]: Nothing to be done for 'dirlinks'.
make[2]: Entering directory '/home/osboxes/nuttx/apps/platform'
make[1]: Leaving directory '/home/osboxes/nuttx/nuttx/openamp' make[1]: Entering directory '/home/osboxes/nuttx/apps' LN: platform/board to /home/osboxes/nuttx/apps/platform/dummy
make[2]: Entering directory '/home/osboxes/nuttx/nuttx/boards/xtensa/esp32/common'
make[2]: Leaving directory '/home/osboxes/nuttx/apps/platform' make[1]: Leaving directory '/home/osboxes/nuttx/apps' make[1]: Entering directory '/home/osboxes/nuttx/nuttx/boards' make[2]: Nothing to be done for 'context'.
make[1]: Nothing to be done for 'context'.
make[2]: Leaving directory '/home/osboxes/nuttx/nuttx/boards/xtensa/esp32/common' make[1]: Leaving directory '/home/osboxes/nuttx/nuttx/boards' make[1]: Entering directory '/home/osboxes/nuttx/nuttx/fs' make[1]: Leaving directory '/home/osboxes/nuttx/nuttx/fs'
make[2]: Entering directory '/home/osboxes/nuttx/apps'
make[1]: Entering directory '/home/osboxes/nuttx/apps'
.
.
.
make[3]: Leaving directory '/home/osboxes/nuttx/apps/system/readline'
make[2]: Leaving directory '/home/osboxes/nuttx/apps'
IN: /home/osboxes/nuttx/apps/libapps.a -> staging/libapps.a
make[1]: Leaving directory '/home/osboxes/nuttx/apps'
make[1]: Leaving directory '/home/osboxes/nuttx/nuttx/fs'
make[1]: Entering directory '/home/osboxes/nuttx/nuttx/fs' make[1]: 'libfs.a' is up to date.
make[1]: Leaving directory '/home/osboxes/nuttx/nuttx/binfmt'
make[1]: Entering directory '/home/osboxes/nuttx/nuttx/binfmt' make[1]: 'libbinfmt.a' is up to date.
make[2]: 'libboard.a' is up to date.
make[1]: Entering directory '/home/osboxes/nuttx/nuttx/arch/xtensa/src' make[2]: Entering directory '/home/osboxes/nuttx/nuttx/boards/xtensa/esp32/common'
CP: nuttx.hex
make[2]: Leaving directory '/home/osboxes/nuttx/nuttx/boards/xtensa/esp32/common' LD: nuttx make[1]: Leaving directory '/home/osboxes/nuttx/nuttx/arch/xtensa/src' CP: nuttx.bin
osboxes@osboxes:~/nuttx/nuttx$

**Este binário não tem os cabeçalhos com as informações que o bootloader do ESP32 espera encontrar, então ele deve ser removido:

$ rm nuttx.bin

E um novo binário deverá ser gerado a partir do arquivo ELF chamado “nuttx”. Para isso, é necessário usar o script esptool.py para gerar este arquivo:

esptool.py --chip esp32 elf2image --flash_mode dio --flash_size 4MB -o ./nuttx.bin nuttx

$ make menuconfig
.config - NuttX/x86_64 Configuration
────────────────────────────────────────────────────────────────────────────────────
┌───────────────────────── NuttX/x86_64 Configuration ──────────────────────────
Arrow keys navigate the menu. <Enter> selects submenus ---> (or empty │
submenus ----). Highlighted letters are hotkeys. Pressing <Y> includes, │
<N> excludes, <M> modularizes features. Press <Esc><Esc> to exit, <?> for │
Help, </> for Search. Legend: [*] built-in [ ] excluded <M> module < > │
┌───────────────────────────────────────────────────────────────────────────
Build Setup --->
System Type --->
Board Selection --->
RTOS Features --->
Device Drivers --->
│ Networking Support --->
Crypto API --->
File Systems --->
Graphics Support --->
│ Memory Management --->
Audio Support --->
Video Support --->
Wireless Support --->
Binary Loader --->
Library Routines --->
Open Asymmetric Multi Processing --->
Application Configuration --->
───────────────────────────────────────────────────────────────────────────┘
├───────────────────────────────────────────────────────────────────────────────
<Select> < Exit > < Help > < Save > < Load > │
───────────────────────────────────────────────────────────────────────────────┘
make menuconfig customiza o que deseja adicionar/retirar na placa. Por exemplo, permite adicionar os drivers de um determinado periférico, adicionar mensagens de debug, etc.

Anote endereços de Gravação

Apache NuttX OS no U-BLOX NINA W106

1 Boot NuttX

2 Hello Demo

3 TIMER

4 Configure o NuttX

4.1 Habilitar ajuda e ls

4.2 Habilitar driver GPIO

4.3 Habilitar GPIO Demo

4.4 Build NuttX

5 GPIO Demo

5.1 Dispositivos NuttX

5.2 Gravar no GPIO

6 Teste o LED

7 GPIO Driver

7.1 Interface GPIO

7.2 Driver da Placa

8 Por que NuttX?

Entre todos os sistemas operacionais incorporados, o Apache NuttX é verdadeiramente único porque ...

  • O NuttX é executado em microcontroladores de 8 bits, 16 bits, 32 bits e 64 bits ...

    Abrangendo plataformas populares como RISC-V, Arm (B302), ESP32 (W106), AVR, x86, …

    (Veja isso)

  • NuttX é estritamente compatível com POSIX .

    O que significa que os aplicativos NuttX devem acessar o hardware do microcontrolador chamando open (), read (), write (), ioctl (), ...

    (Parece Linux Lite!)

  • Se você está se perguntando: NuttX foi batizado em homenagem a seu criador Gregory Nutt . E X porque é compatível com POSIX.

Hoje iremos build, atualizar e executar o NuttX no módulo U-BLOX NINA W106

Exploraremos brevemente os aspectos internos do NuttX para entender como ele funciona ...

Codificar um microcontrolador com funções semelhantes ao Linux (POSIX) pode parecer estranho, mas apreciaremos os benefícios em breve.


1 Boot NuttX

Siga as etapas abaixo para build, atualizar e executar o NuttX para BL602 e BL604 ...

Devemos ver o NuttX Shell em nosso Terminal Serial ...

NuttShell (NSH) NuttX-10.2.0-RC0
nsh>


O firmware NuttX padrão inclui dois aplicativos de demonstração ...

NuttX Hello Demo

NuttX Timer Demo

Vamos testar os aplicativos de demonstração.


2 Hello Demo

No NuttX Shell , digite ...mas antes habilite e compile

 .config - NuttX/x86_64 Configuration
 → Application Configuration → Examples ───────────────────────────────────────────────
  ┌─────────────────────────────────── Examples ────────────────────────────────────
    Arrow keys navigate the menu.  <Enter> selects submenus ---> (or empty         │  
    submenus ----).  Highlighted letters are hotkeys.  Pressing <Y> includes, <N>  │  
    excludes, <M> modularizes features.  Press <Esc><Esc> to exit, <?> for Help,   │  
    </> for Search.  Legend: [*] built-in  [ ] excluded  <M> module  < > module    │  
   ┌────↑(-)─────────────────────────────────────────────────────────────────────  
   │    [ ] FXOS8700CQ motion sensor example                                       
  [ ] GPS example                                                            
   │    [ ] HDC1008 driver example                                                 
   │    [*] "Hello, World!" example                                                
   │    (hello) Program name (NEW)                                                 
   │    (100) Hello task priority (NEW)                                            
   │    (2048) Hello stack size (NEW)                                              
   │    [ ] "Hello, World!" C++ example                                            
   │    [ ] USB HID keyboard example                                               
   │    [ ] IGMP example                                                           
   │    [ ] INA219 example                                                         
   │    [ ] INA226 example                                                         
   │    [ ] LSM330 SPI test program                                                
   │    [ ] LVGL Demo  ----                                                        
   │    [ ] "max31855" example                                                     
   │    [ ] Media test                                                             
   │    [ ] MLX90614 Test Example                                                  
   │    [ ] FreeModBus example                                                     
   │    [ ] Modbus Master example                                                  
   │    [ ] File system mount example                                              
   │    [ ] NULL example                                                           
   │    [ ] NX Demo "Graphic test" example                                         
  ────↓(+)─────────────────────────────────────────────────────────────────────┘  
  ├─────────────────────────────────────────────────────────────────────────────────  
              <Select>    < Exit >    < Help >    < Save >    < Load >             │  
  ─────────────────────────────────────────────────────────────────────────────────┘  
    

hello

Devíamos ver ...

Hello, World!!

(Sim, este é o aplicativo Hello World puro e simples !)

O código-fonte parece muito familiar: hello_main.c

#include <nuttx/config.h>
#include <stdio.h>

int main(int argc, FAR char *argv[])
{
  printf("Hello, World!!\n");
  return 0;
}

É exatamente igual ao Linux! (Quase)

Isso porque NuttX é compatível com POSIX . Ele suporta recursos do Linux como stdio, main () e printf().

Vamos rodar o Timer Demo App.


3 TIMER

No NuttX Shell , digite ...mas antes habilite e compile

 .config - NuttX/x86_64 Configuration
 → Search (timer) → Application Configuration → Examples → Search (timer) → Examples ──
  ┌─────────────────────────────────── Examples ────────────────────────────────────
    Arrow keys navigate the menu.  <Enter> selects submenus ---> (or empty         │  
    submenus ----).  Highlighted letters are hotkeys.  Pressing <Y> includes, <N>  │  
    excludes, <M> modularizes features.  Press <Esc><Esc> to exit, <?> for Help,   │  
    </> for Search.  Legend: [*] built-in  [ ] excluded  <M> module  < > module    │  
   ┌────↑(-)─────────────────────────────────────────────────────────────────────  
   │    [ ] RGB LED Test                                                           
   │    [ ] Serial Blaster example                                                 
   │    [ ] Serial RX example                                                      
   │    [ ] Serial loopback example                                                
   │    [ ] Segment LCD test                                                       
   │    [ ] Smps example                                                           
   │    [ ] Test of stat(), fstat(), and statfs()                                  
   │    [ ] Simple TCP echo server                                                 
   │    [ ] Termios example                                                        
   │    [ ] TIFF file generation example                                           
   │    [*] Timer example                                                          
   │    (/dev/timer0) Timer device name (NEW)                                      
   │    (1000000) Timer interval (microseconds) (NEW)                              
   │    (100000) Sample delay (microseconds) (NEW)                                 
   │    (20)  Number of samples (NEW)                                              
   │    (17)  Notification signal number (NEW)                                     
   │    (2048) Timer stack size (NEW)                                              
   │    (100) Timer task priority (NEW)                                            
   │    (timer) Timer program name (NEW)                                           
   │    [ ] Touchscreen example                                                    
  [ ] UID/GID example                                                        
   │    [ ] USB serial test example                                                
  ────↓(+)─────────────────────────────────────────────────────────────────────┘  
  ├─────────────────────────────────────────────────────────────────────────────────  
              <Select>    < Exit >    < Help >    < Save >    < Load >             │  


timer

Devemos ver algumas mensagens de tempo limite . (Foto acima)

Este aplicativo de demonstração acessa o System Timer de uma forma interessante: timer_main.c


  1. /dev/timer0 aponta para o temporizador do sistema

    (Tudo é um arquivo ... Assim como o Linux!)

  2. Chamamos open() para acessar o System Timer

  3. ioctl() para definir o tempo limite

  4. sigaction() para registrar o manipulador de tempo limite

open(), ioctl() e sigaction() são funções comuns chamadas por Linux Apps.

Os aplicativos NuttX realmente se parecem com os aplicativos Linux!


4 Configure o NuttX

Vamos nos aventurar e adicionar comandos NuttX ...

  • “help” para mostrar os comandos disponíveis

  • “ls” para listar os dispositivos em /dev

  • “gpio” para alternar a saída GPIO e liga/desligar um LED

(Veja a foto acima)

Digite este comando para configurar a construção NuttX em nosso computador ...

make menuconfig

Vamos explorar as opções.

(Mais sobre como configurar o NuttX)


4.1 Habilitar help e ls

No menuconfig , selecione “Application Configuration” . (Foto acima)

Selecione “NSH Library” …


Selecione “Disable Individual Commands" ...

Desmarque as caixas para “help” e “ls” …

“Help” e “ls” agora estão habilitados no NuttX Shell!

No U-BLOX NINA W106 (ESP32) já estão habilitados.

4.2 Habilitar driver GPIO

Pressione “Exit” até que o Menu Principal apareça. (“NuttX / x64_64 Configuration”)

Selecione “Device Drivers” ….


Selecione “IO Expander/GPIO Support” …

Marque a caixa para “GPIO Driver” …


Isso ativa o driver GPIO para NuttX.

(Se não habilitarmos o driver GPIO, o NuttX não nos deixará selecionar o aplicativo de demonstração GPIO!)

4.3 Habilitar GPIO Demo

Pressione “Exit” até que o Menu Principal apareça. (“NuttX / x64_64 Configuration”)

Selecione “Application Configuration” …


Selecione “Examples” …

NuttX revela a lista de aplicativos de demonstração ...


(Os aplicativos Hello e Timer Demo já estão selecionados)

Marque a caixa para “GPIO Driver Demo” …


Compilador Solicitou


Clique em “Save” …


Em seguida, clique em “OK” para salvar a configuração do NuttX em “.config” .

Pressione “Exit” até que o menuconfig feche.

4.4 Rebuild NuttX

Reconstrua e copie o firmware NuttX ...

#  Rebuild NuttX
make
make flash

Estamos prontos para testar os novos comandos!

Comandos ls e gpio

5 GPIO Demo

Vamos executar os novos comandos: “help”, “ls” e “gpio” .

No NuttX Shell, digite ...

help

(“?” Também funciona)

O NuttX diz que os comandos “ls” e “gpio” agora estão disponíveis…

help usage: help [-v] [<cmd>]
  ?  help  ls  uname
Builtin Apps:
  timer  sh  getprime  hello  nsh  gpio

5.1 Dispositivos NuttX

Lembra que tudo é um arquivo no NuttX?

Vamos listar os dispositivos de hardware no NuttX ...

ls /dev

NuttX revela os dispositivos que podemos controlar ...

nsh> ls /dev
/dev:
 console
 gpin0
 gpint0
 gpout0
 null
 timer0
 ttyS0
nsh>
  • /dev/console é o console serial (UART)

  • /dev/gpin0 lê da entrada GPIO

    (Porque habilitamos o driver GPIO)

  • /dev/gpint0 captura a interrupção GPIO

  • /dev/gpout0 grava na saída GPIO

    (Mas qual pin GPIO? Aprenderemos em breve)

  • /dev/null é o dispositivo nulo

    (Igual ao Linux)

  • /dev/timer0 é o temporizador do sistema

    (Já vimos isso antes)

  • /dev/zero é a fonte nula

    (Igual ao Linux)

Vamos escrever para a saída GPIO em /dev/gpout1 


5.2 Gravar no GPIO

Digite aqui para definir a saída GPIO para alta ...

gpio -o 1 /dev/gpout0

(Conforme explicado na foto acima)

A saída GPIO muda de baixo para alto ...

Driver: /dev/gpout0
  Output pin:    Value=0
  Writing:       Value=1
  Verify:        Value=1

Podemos fazer isso para ligar e desligar um LED?

Ainda não. Não dissemos ao NuttX a qual pino GPIO nosso LED está conectado!

Vamos aprender como.

Em osboxes@osboxes:~/nuttx/nuttx/boards/xtensa/esp32/esp32-devkitc/src$ nano esp32_gpio.c

/****************************************************************************
 * Pre-processor Definitions
 ****************************************************************************/

#if !defined(CONFIG_ESP32_GPIO_IRQ) && BOARD_NGPIOINT > 0
#  error "NGPIOINT is > 0 and GPIO interrupts aren't enabled"
#endif

/* Output pins. GPIO15 is used as an example, any other outputs could be
 * used.
 */

#define GPIO_OUT1    15

/* Input pins. GPIO18 is used as an example, any other inputs could be
 * used.
 */

6 Teste o LED

Vamos ligar e desligar o LED do U-BLOX NINA W106

Conecte um LED  ao GPIO 15

No NuttX Shell, digite isso para virar GPIO 15 para High ...

gpio -o 1 /dev/gpout0

NuttX vira GPIO 11 de baixo para alto ...

gpio -o 0 /dev/gpout0
NuttShell (NSH) NuttX-10.1.0
nsh> gpio -o 1 /dev/gpout0
Driver: /dev/gpout0
  Output pin:    Value=0
  Writing:       Value=1
  Verify:        Value=1
nsh> gpio -o 0 /dev/gpout0
Driver: /dev/gpout0
  Output pin:    Value=1
  Writing:       Value=0
  Verify:        Value=0
nsh>

Parabéns, testamos com sucesso o LED com NuttX!

(Tem problemas com o GPIO? Veja estas dicas de solução de problemas)

(Se estivermos controlando LEDs, considere usar o driver de LED do NuttX)


7 GPIO Driver

Vamos dar uma olhada dentro do NuttX para entender como o driver GPIO funciona.

Começamos com o comando “gpio” : gpio_main.c

Na foto acima, vemos que o comando “gpio” chama…

  • abra (“/dev/gpout1”, ...) para acessar o PIN GPIO

  • ioctl (…, GPIOC_READ,…) para ler o PIN GPIO

  • ioctl (..., GPIOC_WRITE, ...) para gravar no pino GPIO

O que são GPIOC_READ e GPIOC_WRITE ?

GPIOC_READ e GPIOC_WRITE são comandos de driver GPIO definidos na interface NuttX GPIO…

  • Interface NuttX GPIO

comando “gpio” funciona em todas as plataformas NuttX porque chama a interface GPIO comum.

7.1 Interface GPIO

Abaixo está a implementação da interface GPIO independente de plataforma (ioctl): gpio.c

//  Standard character driver ioctl method
static int gpio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
  ...
  //  Handle each GPIO Driver Command...
  switch (cmd)
    {
      //  If we're setting the value of an output GPIO...
      case GPIOC_WRITE:
        ...
        //  Call the Board-Specific GPIO Driver
        ret = dev->gp_ops->go_write(
          dev,       //  GPIO Device
          (bool)arg  //  1 (High) or 0 (Low)
        );

Este é um driver de dispositivo de personagem que lida com cada comando de driver GPIO (como GPIOC_WRITE).

O driver chama o driver GPIO específico da placa para executar o comando.

7.2 Driver da Placa

O que é um driver específico da placa?

Cada placa de desenvolvimento possui recursos de hardware específicos da placa. Como LEDs conectados em diferentes pinos GPIO.

O NuttX isola essas diferenças de placa chamando um driver específico da placa .

(Na verdade, estamos chamando o driver específico da placa para BL602 EVB)

Aqui está nosso driver GPIO específico da placa : bl602_gpio.c

/****************************************************************************
 * Name: gpout_write
 ****************************************************************************/

static int gpout_write(FAR struct gpio_dev_s *dev, bool value)
{
  FAR struct esp32gpio_dev_s *esp32gpio = (FAR struct esp32gpio_dev_s *)dev;

  DEBUGASSERT(esp32gpio != NULL);
  DEBUGASSERT(esp32gpio->id < BOARD_NGPIOOUT);
  gpioinfo("Writing %d\n", (int)value);

  esp32_gpiowrite(g_gpiooutputs[esp32gpio->id], value);
  return OK;
}
#endif

g_gpiooutputs mapeia o dispositivo GPIO (como “/dev/gpout0”) para um conjunto de pinos GPIO , que contém o número do pino GPIO .

(O que faz sentido, porque cada placa pode mapear os dispositivos de hardware para diferentes pinos GPIO)

O driver específico da placa chama o driver GPIO específico do U-BLOX NINA W106 para definir a saída GPIO, passando o conjunto de pinos GPIO.

8 Por que o NuttX?

Agora que entendemos o NuttX de dentro para fora, vamos conversar ...

Estou familiarizado com o Embedded Coding no Arduino / STM32 / nRF52. A interface POSIX do NuttX parece muito estranha para mim: open(), read(), ioctl(), ...

Bem, a interface POSIX do NuttX pode ser uma boa coisa para pessoas que estão familiarizadas com Linux e computadores de placa única.

A equipe do NuttX fez um trabalho incrível reforçando a consistência da API em todos os tipos de plataformas. “Escreva uma vez, execute em qualquer lugar” pode ser verdade no NuttX!

Em qualquer caso, é difícil encontrar um sistema operacional integrado de código aberto que suporte tantas plataformas.


DÚVIDAS


Sobre a SMARTCORE

A SmartCore fornece módulos para comunicação wireless, biometria, conectividade, rastreamento e automação.
Nosso portfólio inclui modem 2G/3G/4G/NB-IoT/Cat.M, satelital, módulos WiFi, Bluetooth, GNSS / GPS, Sigfox, LoRa, leitor de cartão, leitor QR code, mecanismo de impressão, mini-board PC, antena, pigtail, LCD, bateria, repetidor GPS e sensores.
Mais detalhes em www.smartcore.com.br