quinta-feira, 28 de janeiro de 2021

Programando u-blox NINA-W102 com NuttX - Acesso GPIO connectado ao LED

Programando u-blox NINA-W102 com NuttX - Acesso GPIO connectado ao LED


O objetivo deste BLOG é demonstrar como é possível utilizar o NuttX para programação do NINA W102. Foi utilizado o EVK NINA W102 para o teste. O exemplo abrirá um terminal para interagir com o NuttX, com um APP para fazer um acesso ao LED na GPIO33.

Testado no Ubuntu 20
EVK NINA W102


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:

Pequena footprint utilizável em todos, exceto nos ambientes de microcontroles mais apertados, o foco está no ambiente minúsculo para pequeno e profundamente incorporado.

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.

NINA W102 E NuttX
Como o módulo NINA W102 é baseado no chip ESP32 (cpu), será possível rodar o Nuttx sem problemas. O usuário deve dar atenção ao mapeamento de GPIOS da U-BLOX.


O link abaixo, é roteiro Básico para que você possa preparar o ambiente para programar o NINA W102 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
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html#get-started-get-esp-idf


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

$ make distclean
$ ./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 2MB -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.
Após compilar, será gerado um BIN, o mesmo deve ser gravado no UBLOX NINA W102, via FLASHTOOLS, junto com partitions.bin e bootloader.bin.
Pode também ser utilizado esptools

TESTANDO NO NINA W102
Abra então o TERATERM (115200,N,8.1)


Conexão com USB para SERIAL


Adicionando APP para o NINA W102

Estando no diretório do nuttx, limpe a sua configuração atual, carregue a configuração para o ESP32 com o nsh (NuttX shell) e por fim entre no menu de configuração através do comando a seguir: 

$ make distclean
$
./tools/configure.sh esp32-devkitc:nsh
$ make menuconfig

osboxes@osboxes:~/nuttx/nuttx$ ./tools/configure.sh esp32-devkitc:nsh
  Copy files
  Select CONFIG_HOST_LINUX=y
  Refreshing...
