Category: NuttX

NuttX 10 Years!

Tomorrow 07 Feb 2017 NuttX RTOS will complete 10 years as an Open Source project. The projects was published in the SourceForge on 07 Feb 2007.

From 2007 to 20017 NuttX evolved a lot. Maybe you don’t know, but NuttX is used by many companies. If you have a Moto Z Phone and got a Snap cover that Snap run NuttX!

Other example is Sony (that company that inspired Steve Jobs to create great products) is also using NuttX and even did a publish presentation about the benefits of using NuttX: http://events.linuxfoundation.org/sites/events/files/slides/DevelopingAudioProductsWithCortexM3NuttXC%2B%2B11_LFELC_OpenIoT_ishikawa_20161209_0.pdf

I discovered about NuttX in 2010. My friend Marcelo Barros pointed about an article in the Linux Jornal. Since then I have used NuttX in many projects as you can find on my old posts.

Also I created a YouTube channel dedicated to NuttX, called NuttX Channel:

NuttX is evolving fast and will be a Linux companion on “Embedded Arena”.

There is no other RTOS good like NuttX, you can spend your time searching. There are more than 200 available: https://en.wikipedia.org/wiki/Comparison_of_real-time_operating_systems

Thank Greg Nutt for this incredible RTOS called NuttX.

More here: http://www.nuttx.org

Flashing firmware with OpenOCD without using telnet

Normally I use OpenOCD to flash firmware on my microcontrollers, but always use telnet to connect to openocd server in the port 4444.

Today I realized it is not necessary to use telnet to flash the firmware, I can do it from command line:

$ sudo openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x08000000"

I used this command to flash the nuttx.bin firmware on STM32F103 Minimum board. This is the “openocd_stm32f1.cfg” config file content:

# STM32F103Minimum Board

# Using stlink as SWD programmer
source [find interface/stlink-v2.cfg]

# SWD as transport
transport select hla_swd

# Use STM32F103C8 target
set WORKAREASIZE 0x4000
source [find target/stm32f103c8t6.cfg]

Testing U-Blox Sara-G350 on NuttX

This is the result of my Sara G350 debug on NuttX:

NuttShell (NSH)
nsh> pppd
tun fd:3
tty fd:4
ipcp init

AHDLC_TX - transmit frame, protocol 0xc021, length 4  offline 0

0x05 0x01 0x00 0x04 


AHDLC_TX - transmit frame, protocol 0xc021, length 4  offline 1

0x05 0x02 0x00 0x04 

chat: char = ~ (0x7E)
chat: char = � (0xFF)
chat: char = } (0x7D)
chat: char = # (0x23)
chat: char = � (0xC2)
chat: char = # (0x23)
chat: char = (0x7F)
chat: char = ' (0x27)
chat: char = (0x7F)
chat: char = # (0x23)
chat: char = (0x7F)
chat: char = " (0x22)
chat: char = (0x7F)
chat: char = & (0x26)
chat: char = ? (0x3F)
chat: char = � (0xC7)
chat: char = ~ (0x7E)
chat: char = ~ (0x7E)
chat: char = � (0xFF)
chat: char = } (0x7D)
chat: char = # (0x23)
chat: char = � (0xC1)
chat: char = ! (0x21)
chat: char = } (0x7D)
chat: char = % (0x25)
chat: char = } (0x7D)
chat: char = " (0x22)
chat: char = } (0x7D)
chat: char =   (0x20)
chat: char = } (0x7D)
chat: char = % (0x25)
chat: char = Y (0x59)
chat: char = ) (0x29)
chat: char = ~ (0x7E)
chat: char = + (0x2B)
chat: char = ; (0x3B)
chat: char = + (0x2B)
chat: char = A (0x41)
chat: char = T (0x54)
chat: char = E (0x45)
chat: char = 1 (0x31)
 (0x0D)har = 
 (0x0D)har = 
chat: char = 
 (0x0A)
chat: char = O (0x4F)
chat: char = K (0x4B)
 (0x0D)har = 
chat: char = 
 (0x0A)
chat: send 'ATZ`
chat_check_response read: 
chat: char = A (0x41)
chat_check_response read: A
chat: char = T (0x54)
chat_check_response read: T
chat: char = Z (0x5A)
chat: wait for 'OK`
chat_check_response read: 
 (0x0D)har = 
