Category: BrainDamage

Running external application on NuttX

Normally NuttX supports internal (Built-In) applications embedded on its firmware. When you run: “nsh> hello” or your application, NuttX look for the application inside the internal flash of the microcontroller and run it.

But NuttX also supports running external applications. These external applications are ELF files. The ELF format is the default executable format used on Linux and almost all Unix OS.

Normally the OS needs to create a Global Symbol Table (AKA: symtab) where the ELF look at to translate the used functions of the ELF binary to memory addresses where these functions exist in the OS.

The “drawback” of this symtab is because it will waste a lot of space inside the flash (firmware) of the OS.

Fortunately NuttX also supports an alternative solution where this symtab is not needed. The ELF binary is created with the fixed memory position of each function address position. The drawback of this solution is the ELF binary is not relocatable, in other words: if you compile a new firmware for your board the existent external ELF binary could to fail because these functions positions are located at a different position now.

You can find the instructions for both options here:

http://www.nuttx.org/doku.php?id=wiki:nshhowtos:elf-addon

I tested the “no-symtab” option loading an external “hello” from a USB Flash Drive:

NuttShell (NSH)
nsh> ls /dev
/dev:
 console
 null
 sda
 ttyS0
nsh> ?
help usage:  help [-v] []

  [           dirname     help        mh          set         unset       
  ?           dd          hexdump     mount       sh          usleep      
  basename    df          kill        mv          sleep       xd          
  break       echo        ls          mw          test        
  cat         exec        mb          ps          time        
  cd          exit        mkdir       pwd         true        
  cp          false       mkfatfs     rm          uname       
  cmp         free        mkrd        rmdir       umount      

Builtin Apps:
  hello
nsh> hello
Hello, World!!

nsh> mount -t vfat /dev/sda /bin
nsh> hello
Hello world from external binary!
nsh>

As you can see initially the internal “hello” program was executed, but after I mounted the USB Flash Drive to /bin the external “hello” takes precedence over the internal.

These are the options I need to get it working:

CONFIG_STM32_OTGFS=y
CONFIG_STM32_CCMEXCLUDE=y
CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_HPWORK=y
CONFIG_USBHOST=y
CONFIG_USBHOST_ISOC_DISABLE=y
CONFIG_USBHOST_MSC=y
CONFIG_FS_FAT=y
CONFIG_BINFMT_EXEPATH=y
CONFIG_PATH_INITIAL="/bin"
CONFIG_ELF=y
CONFIG_LIBC_ARCH_ELF=y
CONFIG_LIBC_EXECFUNCS=y
# CONFIG_EXECFUNCS_HAVE_SYMTAB is not set
CONFIG_EXAMPLES_HELLO=y
CONFIG_NSH_FILE_APPS=y
CONFIG_NSH_ARCHINIT=y
Advertisements

Using BOOST-CC2564MODA with bluez on Linux

I’m trying to get the CC2564MODA working with NuttX, then I decided to test it with Linux’s bluez first to guarantee it is working.

I used a CP2101 USB/Serial dongle, connected RXD to BUTX1, TXD to BURX1, CTS to BURT1, RTS to BUCT1.

Unfortunately the CC2564B will not work correctly if you don’t load a patch to fix its internal firmware. I download the file cc256xb_bt_sp_v1.6.zip from TI site extracted and copied it to:

$ sudo cp ~/CC2564/CC256XB_BT_SP/v1.6/initscripts-TIInit_6.7.16_ble_add-on.bts /lib/firmware/ti-connectivity/TIInit_6.7.16.bts

Next step is to use hciattach:

$ sudo hciattach -s 115200 /dev/ttyUSB0 texas 115200
Found a Texas Instruments' chip!
Firmware file : /lib/firmware/ti-connectivity/TIInit_6.7.16.bts
Loaded BTS script version 1
Device setup complete

Open a new linux terminal and run:

$  sudo btmon
Bluetooth monitor ver 5.37
= New Index: B0:B4:48:F4:A1:54 (BR/EDR,UART,hci1)               [hci1] 0.270465
= Open Index: B0:B4:48:F4:A1:54                                 [hci1] 0.270467
= Index Info: B0:B4:48:F4:A1:54 (Texas Instruments Inc.)        [hci1] 0.270467
= New Index: E0:06:E6:CF:FD:CE (BR/EDR,USB,hci0)                [hci0] 0.270468

Open another terminal and run:

$ sudo btmgmt --index 1

[hci1]# auto-power
Found controller with index 1

Note that I used “–index 1” instead “–index 0” because the BOOST-CC2564MODA was included as “hci1” (my laptop has Bluetooth internally).

Finally we can search for BLE devices:

[hci1]# find -l
Discovery started
hci1 type 6 discovering on
hci1 dev_found: BC:6A:29:AB:3F:46 type LE Public rssi -50 flags 0x0000 
AD flags 0x05 
eir_len 3
hci1 type 6 discovering off
[hci1]# 

How to install NuttX on Nordic nRF52832

Today I tested NuttX on Nordic nRF52832 and it worked fine!!!

I used this low cost nRF52832 module:

https://www.ebay.com/itm/nRF52832-Bluetooth-4-1-BLE-Module-M4-Transparent-Transmission-CORTEX-M4-512KB-/332270581440

First you need to clone, compile and install a recent OpenOCD.

I used this mirror from github because I was facing issue with main repository:

$ git clone https://github.com/ntfreak/openocd
$ cd openocd
$ ./configure --enable-aice --enable-amtjtagaccel --enable-armjtagew --enable-cmsis-dap --enable-dummy --enable-ftdi --enable-gw16012 --enable-jlink --enable-jtag_vpi --enable-opendous --enable-openjtag_ftdi --enable-osbdm --enable-legacy-ft2232_libftdi --enable-parport --disable-parport-ppdev --enable-parport-giveio --enable-presto_libftdi --enable-remote-bitbang --enable-rlink --enable-stlink --enable-ti-icdi --enable-ulink --enable-usb-blaster-2 --enable-usb_blaster_libftdi --enable-usbprog --enable-vsllink
$ make
$ sudo make install

Now we can clone, configure and compile NuttX on nRF52832:

$ git clone https://bitbucket.org/nuttx/nuttx
$ git clone https://bitbucket.org/nuttx/apps
$ cd nuttx
$ ./tools/configure.sh nrf52-pca10040/nsh
$ make menuconfig
$ make

$ ls -l nuttx.bin 
-rwxrwxr-x 1 alan alan 61016 Abr  3 20:07 nuttx.bin

$ arm-none-eabi-size nuttx
   text	   data	    bss	    dec	    hex	filename
  60793	    220	   1972	  62985	   f609	nuttx

Now we can flash nuttx.bin in the board.

To program this board I used a stlink-v2 clone. I connected the SWDIO (board pin 33), SWDCLK (board pin 32), GND (pin 9) and VCC (pin 10) to respective pins of ST-LINK V2 programmer. Note: I connected VCC to 3.3V.

$ sudo openocd -f interface/stlink-v2.cfg -f target/nrf52.cfg -c init -c "reset init" -c halt -c "nrf5 mass_erase" -c "program nuttx.bin verify" -c reset -c exit
Open On-Chip Debugger 0.10.0+dev-00376-g3d3b45a (2018-04-03-20:18)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
WARNING: interface/stlink-v2.cfg is deprecated, please switch to interface/stlink.cfg
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select '.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 1000 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : clock speed 950 kHz
Info : STLINK v2 JTAG v17 API v2 SWIM v4 VID 0x0483 PID 0x3748
Info : using stlink api v2
Info : Target voltage: 3.225739
Info : nrf52.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x000009f4 msp: 0x20000400
Info : nRF52832-QFAA(build code: B0) 512kB Flash
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
** Programming Started **
auto erase enabled
Warn : using fast async flash loader. This is currently supported
Warn : only with ST-Link and CMSIS-DAP. If you have issues, add
Warn : "set WORKAREASIZE 0" before sourcing nrf51.cfg/nrf52.cfg to disable it
target halted due to breakpoint, current mode: Thread 
xPSR: 0x61000000 pc: 0x2000001e msp: 0xfffffffc
wrote 61440 bytes from file nuttx.bin in 1.536207s (39.057 KiB/s)
** Programming Finished **
** Verify Started **
target halted due to breakpoint, current mode: Thread 
xPSR: 0x61000000 pc: 0x2000002e msp: 0xfffffffc
verified 61016 bytes in 0.165886s (359.198 KiB/s)
** Verified OK **
Warn : Flash driver of nrf52.flash does not support free_driver_priv()
Warn : Flash driver of nrf52.uicr does not support free_driver_priv()

You can see the NuttX starting in the serial console configured to 115200 8n1, just use a USB/Serial of 3.3V connecting P0.24 (board pin 36) to RXD, the P0.23 (pin 35) to TXD and the GND (pin 9) to USB/Serial’s GND.

A huddle of electronic modules

I decided to list all the modules on my pile of modules:

3 – Relay module
2 – Analog Microphone module with ampliflier
2 – ADXL345 Accelerometer module (GY-291)
2 – Zero cross detector module
3 – GP2Y0AH01K0F distance sensor
4 – LDR sensor module
1 – MPU9250 module
3 – 4×4 telephone keypad module
2 – PS2 joystick module
1 – VEML6070 UV sensor module
1 – W25Q32FVZPIG SPI NOR Flash module
1 – VS1053 Audio MP3 module
8 – nRF24 2.4GHz module
5 – MicroSD Card module
1 – WS2812 Breakout module
1 – OV7660 (CF7670C-V2) camera module
2 – HMC5883L 3-axis compass (GY-273)
2 – HMC5983 3-axis compass module (GY-282)
2 – Si1145 UV IR light sensor module (GY1145)
1 – BMP280 pressure module
3 – MAX485 RS485 module from LC Technology
1 – ML8511 Analog UV sensor module (GYML8511)
2 – ACS712 Current sensor module
2 – Hall sensor analog module with amplifier
1 – Tilt module (mercury bulb)
1 – Tilt module with 2 brass capsule/tube
2 – GY-86 10DOF MS5611 HMC5883L MPU6050 module (GY-86)
2 – LM75 temperature sensor module (CJMCU-75)
2 – APDS-9960 Gesture sensor module
1 – RDA5807M FM module (RRD-102)
1 – SX1509 keypad controller module
3 – Laser pointer module
3 – Reed-switch module with amplifier
2 – MQ2 butane sensor module (FC-22)
1 – Hall sensor module without amplifier (Keyes without number)
2 – MCP4725 DAC module
2 – ADCL335 Analog Accelerometer module (GY-61)
2 – Ra-01 LoRa module 433MHz
1 – TCS34725FN Color Light sensor module
1 – BH1750FVI light sensor module
1 – MAX30100 Pulse Oximeter and Heart-Rate Sensor module
2 – Buzzer module (RobotDyn)
1 – LSM6DS3 3-axis accelometer gyroscope
1 – MLX90614 Infrared Thermometer module (GY-906)
2 – BME-280 pressure module
1 – VL53L0X laser ranging sensor module (GYVL53L0X)
5 – TXB0108 level-shifter module (HW-0108)
1 – HTU21 humidity sensor module (GY-21)
2 – TEA5767 FM radio module (PL102BC-N)
1 – DHT11 humidity and temperature sensor module
2 – Thyristor AC switch 5V logic AC 220V/5A module
1 – DS18B20 1-wire temperature probe
1 – USB Audio IN/OUT module
1 – AT24C02B EEPROM module
5 – HX711 24-bit ADC Load Cell amplifier module
1 – BMP180 barometer sensor module (GY-68)
2 – ??? module with a small QFN chip with this code: 2222 C3H 9L8GS
5 – mini joysticks 5-way
3 – slide potentiometer
3 – photodetectors similar used on mouse
1 – voltage regulator module LM2596 DC-DC
1 – RTC module DS1302
1 – SIM800 modem module
3 – MAX6675 thermocoupler module
1 – SI4703 FM Radio Module
1 – CDM324 Radar Module
1 – ILI9486 LCD Module
3 – SN65HVD230 CAN Transceiver

I already created drivers for some of these sensors in the NuttX (i.e.: ADXL345, APDS-9960, BH1750FVI, BMP180, VEML6070, ZeroCross, etc). But there are many more to be added.

How to build NuttX on Windows 10

First let me to make things clear: I stopped using Windows operating system about 18 years ago, when in 2000 Chernobyl virus erased the BIOS Flash and the Hard Disk of my computer that was running Windows 98 at that time.

But since many people are asking me to show how to compile NuttX on Windows, I will show how you can do it using Windows 10 (sorry Windows 7, Windows Vista, Windows XP, Windows 2000, Windows Millennium, Windows 98, Windows 95, Windows 3.1, … and DOS users, but it only works on Windows 10).

You need to enable to “Developer Mode” of Windows: click on Window icon at bottom left corner of your screen and then click on “Windows Settings” (gear icon).

Settings:

In the “Windows Settings” click on “Update & Security”.

Update & Security:

Inside it click in “For Developers”.

For developers:

And enable the option “Developer Mode”.

Developer mode:

After that you need to enable the Windows Subsystem for Linux. Open the “Control Panel”.

Control Panel:

Enter inside “Programs”.

Programs:

Click on “Turn Windows features on or off”.

Turn Windows features on or off:

Then it will open the “Windows Features” window, scroll down until you find “Windows Subsystem for Linux”.

Enable the Windows Subsystem for Linux:

Then click to enable it:

At this moment the Windows will ask to restart, click in the Restart button.

When the system restarted you can run the “bash” command:

It will show the message explaining the a Linux distribution is not installed:

Open the browser and go to: https://aka.ms/wslstore

The the Microsoft Store will open automatically:

Click in the Ubuntu distribution, and the click on Get button:

When it finishes the download click on Launch button:

It will run the installation script, when it finishes you can close it and run the Ubuntu command:

Then the Linux terminal will open:

Now you can follow these steps to compile NuttX:

$ sudo apt-get update

$ sudo apt-get install automake bison build-essential flex gcc-arm-none-eabi gperf git libncurses5-dev libtool libusb-dev libusb-1.0.0-dev pkg-config

Create the nuttx workspace:

mkdir ~/nuttxspace

cd ~/nuttxspace

The Windows Subsystem for Linux doesn’t support USB devices (except USB Pendrive), then we don’t need to install OpenOCD. We will use the JLink too on Windows itself.

Clone the NuttX repositories:

$ cd ~/nuttxspace

$ git clone https://bitbucket.org/nuttx/nuttx

$ git clone https://bitbucket.org/nuttx/apps

$ git clone https://bitbucket.org/nuttx/tools

Configure, compile and install the Kconfig-Frontends (needed by NuttX’s menuconfig)

$ cd ~/nuttxspace

$ cd tools/kconfig-frontends/

$ ./configure

$ make

$ sudo make install

$ sudo ldconfig

Now we can compile NuttX for XMC4-Relax board!

Run the configure script:

$ cd ~/nuttxspace

$ cd nuttx

$ ./tools/configure.sh xmc4500-relax/nsh

Run menuconfig and change the build to Linux and UART3 as serial console:

$ make menuconfig

Build Setup  --->
    Build Host Platform (Linux)

System Type  --->
    XMC4xxx Peripheral Support  --->
        [ ] USIC0
        [*] USIC1  (press SPACE to select)
        [ ] USIC2

    XMC4xxx USIC Configuration  --->
        USIC1 Channel 0 Configuration (Not used)  --->
        USIC1 Channel 1 Configuration (UART3)  --->

Device Drivers  --->
    [*] Serial Driver Support  --->
        Serial console (UART3)  --->

Time to compile it:

$ make

If everything compiled correctly you get a nuttx.bin:

$ ls -l nuttx.bin
-rwxrwxr-x 1 alan alan 79804 Jan  8 12:25 nuttx.bin

Just copy this nuttx.bin binary to Windows side:

$ cp nuttx.bin /mnt/c/ProgramData/

You will need to configure Windows Explorer to show Hidden files, this way you could see the nuttx.bin at C:\ProgramData

Running NuttX on Infineon XMC4500-Relax

This is a step-by-step tutorial explaining how to compile and install NuttX on Infineon XMC4500-Relax board.

These steps where tested on Ubuntu 16.04 LTS (Long Term Support).

Open the Linux terminal and install the dependence packages using this command:

$ sudo apt-get install automake bison build-essential flex gcc-arm-none-eabi gperf git libncurses5-dev libtool libusb-dev libusb-1.0.0-dev pkg-config

Create the nuttx workspace:

mkdir ~/nuttxspace

cd ~/nuttxspace

Clone and compile the OpenOCD (it is used to flash the firmware in the board).

$ git clone http://repo.or.cz/r/openocd.git

$ cd ~/nuttxspace/openocd

$ ./bootstrap

$ ./configure --enable-internal-jimtcl --enable-maintainer-mode --disable-werror --disable-shared --enable-stlink --enable-jlink --enable-rlink --enable-vslink --enable-ti-icdi --enable-remote-bitbang

$ make

$ sudo make install

Copy the OpenOCD udev rules and update it:

$ cd contrib

$ sudo cp 60-openocd.rules /etc/udev/rules.d/

$ sudo udevadm trigger

Clone the NuttX repositories:

$ cd ~/nuttxspace

$ git clone https://bitbucket.org/nuttx/nuttx

$ git clone https://bitbucket.org/nuttx/apps

$ git clone https://bitbucket.org/nuttx/tools

Configure, compile and install the Kconfig-Frontends (needed by NuttX’s menuconfig)

$ cd ~/nuttxspace

$ cd tools/kconfig-frontends/

$ ./configure

$ make

$ sudo make install

$ sudo ldconfig

Now we can compile NuttX for XMC4-Relax board!

Run the configure script:

$ cd ~/nuttxspace

$ cd nuttx

$ ./tools/configure.sh xmc4500-relax/nsh

Run menuconfig and change the build to Linux and UART3 as serial console:

$ make menuconfig

Build Setup  --->
    Build Host Platform (Linux)

System Type  --->
    XMC4xxx Peripheral Support  --->
        [ ] USIC0
        [*] USIC1  (press SPACE to select)
        [ ] USIC2

    XMC4xxx USIC Configuration  --->
        USIC1 Channel 0 Configuration (Not used)  --->
        USIC1 Channel 1 Configuration (UART3)  --->

Device Drivers  --->
    [*] Serial Driver Support  --->
        Serial console (UART3)  --->

Time to compile it:

$ make

If everything compiled correctly you get a nuttx.bin:

$ ls -l nuttx.bin
-rwxrwxr-x 1 alan alan 79804 Jan  8 12:25 nuttx.bin

Plug the USB cable on you computer and on XMC4500-Relax board and use OpenOCD to flash it:

$ sudo openocd -f board/xmc4500-relax.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x0c000000"

You should see these messages:

$ sudo openocd -f board/xmc4500-relax.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x0c000000"
Open On-Chip Debugger 0.10.0+dev-00172-g7719e96 (2017-11-12-09:13)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
adapter speed: 4000 kHz
cortex_m reset_config sysresetreq
adapter speed: 1000 kHz
Info : No device selected, using first device.
Info : J-Link Lite-XMC4000 Rev.1 compiled Apr  2 2015 18:25:20
Info : Hardware version: 1.00
Info : VTarget = 3.300 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x2ba01477
Info : xmc4500.cpu: hardware has 6 breakpoints, 4 watchpoints
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000200 msp: 0x20001e84
auto erase enabled
Info : Clearing flash status
Info : Clearing flash status
wrote 81920 bytes from file nuttx.bin in 19.998228s (4.000 KiB/s)

Configure your Linux machine to let your user to have access to serial port:

$ sudo usermod -a -G dialout alan

You just replace ‘alan’ with your username.

You need a USB/Serial adapter that works to 3.3V, like FDTI dongle or Silabs CP2102.

Connect the USB/Serial RXD to XMC4500-Relax board P0.1 (Header pin X1 pin 34), connect TXD to P0.0 (Header pin X1 pin 36) and connect the GND to board GND (Header pin X1 pin 1, 2, 3 or 4).

Configure minicom to use your USB/Serial adapter (i.e. at /dev/ttyUSB0) to 115200 8n1:

$ sudo minicom -s

Serial port setup
    A -    Serial Device      : /dev/ttyUSB0
    E -    Bps/Par/Bits       : 115200 8N1
    F - Hardware Flow Control : No
    G - Software Flow Control : No

Save setup as dfl

Exit

Press the XMC4500 Reset button and you should see:

NuttShell (NSH)                                                                 
nsh>

Type ‘help’ or ‘?’ to the the listing of enabled commands:

nsh> help
help usage:  help [-v] []

  [           dirname     help        mh          set         unset       
  ?           dd          hexdump     mount       sh          usleep      
  basename    df          kill        mv          sleep       xd          
  break       echo        ls          mw          test        
  cat         exec        mb          ps          time        
  cd          exit        mkdir       pwd         true        
  cp          false       mkfatfs     rm          uname       
  cmp         free        mkrd        rmdir       umount      

Builtin Apps:
  i2c
  ramtest
nsh>