make[1]: Entering directory '/home/osboxes/nuttx/nuttx'
make[2]: Entering directory '/home/osboxes/nuttx/nuttx/boards'
make[2]: Leaving directory '/home/osboxes/nuttx/nuttx/boards'
make[2]: Entering directory '/home/osboxes/nuttx/apps'
make[3]: Entering directory '/home/osboxes/nuttx/apps/platform'
make[3]: Leaving directory '/home/osboxes/nuttx/apps/platform'
make[3]: Entering directory '/home/osboxes/nuttx/apps/builtin'
make[3]: Leaving directory '/home/osboxes/nuttx/apps/builtin'
make[2]: Leaving directory '/home/osboxes/nuttx/apps'
make[2]: Entering directory '/home/osboxes/nuttx/nuttx/graphics'
make[3]: Entering directory '/home/osboxes/nuttx/nuttx/graphics/nxglib'
make[3]: Leaving directory '/home/osboxes/nuttx/nuttx/graphics/nxglib'
make[3]: Entering directory '/home/osboxes/nuttx/nuttx/graphics/nxglib'
make[3]: Leaving directory '/home/osboxes/nuttx/nuttx/graphics/nxglib'
make[3]: Entering directory '/home/osboxes/nuttx/nuttx/graphics/nxglib'
make[3]: Leaving directory '/home/osboxes/nuttx/nuttx/graphics/nxglib'
make[2]: Leaving directory '/home/osboxes/nuttx/nuttx/graphics'
make[2]: Entering directory '/home/osboxes/nuttx/nuttx/arch/xtensa/src'
make[2]: Nothing to be done for 'clean_context'.
make[2]: Leaving directory '/home/osboxes/nuttx/nuttx/arch/xtensa/src'
make[1]: Leaving directory '/home/osboxes/nuttx/nuttx'
LN: include/arch to arch/xtensa/include
LN: include/arch/board to /home/osboxes/nuttx/nuttx/boards/xtensa/esp32/esp32-devkitc/include
LN: include/arch/chip to arch/xtensa/include/esp32
LN: arch/xtensa/src/board to /home/osboxes/nuttx/nuttx/boards/xtensa/esp32/esp32-devkitc/../common
LN: arch/xtensa/src/board/board to /home/osboxes/nuttx/nuttx/boards/xtensa/esp32/esp32-devkitc/src
LN: arch/xtensa/src/chip to arch/xtensa/src/esp32
LN: /home/osboxes/nuttx/nuttx/drivers/platform to /home/osboxes/nuttx/nuttx/boards/xtensa/esp32/esp32-devkitc/../drivers
make[1]: Entering directory '/home/osboxes/nuttx/nuttx/libs/libxx'
make[1]: Nothing to be done for 'dirlinks'.
make[1]: Leaving directory '/home/osboxes/nuttx/nuttx/libs/libxx'
make[1]: Entering directory '/home/osboxes/nuttx/nuttx/boards'
make[1]: Leaving 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/openamp'
make[1]: Entering directory '/home/osboxes/nuttx/apps'
make[2]: Entering directory '/home/osboxes/nuttx/apps/platform'
LN: platform/board to /home/osboxes/nuttx/apps/platform/dummy
make[2]: Leaving directory '/home/osboxes/nuttx/apps/platform'
make[1]: Leaving directory '/home/osboxes/nuttx/apps'
make[1]: Entering directory '/home/osboxes/nuttx/apps'
make[2]: Entering directory '/home/osboxes/nuttx/apps/canutils'
mkkconfig in /home/osboxes/nuttx/apps/canutils
make[2]: Leaving directory '/home/osboxes/nuttx/apps/canutils'
make[2]: Entering directory '/home/osboxes/nuttx/apps/examples'
mkkconfig in /home/osboxes/nuttx/apps/examples
make[2]: Leaving directory '/home/osboxes/nuttx/apps/examples'
make[2]: Entering directory '/home/osboxes/nuttx/apps/fsutils'
mkkconfig in /home/osboxes/nuttx/apps/fsutils
make[2]: Leaving directory '/home/osboxes/nuttx/apps/fsutils'
make[2]: Entering directory '/home/osboxes/nuttx/apps/gpsutils'
mkkconfig in /home/osboxes/nuttx/apps/gpsutils
make[2]: Leaving directory '/home/osboxes/nuttx/apps/gpsutils'
make[2]: Entering directory '/home/osboxes/nuttx/apps/graphics'
mkkconfig in /home/osboxes/nuttx/apps/graphics
make[2]: Leaving directory '/home/osboxes/nuttx/apps/graphics'
make[2]: Entering directory '/home/osboxes/nuttx/apps/industry'
mkkconfig in /home/osboxes/nuttx/apps/industry
make[2]: Leaving directory '/home/osboxes/nuttx/apps/industry'
make[2]: Entering directory '/home/osboxes/nuttx/apps/interpreters'
mkkconfig in /home/osboxes/nuttx/apps/interpreters
make[2]: Leaving directory '/home/osboxes/nuttx/apps/interpreters'
make[2]: Entering directory '/home/osboxes/nuttx/apps/netutils'
mkkconfig in /home/osboxes/nuttx/apps/netutils
make[2]: Leaving directory '/home/osboxes/nuttx/apps/netutils'
make[2]: Entering directory '/home/osboxes/nuttx/apps/system'
make[3]: Entering directory '/home/osboxes/nuttx/apps/system/libuv'
mkkconfig in /home/osboxes/nuttx/apps/system/libuv
make[3]: Leaving directory '/home/osboxes/nuttx/apps/system/libuv'
mkkconfig in /home/osboxes/nuttx/apps/system
make[2]: Leaving directory '/home/osboxes/nuttx/apps/system'
make[2]: Entering directory '/home/osboxes/nuttx/apps/testing'
mkkconfig in /home/osboxes/nuttx/apps/testing
make[2]: Leaving directory '/home/osboxes/nuttx/apps/testing'
make[2]: Entering directory '/home/osboxes/nuttx/apps/wireless'
make[3]: Entering directory '/home/osboxes/nuttx/apps/wireless/bluetooth'
mkkconfig in /home/osboxes/nuttx/apps/wireless/bluetooth
make[3]: Leaving directory '/home/osboxes/nuttx/apps/wireless/bluetooth'
make[3]: Entering directory '/home/osboxes/nuttx/apps/wireless/ieee802154'
mkkconfig in /home/osboxes/nuttx/apps/wireless/ieee802154
make[3]: Leaving directory '/home/osboxes/nuttx/apps/wireless/ieee802154'
mkkconfig in /home/osboxes/nuttx/apps/wireless
make[2]: Leaving directory '/home/osboxes/nuttx/apps/wireless'
mkkconfig in /home/osboxes/nuttx/apps
make[1]: Leaving directory '/home/osboxes/nuttx/apps'
#
# configuration written to .config
#
osboxes@osboxes:~/nuttx/nuttx$
osboxes@osboxes:~/nuttx/nuttx$ make menuconfig

Para adicionar o driver para o LED, navegue em Device Drivers->LED Support e selecione LED Driver e Generic Lower Half LED Driver (pressione y). Neste passo você está adicionando o driver para o LED.


Retorne ao menu inicial através de ‘Exit’. Basta usar as setas laterais e ‘Enter’.

Por fim, para adicionar o exemplo navegue em Application Configuration->Examples e selecione Led Driver Example.


Saia do menu através de “Exit” e salve a configuração.

Antes de mandar compilar, não esquecer de habilitar o ESP-IDF e também alterar o arquivo
~/nuttx/nuttx/boards/xtensa/esp32/esp32-devkitc/src$ nano esp32-devkitc.h