chat_check_response read: 
 (0x0D)har = 
chat_check_response read: 
chat: char = 
 (0x0A)
chat_check_response read: 

chat: char = O (0x4F)
chat_check_response read: O
chat: char = K (0x4B)
chat: got it!
 (0x0D)har = 
chat: char = 
 (0x0A)
chat: send 'AT`
chat_check_response read: 
chat: char = A (0x41)
chat_check_response read: A
chat: char = T (0x54)
chat: wait for 'OK`
chat_check_response read: 
 (0x0D)har = 
chat_check_response read: 
 (0x0D)har = 
chat_check_response read: 
chat: char = 
 (0x0A)
chat_check_response read: 

chat: char = O (0x4F)
chat_check_response read: O
chat: char = K (0x4B)
chat: got it!
 (0x0D)har = 
chat: char = 
 (0x0A)
chat: send 'AT+CGDCONT = 1,"IP","internet"`
chat_check_response read: 
chat: char = A (0x41)
chat_check_response read: A
chat: char = T (0x54)
chat_check_response read: T
chat: char = + (0x2B)
chat_check_response read: +
chat: char = C (0x43)
chat_check_response read: C
chat: char = G (0x47)
chat_check_response read: G
chat: char = D (0x44)
chat_check_response read: D
chat: char = C (0x43)
chat_check_response read: C
chat: char = O (0x4F)
chat_check_response read: O
chat: char = N (0x4E)
chat_check_response read: N
chat: char = T (0x54)
chat_check_response read: T
chat: char =   (0x20)
chat_check_response read:  
chat: char = = (0x3D)
chat_check_response read: =
chat: char =   (0x20)
chat_check_response read:  
chat: char = 1 (0x31)
chat_check_response read: 1
chat: char = , (0x2C)
chat_check_response read: ,
chat: char = " (0x22)
chat_check_response read: "
chat: char = I (0x49)
chat_check_response read: I
chat: char = P (0x50)
chat_check_response read: P
chat: char = " (0x22)
chat_check_response read: "
chat: char = , (0x2C)
chat_check_response read: ,
chat: char = " (0x22)
chat_check_response read: "
chat: char = i (0x69)
chat_check_response read: i
chat: char = n (0x6E)
chat_check_response read: n
chat: char = t (0x74)
chat_check_response read: t
chat: char = e (0x65)
chat_check_response read: e
chat: char = r (0x72)
chat_check_response read: r
chat: char = n (0x6E)
chat_check_response read: n
chat: char = e (0x65)
chat_check_response read: e
chat: char = t (0x74)
chat_check_response read: t
chat: char = " (0x22)
chat: wait for 'OK`
chat_check_response read: 
 (0x0D)har = 
chat_check_response read: 
 (0x0D)har = 
chat_check_response read: 
chat: char = 
 (0x0A)
chat_check_response read: 

chat: char = O (0x4F)
chat_check_response read: O
chat: char = K (0x4B)
chat: got it!
 (0x0D)har = 
chat: char = 
 (0x0A)
chat: send 'ATD*99***1#`
chat_check_response read: 
chat: char = A (0x41)
chat_check_response read: A
chat: char = T (0x54)
chat_check_response read: T
chat: char = D (0x44)
chat_check_response read: D
chat: char = * (0x2A)
chat_check_response read: *
chat: char = 9 (0x39)
chat_check_response read: 9
chat: char = 9 (0x39)
chat_check_response read: 9
chat: char = * (0x2A)
chat_check_response read: *
chat: char = * (0x2A)
chat_check_response read: *
chat: char = * (0x2A)
chat_check_response read: *
chat: char = 1 (0x31)
chat_check_response read: 1
chat: char = # (0x23)
chat: wait for 'CONNECT`
chat_check_response read: 
 (0x0D)har = 
chat_check_response read: 
 (0x0D)har = 
chat_check_response read: 
chat: char = 
 (0x0A)
chat_check_response read: 

chat: char = C (0x43)
chat_check_response read: C
chat: char = O (0x4F)
chat_check_response read: O
chat: char = N (0x4E)
chat_check_response read: N
chat: char = N (0x4E)
chat_check_response read: N
chat: char = E (0x45)
chat_check_response read: E
chat: char = C (0x43)
chat_check_response read: C
chat: char = T (0x54)
chat: got it!
ipcp init
ipcp init

