11 September 2015

Compiling a device tree using yocto

I am assuming you have a functional kernel recipe, say 'linux-yocto' with a device tree in e.g. arch/arm/boot/dts.

First build your kernel using

bitbake linux-yocto

Then run again using devshell

bitbake linux-yocto -c devshell

This places you in an shell in the temporary kernel source directory:


However all of the yocto scripts required to build are in the build output directory, $KBUILD_OUTPUT. That will be something like:


so to edit-build-deploy a device tree, you need to edit the dts file in the build directory (I find I need to do this from a different window, as editors don't work right in the devshell)

emacs arch/arm/boot/dts/machine.dts

then (still from the source directory)

make machine.dtb

(Note: machine.dtb, not machine.dts.)

Then copy your dtb file from the build output directory:

cp $KBUILD_OUTPUT/arch/arm/boot/dts/machine.dtb ~

Do not forget to copy your updated dts someplace permanent, because the kernel-source work dir will get wiped out in the next do_fetch() operation.

06 April 2015

Compiling Ericsson CXP_MBM_Tools_Development_Kit

We use a modem chipset from Ericsson. Ericsson has left this business so their engineering support is somewhat less than totally awesome. Perhaps you have the CXP_MBM_Tools_Development_Kit in your hot little hands and would like to make it compile under recent versions of gcc. (Note that if you do not have this kit, I cannot help you.) If you try to build under Ubuntu 14.04 it will fail with an error like:

Linking C executable out/mtool
/yocto/sources/CXP_MBM_Tools_Development_Kit/build/ecp/out/libecp.so: undefined reference to `dlopen'
/yocto/sources/CXP_MBM_Tools_Development_Kit/build/ecp/out/libecp.so: undefined reference to `dlclose'
/yocto/sources/CXP_MBM_Tools_Development_Kit/build/ecp/out/libecp.so: undefined reference to `dlerror'
/yocto/sources/CXP_MBM_Tools_Development_Kit/build/ecp/out/libecp.so: undefined reference to `dlsym'
collect2: error: ld returned 1 exit status

Per this post, changes to the "strictness" of shared libraries requires that you call -ldl after the desired shared libraries rather than before. #THANKS OBAMA.

There's probably a better way to do it than this, but this will suffice:

IN CXC_Manufacturing_Tool/src/CMakeLists.txt:

-  set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} " -ldl -Wl,-rpath=./")
+  set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} " -Wl,-rpath=./")

-  target_link_libraries(${TARGET_NAME} ${LIBRARY_LIST} ${CMAKE_THREAD_LIBS_INIT})
+  target_link_libraries(${TARGET_NAME} ${LIBRARY_LIST} ${CMAKE_THREAD_LIBS_INIT} -ldl)

15 January 2014

Talking to your modem under embedded linux

With the right drivers, modems chipsets show up as USB devices under linux, usually /dev/ttyACM*. When everything is working right, pppd just takes care of all of this an you have a nice easy ip layer. But when you are trying to figure out what your device is doing from the datasheet, you just want to type commands to the modem and get back its responses.

Googling for this resulted in approximately one billion ways to read and write from USB modems, including cat, cu, socat, getty, minicom, putty and, god help us, perl. These are distinguished by either a) not being bi-direction or b) not installed on a generic busybox-based embedded system. What you really want to use is microcom. It is built in to busybox, it works, and it's actually easier to use that most of the other options.

microcom [-d DELAY] [-t TIMEOUT] [-s SPEED] [-X] TTY
Copy bytes for stdin to TTY and from TTY to stdout
        -d      Wait up to DELAY ms for TTY output before sending every
                next byte to it
        -t      Exit if both stdin and TTY are silent for TIMEOUT ms
        -s      Set serial line to SPEED
        -X      Disable special meaning of NUL and Ctrl-X from stdin

The -t option is actually quite clever; it's very easy to disable control sequences and then get stuck. This bombs you out if nobody talks for x milliseconds. Example:

$ microcom -t 3000 /dev/ttyACM2

+CFUN: (0,1,4-6),(0,1)


