VoCore2: remote debug with GDB

I love command line recently, Eclipse might be easy to use(I do not like Java complex depends), Qt creator looks nice(this is my favorite IDE), but command line, the GDB, is their core.

First, let’s compile gdb…
This article is focus on cross-compile. (I do not think you can compile gdb on VoCore2 magically πŸ™‚

Once you compile openwrt or LEDE on your host linux computer, it already have gdb(mipsel-openwrt-linux-uclibc-gdb), but it has a bug, when you run it later it will report “Remote ‘g’ packet reply is too long”. This is easy to fix, we need to modify gdb Makefile, in openwrt/toolchain/gdb/Makefile, section “Host/Configure”, add “–with-expat” to CFLAGS. Better to delete old compiled gdb file in build_dir.

You might also need to install expat lib, call “apt-get install libexpat-dev”

Then compile…

Now let’s make a simple app to debug
I’d like to use “mem”, this small app is used to read and write to memory directly. I use it to develop driver and do quick hack to the kernel.
Source code is here: Link to Source

Uncompress it and get mem.c

Next step, compile it with debug information
One command line will do this, do not forget -g, it is used to generate debug links.

mipsel-openwrt-linux-uclibc-gcc -g mem.c -o mem

Make gdbserver
In openwrt “make menuconfig”, Development section, select gdbserver.
Compile and install gdbserver to your VoCore.
Also you can copy mem to your VoCore.

We can happy debug
On VoCore2, run command

gdbserver ./mem

On your host, run command

mipsel-openwrt-linux-uclibc-gdb ./mem
(gdb) set sysroot ~/openwrt/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-
(gdb) target remote

Now we can use gdb command:

r: run the app.
l: show source code list.
b: add break point, parameter is the line number.
ni: step over one line.
si: step in one line.
p: show the parameter value.
d: delete break point.
i b: show current break point.
c: continue and run to next break point.

VoCore2: Login to Terminal from Browser

1. Download the package Makefile from https://github.com/paradislover/shellinabox, current version it is 2.19.

2. Put it in openwrt source/package/utils

3. Call “make menuconfig”, select shellinabox in Network submenu.

4. Compile openwrt, and upgrade VoCore2 firmware.

5. Connect to VoCore2 by wire or wifi, now we can login to it from browser

Good luck!

VoCore2: New Dock with microUSB Ethernet!

I made another dock for VoCore2 Ultimate, added on board USB to Ethernet to replace old on board USB to TTL, this alter will make VoCore2 more flexble.

Currently the microUSB port is not only for power, but also it is another ethernet port(using port 1).

Once we connect it to computer, we can debug VoCore2 by USB LAN10/100, much faster and more stable.

PS: USB2TTL is removed from dock but still able to use an external device connect to UART0 for the console debug.

Now we can have more advanced usage:

ifconfig will find this device once it is connect to your Linux/MacOS computer.(Windows should be same)

	ether 00:e0:3c:36:e2:xx
	inet6 fe80::10ad:1794:b44f:59xx%en7 prefixlen 64 secured scopeid 0xf 
	inet6 fdac:96e9:9938::1874:61ba:9aca:6axx prefixlen 64 autoconf secured 
	inet6 fdac:96e9:9938::f85f:93f7:4c10:82xx prefixlen 64 autoconf temporary 
	inet netmask 0xffffff00 broadcast
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect (100baseTX)
	status: active

It allocedΒ for my computer.
This dock is specially for portable router, VPN connection.

Its shape is exactly same as VoCore2 Ultimate. πŸ™‚
Here is the raw dock, based on RTL8152

VoCore2 Tips

1. Switch port0 between “wan” and “lan”

change in VoCore2, /etc/config/network, first vlan is lan ports, second vlan is wan port, put 0 into second one, port0 will become lan port.

config switch_vlan
    option ports '0 2 3 4 6t'

config switch_vlan
    option ports '1 6t'

2. Restart wifi in console.


3. Clean memory of VoCore2 for long time usage.

sync && echo 3 > /proc/sys/vm/drop_caches

4. Play radio with VoCore2 Ultimate

(sleep 5;wget -O - http://icecast.cogecomedia.com:8000/chmp.mp3 | madplay -)&

(Canada Radio πŸ™‚

5. Add password for UART console.

modify /etc/inittab

::askconsole:/bin/ash --login

note: make sure busybox enable login command when compile busybox.

6. Windows7 or lower system can not install driver for USB2TTL
check this link: Connecting to the serial console on Windows 7


Special Thanks

Patrick Coutu (contribute 3, 4)
Noble Pepper (contribute 6)

Write Bin File by Bash & Awk

Sometimes I find I am locked out VoCore2 wifi, because some executable files missed or messed up the factory setting. The only exists connection is the uart console.

PS: if you messed up factory setting, the wireless driver will not work anymore, because the driver read factory setting for some important data such as mac address, timer offset etc…

I might have three choices:

1. connect a cable to ethernet port — but I do not have…
2. on vocore.io/v2, fix brick part, use another VoCore2 SPI reflash the flash — but I only have the broken one…
3. use iwpriv, manually set the driver — around 30+ settings, I am sure I do not want to do that…

so I am looking for a way using bash and awk to write a bin file, even it is slow, but no problem, I accept, at least it is fast than the upper ways.:)

We will need three commands, bash/awk/dd

Key to make this happen:
awk can do most of the work, but it can not write zero to a file, we will need use dd copy a zero from /dev/zero.



create_byte_map() {
dd if=/dev/zero of=/tmp/map bs=1 count=1 2> /dev/null
echo | awk '{ for(i = 0; i < 256; i++) { printf("%c", i); }}' >> /tmp/map

attach_byte() {
name=$1; byte=$2;
if [ -f $name ]; then size=`ls -l ${name} | awk '{print $5}'`; else size=0; fi
dd if=/tmp/map of=${name} bs=1 count=1 seek=${size} skip=${byte} 2> /dev/null

attach_bytes() {
name=$1; string=$2;
echo $string | awk -F " " '{for (i = 1; i <= NF; i++) print $i}' | while read byte
do attach_byte $name $byte; done


# example:
attach_bytes /tmp/myfile "`echo $1 | awk '{printf("184 216 18 103 0 88");}'`";
hexdump -C /tmp/myfile

If I want output some char(0~255) to a file, just call the bash function:
attach_bytes [output file] [char in decimal(0~255)]

This looks like stupid but sometimes it really helpful. If there is any clever way, let me know πŸ™‚

VoCore2: Control RGB(WS2812B) LEDs

Now we can use VoCore2 control WS2812B based LED belt πŸ™‚ Hope this helps you make a beautiful house.

This is a “big” project for me, it contains three parts.

  • Linux Driver
    I am using I2S interface, because the best timer on VoCore2 is 1us… WS2812 requests 800KHz, and its bit0, bit1 is special: 800ns high then 400ns low, it is its bit1, 400ns high then 800ns low it is its bit0. We can not use timer to output that.
    But There is a super good channel, it is I2S. I2S speed is up to 240MHz. I find a way to use three I2S bits to simulate one WS2812 bit, set I2S speed to 2400KHz. πŸ™‚
    PS: I spend some time rewrite dma driver, so data is transfer from dma and VoCore2 is able to control 1024 LEDs at 30fps using less than 1% cpu.
  • API for user space
    I2S interface is not designed for such “common” usage, it is used to transfer audio data, so it is align with double word(4 byte), and have its special byte order, we can not send “abc” to I2S directly, because I2S real output will be “c?ab”. To use I2S interface, an API convert data order is necessary.
  • Hardware design.
    VoCore2 signal output voltage is 3.3V, WS2812B min signal voltage is 0.7 x Vcc = 3.5V, not match well. We’d better to use a buffer gate to convert the signal voltage for the accurate situation. This is option, without gate it still work, just sometime one or two LEDs are naughty. Connection is simple, I2S_SDO to WS2812B DATAIN.

β€œThere is no secret in the source code.”

First is Linux Driver Code: ws2812b.c, put it into Linux kernel and add it to Makefile and Kconfig, also enable gdma at VOCORE2.dts, compile. If it works normal, it will create a system file at /sys/devices/10000000.palmbus/10002800.gdma/update

You can try “echo aaaa > /sys/devices/10000000.palmbus/10002800.gdma/update”, I2S_SDO will output wave like this:

PS: actually I2S received data is “aaaa\r”

Then API Source Code:Β ws2812_api

ws2812_reset(): call this to turn all LEDs off RGB(0,0,0).
ws2812_set(int *color, int size): set leds colors. example: you have 16 WS2812B in a line, you want to set them to different color, code should be like this (include ws2812.h)

		int color[] = {0x080000, 0x000800, 0x000008,
		               0x080000, 0x000800, 0x000008,
		               0x080000, 0x000800, 0x000008,
		               0x080000, 0x000800, 0x000008,
		               0x080000, 0x000800, 0x000008,
		ws2812_set(color, sizeof(color) / sizeof(int));

For more details, check unit test code atΒ the end ofΒ ws2812.c.
The head photo is from this code πŸ™‚ For me everything works well.

VoCore2: Wifi driver(mt7628.ko) for LEDE 2

Last time I have success make the driver work, but it is not done.

Currently the log is like this, call “ifconfig ra0 up”

[  113.627999] mt7628_switch_channel(): Switch to Ch#9(1T1R), BBP_BW=0
[  113.634363] SYNC - BBP R4 to 20MHz.l
[  113.935695] [PMF]ap_pmf_init:: apidx=0, MFPC=0, MFPR=0, SHA256=0
[  113.941908] MtAsicSetRalinkBurstMode(2821): Not support for HIF_MT yet!
[  113.948644] MtAsicSetPiggyBack(746): Not support for HIF_MT yet!
[  113.982402] mt7628_switch_channel(): Switch to Ch#4(1T1R), BBP_BW=1
[  113.988785] MtAsicSetTxPreamble(2800): Not support for HIF_MT yet!
[  113.995163] MtAsicSetPreTbtt(): bss_idx=0, PreTBTT timeout = 0xf0
[  114.001379] Main bssid = b8:d8:12:67:5f:b5
[  114.005593] <==== rt28xx_init, Status=0

But I stopped here, I can find the SSID in my computer wifi list, but I can not connect to it, the icon on computer(macbook) is keeping in “connecting” status. I think I must miss some key steps, normal log should be like this.

[  449.410000] <==== rt28xx_init, Status=0
[  449.540000] device ra0 entered promiscuous mode
[  449.540000] br-lan: port 2(ra0) entered forwarding state
[  449.550000] br-lan: port 2(ra0) entered forwarding state
[  451.550000] br-lan: port 2(ra0) entered forwarding state

After ifconfig up, there is no log about ra0 entered forwarding state :p I am a noob again, haha. If you reader happen to know my mystery issue, please leave a message to this post πŸ™‚

Here is my compiled mt7628.ko for lede, do not depends on other kernel module, my command: "insmod mt7628.ko" and "ifconfig ra0 up" should make it work.

Also mediatek driver do not support openwrt uci interface, Linkit driver is using iwpriv to setup everything, another way is to use a config file in /etc/wireless/mt7628/mt7628.dat.

You can download here and copy to your lede.mt7628.dat

PS: the developing version lede is broken for VoCore2, lol, I guess somebody modify uart2 interrupt, now uart2 can not input any command to console, only able to output log to console, sad πŸ™‚