Sending LCP request packet -  len 10

AHDLC_TX - transmit frame, protocol 0xc021, length 10  offline 0

0x01 0x00 0x00 0x0a 0x02 0x06 0xff 0xff 0xff 0xff 


Receiving packet with good crc value, len 24

0x01 0x01 0x00 0x14 0x02 0x06 0x00 0x00 0x00 0x00 0x05 0x06 0xed 0xb6 0x5b 0x05 
0x07 0x02 0x08 0x02 

LCP Packet - ipcp init
received [LCP Config Request id 1
   
Send ACK!
Writing ACK frame 

AHDLC_TX - transmit frame, protocol 0xc021, length 20  offline 1

0x02 0x01 0x00 0x14 0x02 0x06 0x00 0x00 0x00 0x00 0x05 0x06 0xed 0xb6 0x5b 0x05 0x07 0x02 0x08 0x02 

- end ACK Write frame


Receiving packet with good crc value, len 14

0x02 0x00 0x00 0x0a 0x02 0x06 0xff 0xff 0xff 0xff 

LCP Packet - LCP-ACK - >>>>>>>> good ACK id up! 0


**Sending IPCP Request packet

AHDLC_TX - transmit frame, protocol 0x8021, length 10  offline 0

0x01 0x00 0x00 0x0a 0x03 0x06 0x00 0x00 0x00 0x00 


Receiving packet with good crc value, len 14

0x01 0x01 0x00 0x0a 0x03 0x06 0xbf 0x78 0xee 0x5e 

IPCP Packet - IPCP len 10
check lcplist
IPCP options are good
Peer IP 
Send IPCP ACK!
SET- stuff -- are we up? c=10 dif=2 
Writing ACK frame 

AHDLC_TX - transmit frame, protocol 0x8021, length 10  offline 1

0x02 0x01 0x00 0x0a 0x03 0x06 0xbf 0x78 0xee 0x5e 

- End ACK Write frame


Receiving packet with good crc value, len 14

0x03 0x00 0x00 0x0a 0x03 0x06 0xbf 0x78 0xee 0x5e 

IPCP Packet - IPCP len 10
CONF NAK



**Sending IPCP Request packet

AHDLC_TX - transmit frame, protocol 0x8021, length 10  offline 0

0x01 0x01 0x00 0x0a 0x03 0x06 0xbf 0x78 0xee 0x5e 


Receiving packet with good crc value, len 14

0x02 0x01 0x00 0x0a 0x03 0x06 0xbf 0x78 0xee 0x5e 

IPCP Packet - IPCP len 10
CONF ACK
were up! 



Receiving packet with good crc value, len 44

0x45 0x00 0x00 0x28 0x7b 0xfb 0x40 0x00 0x40 0x06 0xfc 0xf0 0xad 0xfc 0x66 0x10 
0xbf 0x78 0xee 0x5e 0x01 0xbb 0xd6 0x15 0x39 0x78 0xcc 0xf2 0x00 0x00 0x00 0x00 0x50 0x04 0x00 0x00 0x0f 0xc1 0x00 0x00 

IPV4 Packet---

 len 8

Writing ECHO-REQUEST frame 

AHDLC_TX - transmit frame, protocol 0xc021, length 8  offline 0

0x09 0x01 0x00 0x08 0x00 0x00 0x00 0x00 

- end ECHO-REQUEST Write frame

Receiving packet with good crc value, len 12

0x0a 0x01 0x00 0x08 0xed 0xb6 0x5b 0x05 

LCP Packet - LCP-ECHO REPLY


Receiving packet with good crc value, len 44

0x45 0x00 0x00 0x28 0x0a 0x36 0x40 0x00 0x40 0x06 0xfd 0x24 0x41 0x37 0x44 0x67 
0xbf 0x78 0xee 0x5e 0x01 0xbb 0xa7 0x8c 0x87 0x92 0x83 0x53 0x00 0x00 0x00 0x00 0x50 0x04 0x00 0x00 0xc8 0x3d 0x00 0x00 

IPV4 Packet---


Receiving packet with good crc value, len 44

0x45 0x00 0x00 0x28 0x92 0xf2 0x40 0x00 0x40 0x06 0xe5 0xf9 0xad 0xfc 0x66 0x10 
0xbf 0x78 0xee 0x5e 0x01 0xbb 0xcf 0xf6 0x06 0x37 0xf1 0xec 0x00 0x00 0x00 0x00 0x50 0x04 0x00 0x00 0x24 0x27 0x00 0x00 

IPV4 Packet---

 len 8

Writing ECHO-REQUEST frame 

AHDLC_TX - transmit frame, protocol 0xc021, length 8  offline 0

0x09 0x02 0x00 0x08 0x00 0x00 0x00 0x00 

- end ECHO-REQUEST Write frame

Receiving packet with good crc value, len 12

0x0a 0x02 0x00 0x08 0xed 0xb6 0x5b 0x05 

LCP Packet - LCP-ECHO REPLY

This is the small “workaround” I did to get the modem working:

diff --git a/netutils/pppd/chat.c b/netutils/pppd/chat.c
index 35ab4c2..637686c 100644
--- a/netutils/pppd/chat.c
+++ b/netutils/pppd/chat.c
@@ -110,7 +110,12 @@ static int chat_check_response(int fd, const char* response, int timeout)
 
   while (*response)
     {
+      /* Just a workaround to get data from modem */
+      printf("chat_check_response read: %c\n", c);
+
       ret = chat_read_byte(fd, &c, timeout);
+      //printf("chat_check_response read: %c\n", c);
+
       if (ret < 0)
         {
           return ret;
@@ -153,6 +158,10 @@ int ppp_chat(int fd, struct chat_script_s *script, int echo)
 
   while (request)
     {
+      /* Wait data arrived before flushing */
+
+      usleep(100000);
+
       chat_flush(fd);
 
       printf("chat: send '%s`\n", request);

Using JLinkExe to flash a new firmware into STM32F407

These are the commands I use to flash a nuttx.bin firmware in the STM32F407 microcontroller:

$ JLinkExe -if SWD
SEGGER J-Link Commander V4.98e ('?' for help)
Compiled May  5 2015 11:49:39
DLL version V4.98e, compiled May  5 2015 11:49:35
Firmware: J-Link ARM V8 compiled Nov 28 2014 13:44:46
Hardware: V8.00
S/N: 268006167 
OEM: SEGGER-EDU 
Feature(s): FlashBP, GDB 
VTarget = 0.200V
J-Link>exit

$ sudo JLinkExe 
SEGGER J-Link Commander V4.98e ('?' for help)
Compiled May  5 2015 11:49:39
DLL version V4.98e, compiled May  5 2015 11:49:35
Firmware: J-Link ARM V8 compiled Nov 28 2014 13:44:46
Hardware: V8.00
S/N: 268006167 
OEM: SEGGER-EDU 
Feature(s): FlashBP, GDB 
VTarget = 3.300V
Info: TotalIRLen = 9, IRPrint = 0x0011
Info: Found Cortex-M4 r0p1, Little endian.
Info: FPUnit: 6 code (BP) slots and 2 literal slots
Info: CoreSight components:
Info: ROMTbl 0 @ E00FF000
Info: ROMTbl 0 [0]: FFF0F000, CID: B105E00D, PID: 000BB00C SCS
Info: ROMTbl 0 [1]: FFF02000, CID: B105E00D, PID: 003BB002 DWT
Info: ROMTbl 0 [2]: FFF03000, CID: B105E00D, PID: 002BB003 FPB
Info: ROMTbl 0 [3]: FFF01000, CID: B105E00D, PID: 003BB001 ITM
Info: ROMTbl 0 [4]: FFF41000, CID: B105900D, PID: 000BB9A1 TPIU
Info: ROMTbl 0 [5]: FFF42000, CID: B105900D, PID: 000BB925 ETM
Found 2 JTAG devices, Total IRLen = 9:
 #0 Id: 0x4BA00477, IRLen: 04, IRPrint: 0x1, CoreSight JTAG-DP (ARM)
 #1 Id: 0x06413041, IRLen: 05, IRPrint: 0x1, STM32 Boundary Scan
Cortex-M4 identified.
Target interface speed: 100 kHz

J-Link> device stm32f407ve
Info: Device "STM32F407VE" selected.
Reconnecting to target...
Info: TotalIRLen = 9, IRPrint = 0x0011
Info: TotalIRLen = 9, IRPrint = 0x0011
Info: Found Cortex-M4 r0p1, Little endian.
Info: FPUnit: 6 code (BP) slots and 2 literal slots
Info: CoreSight components:
Info: ROMTbl 0 @ E00FF000
Info: ROMTbl 0 [0]: FFF0F000, CID: B105E00D, PID: 000BB00C SCS
Info: ROMTbl 0 [1]: FFF02000, CID: B105E00D, PID: 003BB002 DWT
Info: ROMTbl 0 [2]: FFF03000, CID: B105E00D, PID: 002BB003 FPB
Info: ROMTbl 0 [3]: FFF01000, CID: B105E00D, PID: 003BB001 ITM
Info: ROMTbl 0 [4]: FFF41000, CID: B105900D, PID: 000BB9A1 TPIU
Info: ROMTbl 0 [5]: FFF42000, CID: B105900D, PID: 000BB925 ETM

J-Link> loadbin ./nuttx.bin 0
Halting CPU for downloading file.
Downloading file [./nuttx.bin]...Info: J-Link: Flash download: Flash programming performed for 1 range (65536 bytes)
Info: J-Link: Flash download: Total time needed: 9.917s (Prepare: 0.678s, Compare: 0.016s, Erase: 1.447s, Program: 7.687s, Verify: 0.006s, Restore: 0.081s)
O.K.
J-Link>

NuttX low power modes

The NuttX power management has four levels or modes (from include/nuttx/power/pm.h):

NORMAL
The normal, full power operating mode.

IDLE
This is still basically normal operational mode, the system is,
however, IDLE and some simple steps to reduce power consumption
provided that they do not interfere with normal Operation.
Simply dimming a backlight might be an example something that
would be done when the system is idle.

STANDBY
Standby is a lower power consumption mode that may involve more
extensive power management steps such has disabling clocking or
setting the processor into reduced power consumption modes. In
this state, the system should still be able to resume normal
activity almost immediately.

SLEEP
The lowest power consumption mode. The most drastic power
reduction measures possible should be taken in this state. It
may require some time to get back to normal operation from
SLEEP (some MCUs may even require going through reset).

Sigrok and a “cheap” Saleae clone can save your life (I meant your time)

An affordable, inexpensive and “cheap” Saleae clone could save your day (really).

You could find it for less than U$ 10:
http://www.electrodragon.com/product/saleae-usb-logic-analyzer-24m-8-channel/

I was implementing a NuttX driver for BMP180 over I2C, but was failing to get it working and it was difficult to discover what was going on.

I decided to test my cheap Saleae clone for the first time. The Sigrok tool installation from source code is explained here:

http://marcusjenkins.com/linux/saleae-logic-analyser-clone-with-ubuntu/

Then compared my driver command:

bad_i2c_command

against Adrafruit BMP085/BMP180 commands:

good_i2c

Imediately I noticed I forgot to write the register address that I need to read before issuing the read command.

Just an I2C_WRITE before a I2C_READ fixed the issue!

Related: How to use sigrok to measure real-time signal latency http://blog.savoirfairelinux.com/en/2014/logic-analyzer-visualize-latency-with-sigrok-and-matplotlib/

Update: You need to copy the firmware to Sigrok work:

cp fx2lafw-saleae-logic.fw /usr/local/share/sigrok-firmware/fx2lafw-saleae-logic.fw

I got the firmware from sigrok-firmware-fx2lafw-bin-0.1.3.tar.gz

Cloning NuttX repositories

The NuttX RTOS is moving from SourceForge to BitBucket, during this move Greg Nutt created some separated repositories for NuttX kernel, applications and other submodules.

You can see the steps to clone NuttX repositories in the README page:
https://bitbucket.org/patacongo/nuttx/

Basically all you need to do is this:

$ mkdir nuttx
$ cd nuttx
$ git clone https://bitbucket.org/patacongo/nuttx.git nuttx
$ git clone https://bitbucket.org/nuttx/apps.git apps
$ cd nuttx
$ git submodule init
$ git submodule update

Now you can compile your “board” and your “config”:

$ cd tools
$ ./configure.sh "<board/config>"

Replace "<board/config>", example:
  $ ./configure.sh stm32f4discovery/usbnsh

$ cd ..
$ make oldconfig
$ make menuconfig
$ make

To keep your local repository updated execute:

$ git submodule foreach git pull

That’s all!!!