* LED
 *
 * This is an externally connected LED used for testing.
 */

#define GPIO_LED1     33
Que é o GPIO on está conectado o LED RGB para que acende o LED VERDE!


$ . $HOME/esp/esp-idf/export.sh
$ make clean
$ make
osboxes@osboxes:~/nuttx/nuttx$ make
make[1]: Entering directory '/home/osboxes/nuttx/nuttx/tools'
make[1]: Leaving directory '/home/osboxes/nuttx/nuttx/tools'
make[1]: Entering directory '/home/osboxes/nuttx/nuttx'
make[2]: Entering directory '/home/osboxes/nuttx/nuttx/boards'
make[2]: Leaving directory '/home/osboxes/nuttx/nuttx/boards'
make[2]: Entering directory '/home/osboxes/nuttx/apps'
make[3]: Entering directory '/home/osboxes/nuttx/apps/platform'
make[3]: Leaving directory '/home/osboxes/nuttx/apps/platform'
make[3]: Entering directory '/home/osboxes/nuttx/apps/builtin'
 
Antes de gravar o BIN, repita o processo **

Abra o terminal e você verá o novo APP, no caso "leds"



Veja o led Piscando!


Aqui está o APP

/**************************************************************************** * examples/leds/leds_main.c * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. Neither the name NuttX nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include <nuttx/config.h> #include <sys/ioctl.h> #include <stdbool.h> #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <sched.h> #include <errno.h> #include <nuttx/leds/userled.h> /**************************************************************************** * Private Data ****************************************************************************/ static bool g_led_daemon_started; /**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** * Name: led_daemon ****************************************************************************/ static int led_daemon(int argc, char *argv[]) { userled_set_t supported; userled_set_t ledset; bool incrementing; int ret; int fd; /* Indicate that we are running */ g_led_daemon_started = true; printf("led_daemon: Running\n"); /* Open the LED driver */ printf("led_daemon: Opening %s\n", CONFIG_EXAMPLES_LEDS_DEVPATH); fd = open(CONFIG_EXAMPLES_LEDS_DEVPATH, O_WRONLY); if (fd < 0) { int errcode = errno; printf("led_daemon: ERROR: Failed to open %s: %d\n", CONFIG_EXAMPLES_LEDS_DEVPATH, errcode); goto errout; } /* Get the set of LEDs supported */ ret = ioctl(fd, ULEDIOC_SUPPORTED, (unsigned long)((uintptr_t)&supported)); if (ret < 0) { int errcode = errno; printf("led_daemon: ERROR: ioctl(ULEDIOC_SUPPORTED) failed: %d\n", errcode); goto errout_with_fd; } /* Excluded any LEDs that not supported AND not in the set of LEDs the * user asked us to use. */ printf("led_daemon: Supported LEDs 0x%02x\n", (unsigned int)supported); supported &= CONFIG_EXAMPLES_LEDS_LEDSET; /* Now loop forever, changing the LED set */ ledset = 0; incrementing = true; for (; ; ) { userled_set_t newset; userled_set_t tmp; if (incrementing) { tmp = ledset; do { tmp++; newset = tmp & supported; } while (newset == ledset); /* REVISIT: There are flaws in this logic. It would not work * correctly if there were spaces in the supported mask. */ if (newset == 0) { incrementing = false; continue; } } else { /* REVISIT: There are flaws in this logic. It would not work * correctly if there were spaces in the supported mask. */ if (ledset == 0) { incrementing = true; continue; } tmp = ledset; do { tmp--; newset = tmp & supported; } while (newset == ledset); } ledset = newset; printf("led_daemon: LED set 0x%02x\n", (unsigned int)ledset); ret = ioctl(fd, ULEDIOC_SETALL, ledset); if (ret < 0) { int errcode = errno; printf("led_daemon: ERROR: ioctl(ULEDIOC_SUPPORTED) failed: %d\n", errcode); goto errout_with_fd; } usleep(500*1000L); } errout_with_fd: close(fd); errout: g_led_daemon_started = false; printf("led_daemon: Terminating\n"); return EXIT_FAILURE; } /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * leds_main ****************************************************************************/ int main(int argc, FAR char *argv[]) { int ret; printf("leds_main: Starting the led_daemon\n"); if (g_led_daemon_started) { printf("leds_main: led_daemon already running\n"); return EXIT_SUCCESS; } ret = task_create("led_daemon", CONFIG_EXAMPLES_LEDS_PRIORITY, CONFIG_EXAMPLES_LEDS_STACKSIZE, led_daemon, NULL); if (ret < 0) { int errcode = errno; printf("leds_main: ERROR: Failed to start led_daemon: %d\n", errcode); return EXIT_FAILURE; } printf("leds_main: led_daemon started\n"); return EXIT_SUCCESS; }

DÚVIDAS

suporte@smartcore.com.br

REFERÊNCIAS
 

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