If you really want to use socat I guess you can. In the below I seem to have forgotten whatever magic option is required to make socat send CRLF instead of just LF, so it doesn't actually work.

D4-11-D6-00-00-16:~ $ socat - /dev/ttyACM2



Notes on using the shell

Since I mostly use the shell under embedded linux, when I say /bin/sh I really mean /bin/ash, the Almquist shell, which is compiled into BusyBox and therefore pretty cheap resource-wise.

Maybe there are some people out there who like shell syntax. Suffice it to say I am not one of them. 


Some helpful links for myself:
The secret to successful shell Googling is knowing that "[" is pronounced "test".

Code Chunks

I can't believe I have to actually write down how to make a for loop.

POSIX-compatible For Loop

while [ $i -lt $max ]; do
  echo "$i"
  true $(( i++ ))

Assuming I can edit blogger posts, I'll edit this later.

Hilbert Transforms

This talk on Signal Processing Problems in Genomics by P. P. Vaidyanathan is an easy-to-read introduction to how signal processing techniques such as Fourier analysis are used in Genomics.

Complex to Real has a series of tutorials on signal processing topics. The tutorial on the Hilbert transform and its application to computing the envelope of a function is the best I've found.

27 September 2013


I'm writing in C for a while so I was reading Jim Larson's C style guide which prosthelytizes on the One True Bracket Style among other things. Good lord I had no idea indenting styles had names.

I am fine with 1TBS, but but I can't take tab=8 spaces. It is awful. Sorry.

23 September 2013

Upgrading Embedded Systems Using Rsync

Rsync-based Upgrades

Rsync is a marvelous if somewhat intimidating file-synchronization tool. I've been using it with good results to upgrade embedded linux devices in the field. (We have a backup kernel and root filesystem partition, so this is not a crazy as it sounds.)

Rsync is one of those programs that can do some many things that it is sometimes easier to modify an example what you want to do rather than trying to figure it out from the man page. So here are two examples.

Say we have a directory newroot that contains an image of the root file system we want to apply to a remote system:


Upgrade Root Filesystem Using Rsync

If we want to replace an entire root filesystem we can do it like this:

 rsync -RlptzvPDe "ssh -i ~/.ssh/id.rsa" --checksum --delete --stats --exclude="sudo" --exclude="sudoedit" --exclude="shadow" --exclude="gshadow" newroot/bin newroot/etc newroot/lib newroot/sbin newroot/opt newroot/usr newroot/var/lib newroot/www newroot/boot root@

switches controlling what to copy: (r)ecursive and recreate (l)inks

switches controlling metadata: (p)ermissions (t)ime but not (D)evices (g)roup (o)wner (as we want ssh user to own everything)
other required switches: (z)compress (e)xecute-via-ssh --checksum (slower but safer)
other useless switches: (P)rogress (v)erbose --stats

Specifying the root source directories (/bin, /etc...) avoids problems associated with the special directories like /proc and /dev.

Note I am using the not-particularly-safe --delete option. That is one reason why syncing special directories would be unwise.

The excludes are there to prevent attempts to overwrite a couple of other files associated with authentication.

Upgrade Multiple Files Using Rsync

Say you just need to send a couple of files. Rsync is very fast even when asked to duplicate the entire root filesystem, but sometimes the root filesystem built by the cross-compiling toolchain defers constructing the startup script order until first boot. Upgrading everything restores the system to first boot configuration, with the result that a checkconfig script might run to reconstruct the various scripts in /etc/rcS.d. That is unnecessary if none of that is actually changing.

Here's how to upgrade a few selected files (myApp and myApp.conf) using rsync:

rsync -RlptzvPDe "ssh -i ~/.ssh/id.rsa" --checksum --stats newroot/./etc/myApp.conf newroot/./opt/myApp root@

Here we've used (R)elative paths instead of (r)ecursive. Identifying the part of the relative path you want to transfer with a "." is a trick from the rsync manual; it means "copy relative path starting here." Since the target is / we end up upgrading files in /etc and /opt on the remote.

One issue: it seems rsync cannot upgrade itself via rsync!