You are currently browsing the archives for the training category.

Security and Connected Devices

September 9th, 2015
Andy McCormick

Andy McCormick

Technical Consultant at Feabhas Ltd
I provide expertise and training for Embedded Linux courses.

I have over 20 years of experience in the embedded sector, gained at companies such as Pace, Open TV and Sony Semiconductor Europe.

I've led work on numerous projects at all stages in the design cycle with comprehensive expertise in software engineering design, support and integration.
Andy McCormick

Latest posts by Andy McCormick (see all)

With the Internet of Things, we are seeing more and more devices that were traditionally “deep embedded” and isolated from the outside world becoming connected devices. Security needs to be designed into connected products from the outset as the risk of outside attacks is very real. This is especially true if you’re migrating from embedded RTOS systems to Linux and encountering a smorgasbord of “free” connectivity functionality for the first time.

Here we list 10 top tips to help make your connected device as secure as possible. Remember, in many cases, it may not be a question of ‘if’ but ‘when’ an attack occurs.

1. Keep your subsystems separate.

The Jeep Cherokee was chosen as a target for hacking by Charlie Miller and Chris Valasek following an assessment of the vulnerabilities of 24 models of vehicle to see if the internet-connected devices used primarily for communication and entertainment were properly isolated from the driving systems [1].

Most car driving systems are controlled using a CAN bus. You could access them via a diagnostic port – this is what happens when they are serviced in a garage. You would have to have physical access to the vehicle to do this. But if you are connecting to the comms/entertainment systems via the internet, and they’re connected to the driving systems, you could potentially access the driving systems from the internet.

With the explosion of devices being connected, consideration needs to be made to the criticality of functions and how to prevent remote access to a car’s brakes, steering, accelerator, power train and engine management controls. While it might be permissible to grant remote read access for instruments (e.g. mileage and fuel consumption), any control systems should only be accessible by the driver at the controls. And with things like heart monitors starting to become connected devices, the criticality of separation is likely to increase.

2. Secure Your Boot Code

One of the most effective ways of hijacking a system is via the boot code. Some of the earliest computer viruses, e.g. the Elk Cloner for Apple II [2], Brain and Stoned viruses for PCs, infected the boot sectors of removable media. Later viruses corrupted the operating system or even loaded their own. The same possibilities exist with computers and embedded devices today if the bootloader is well known, e.g, grub, u-boot or redboot.

Most devices designed with security in mind have a secure bootloader and a chain of trust. The bootloader will boot from a secure part of the processor and will have a digital signature, so that only a trusted version of it will run. The bootloader will then boot a signed main runtime image.

In many cases the bootloader will boot a signed second stage bootloader, which will only boot a signed main runtime. That way, the keys or encryption algorithms in the main runtime can be changed by changing the second stage bootloader.

3. Use Serialisation and Control Your Upgrade Path

When it comes to upgrading images in the field (to support new features, or to fix bugs or security flaws), this can be done using serialisation to target specific units in the field at particular times to reduce the risk of large numbers of units failing simultaneously after an upgrade.

Each runtime image should be signed with a version number so that only higher number versions can run. Upgrades can be controlled by a combination of different keys held in the unit’s FLASH.

4. Design for Disaster Recovery

Your box no longer boots in the field because the runtime image has become corrupted. What then?
Truck rolls or recalls are very expensive and they deprive the user of their product. There are alternatives:

(i) Keep a copy of the runtime for disaster recovery. This can be stored in onboard FLASH as a mirror of the runtime itself, or in a recovery medium, e.g. a USB stick, which is favoured these days by PC manufacturers.

(ii) Alternatively, the bootloader can automatically try for an over-the-air download – this is often favoured with things like set top boxes where the connection is assumed good (it wouldn’t be much of a set top box if it couldn’t tune or access the internet). This saves on FLASH but deprives the user of their product while the new runtime image is being downloaded.

5. Switch off debug code

Don’t give out any information that might be of use to the outside world. The Jeep Cherokee hack was made possible by an IP address being passed back to the user. It’s hard to see what use this would be to a typical non-tech user.

6. Harden the Kernel

The Linux Kernel contains thousands of options, including various ports, shells and communication protocols. It almost goes without saying that any production builds needs everything switched off except the features you need. But implementing this isn’t always so straightforward due to the inter-dependencies of some kernel features. Don’t use bash unless it’s unavoidable, use ash instead. The disclosure of the Shellshock, a 25-year-old vulnerability [3], in September 2014, triggered a tidal wave of hacks, mainly distributed denial of service attacks and vulnerability scanning.

Disable telnet. Disable SSH unless you have an essential usage requirement. Disable HTTP. If there is any way a user might form a connection with the box, especially using a method well-used on other boxes, that’s a door into the box that needs locking.

With the growing capabilities and connected nature of embedded RTOS systems approaching that of embedded Linux in Machine to Machine communications and the Internet of Things, similar “hardening” processes need to be followed.

7. Use a Trusted Execution Environment

Most of the main processors used in connected devices (smart phones, tablets, smart TVs, set top boxes) now contain a secure area known as a Trusted Execution Environment (TEE).

A TEE provides isolated execution environment where confidential assets (e.g. video content, banking information) can be accessed in isolation. Four popular uses are:
(i) premium content protection, especially 4k UHD content
(ii) mobile financial services
(iii) authentication (facial recognition, fingerprints and voice)
(iv) secure handling of commercially sensitive or government-classified information on devices.

TEEs have two security levels:
Profile 1 is intended to prevent software attacks.
Profile 2 is intended to prevent hardware and software attacks.

8. Use a Container Architecture

If you are designing a system with a processor that doesn’t use a TEE, you can still design a reasonably safe solution using a container architecture to isolate your key processes.

Linux Containers have been around since August 2008 and relies on Kernel cgroups functionality that first appeared in Kernel version 2.6.24. LXC 1.0, which appeared in February 2014, is considerably more secure than earlier implementations, allowing regular users to run “unprivileged containers”.

Alternatives to LXC are virtualization technologies such as OpenVZ and Linux-Vserver. Other operating systems contain similar technologies such as FreeBDS jails, Solaris Containers, AIX Workload Partitions. Apple’s iOS also uses containers.

9. Lock your JTAG port

Quihoo360 Unicorn Team’s hack of Zigbee [4] was made possible by dumping the contents of the FLASH from the board of the IoT gateway. This enabled them to identify the keys used on the network. The fact that the keys themselves were stored in a format that enabled them to be decoded made the hack easier.

If your JTAG port is unlocked, and hackers have access to the development tools used for the target processor, then they could potentially overwrite any insecure boot code with their own, allowing them to take control of the system and its upgrades.

10. Encrypt Communications Channels and any Key Data

If all the above steps are taken, a device can still be vulnerable to a man-in-the middle attack if the payload is sent unencrypted.

If you have a phone, table, smart TV or set top box accessing video on demand (VOD), the user commands need to be encrypted, otherwise it is possible to get free access to the VOD server by spoofing the server to capture box commands, and then spoofing the box to capture the server responses. It might even be possible to hack the server to grant access to multiple devices in the field, or mount a denial of service attack.

GPS spoofing by Quihoo 360 was demonstrated at DEF CON 23, where signals were recorded and re-broadcast [5]. It’s not the first time GPS spoofing has happened. Spoofing / MoM attacks on any user-connected system are commonplace.

Bonus Extra Tip: Get a Third Party to Break It

This is probably the most useful advice of all. As with software testing in general, engineers shouldn’t rely on marking their own homework: the same blind spots missed in a design will be missed in testing. Engineers designing systems won’t have the same mentality as those trying to hack them. An extra pair of eyes going over the system trying to break it will expose vulnerabilities you never thought existed.


Security is a vast subject and we’ve only scratched the surface in this blog.
Feabhas offer a course EL-402 in Secure Linux Programming, for more information click here.


1. Fiat Chrysler Jeep Cherokee hack

2. Elk Cloner

3. Shellshock

4. Zigbee hack
Def Con 23

5. GPS Spoofing
Def Con 23

Python – The everyman’s language

May 17th, 2013

Nick Glynn

Technical Consultant at Feabhas
Nick Glynn is a key technical trainer and consultant delivering courses and expertise on Android, Python, Security and Linux at home in the UK and across the globe.

He has a broad range of experience, from board bring-up, Linux driver development, and systems development through to full stack deployments, web app development, and security hardening for both the Linux and Android platforms.

Latest posts by Nick Glynn (see all)

Python is a very nice language in many respects: enforced white-spacing promotes readability, extensibility and Python’s inbuilt Read-Eval-Print-Loop interpreter combined with its introspection capabilities provides a very easy way to learn and get to grips with the language.

But that can’t be all, can it? Why Python?

One of the reasons behind the success of our course has been customers wanting a good language for developing automated testing scripts and Python fits the bill brilliantly – it’s fast (enough), approachable and has great support for the embedded platforms of today and tomorrow (read: Linux  :))

In the scripting ring we have a number of contenders – Bash, Perl, Ruby, Lua, Javascript but each lacks that certain je ne sais quoi that makes Python so good – or maybe it’s just that the others don’t quite do what I want; Perl has a syntax that makes me want to scratch my eyes out, Bash is great on the command line but has control structures and compatibility issues that make the baby Jesus cry but some of the others are worth a look.

Lua is nice, I’m honestly a fan of Lua and have used it in previous projects where Python was just too big to embed (adding in Lua is a ‘tiny’ 400kb) but that’s the issue – Python is a general programming language – I can quickly bring in web services, advanced numerical libraries, GUIs and scientific libraries as well as the built-in things like networking and threading but Lua just simply isn’t designed for the vast contexts that Python fits and that’s part of Lua’s design – it’s not a general scripting language.

JavaScript is the in-vogue scripting language of the moment; it’s easy to test and develop in the web browser and it has a C style language that can appeal but I worry about any language where I can type in the following and not have it shout an error at me…

[nick@zeus ~]$ gjs
gjs> +((+!![]+[])+(!+[]+!![]))

12? of course it is. Go home JavaScript. You’re drunk.

I am seeing more and more interest in using JavaScript in the embedded space, one recent example being the new Beaglebone Black, which allows you to interact with the hardware using JavaScript and a Node.JS back-end.  JavaScript, though, it is still too tied to web technologies and less as a general system scripting language.

Ruby… well, I just simply haven’t found a good resource for learning about Ruby in the embedded space – that one is on me, sorry but maybe I was just scared by the famous Wat talk (here’s looking at you too JavaScript).


One thing that does let down Python, in my opinion, is the lack of a good developer environment. I appreciate that Python is easy to use and the interactivity is a massive boon but showing IDLE to someone who has used Visual Studio and all it’s spoon feeding goodness does make me a little sad.


Approachable huh?

Line numbers? Stability? A carat that will allow you to type when you misclick? – why do you need those when you can have… Detachable Menus!
It’s easy to make fun but IDLE seems un-maintained and could do with some TLC but it’s still useful as a learning tool to bridge the gap between Visual Studio and the command line.  On the plus side, the debugger does bring some good insight into the operation of the code for first-timers.


Whenever I need to script something, mock up an interface, test a design, develop some back-end code or create a full application – Python is always there for me.
Python’s versatility, compatibility and ‘kitchen sink’ approach make Python a fantastic choice for almost everyone, from non-programmers through to the physicists at CERN using it to create black holes.  It truly is the everyman’s (and woman’s) language.

So why not learn something new?

[nick@zeus ~]$ python
Python 2.7.3 (default, Aug 9 2012, 17:23:58)
[GCC 4.7.1 20120720 (Red Hat 4.7.1-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import antigravity

I Dream of a Cheeky Missile Launcher

October 12th, 2012

Nick Glynn

Technical Consultant at Feabhas
Nick Glynn is a key technical trainer and consultant delivering courses and expertise on Android, Python, Security and Linux at home in the UK and across the globe.

He has a broad range of experience, from board bring-up, Linux driver development, and systems development through to full stack deployments, web app development, and security hardening for both the Linux and Android platforms.

Latest posts by Nick Glynn (see all)

I read a blog post by Matthias Vallentin a while back about getting a USB missile launcher working and thought that a similar gadget would be a nice candidate for the 2012 refresh of our successful EL503 Developing for Embedded Linux course so ordered a nice looking piece of hardware from Amazon – the Thunder Missile Launcher from Dream Cheeky.

Sadly these guys don’t provide Linux drivers and the hardware wasn’t an exact match for the launcher used in Matthias’ article so I had to do a bit of research.

Normally it would be a case of firing up my Windows partition and using a USB Sniffer but I didn’t want to shutdown my system as I was in the middle of quite a few projects so I hit the net and stumbled across the Retaliation project which used the Thunder Launcher to punish people who broke a CI build and a blog piece by Nathan Milford which had the requisite USB command codes but had programs that leveraged libUSB from userspace.

So now I knew what I had to feed my launcher and had some good resources on Linux USB[1] [2] [3] now I could start!

Echoing Matthias’ steps – I created a simple core driver that would print info out in the probe

/* Rocket launcher specifics */
#define LAUNCHER_VENDOR_ID 0x2123
#define LAUNCHER_PRODUCT_ID 0x1010
#define LAUNCHER_NODE "launcher"

static struct usb_class_driver class;

/* Table of devices that work with this driver */
static struct usb_device_id launcher_table[] =
{} /* Terminating entry */
MODULE_DEVICE_TABLE (usb, launcher_table);

static struct usb_driver launcher_driver =
.name = "launcher_driver",
.id_table = launcher_table,

static int launcher_open(struct inode *inodep, struct file *filp)
int retval = 0
/* Save our object in the file's private structure. */
/* filp->private_data = dev; */
return retval;

static int launcher_close(struct inode *inodep, struct file *filp)
int retval = 0;
/* We can get private data from filp->private_data; */
return retval;

static ssize_t launcher_read(struct file *f, char __user *buf, size_t cnt,
loff_t *off)
int retval = -EFAULT;
return retval;

static ssize_t launcher_write(struct file *filp, const char __user *user_buf,
size_t count, loff_t *off)
int retval = -EFAULT;
/* We can get private data from filp->private_data; */
return retval;

static struct file_operations fops =
.open = launcher_open,
.release = launcher_close,
.read = launcher_read,
.write = launcher_write,

static int launcher_probe(struct usb_interface *interface, const struct usb_device_id *id)
struct usb_device *udev = interface_to_usbdev(interface);
struct usb_host_interface *iface_desc;
int retval = -ENODEV;


/* Set up our class */ = LAUNCHER_NODE"%d";
class.fops = &fops;

if ((retval = usb_register_dev(interface, &class)) minor);
/* This will be our private interface device data instead of NULL eventually */
/* usb_set_intfdata(interface, NULL); */
return retval;

static void launcher_disconnect(struct usb_interface *interface)
/* Give back our minor. */
usb_deregister_dev(interface, &class);

static int __init launcher_init(void)
int result;

/* Wire up our probe/disconnect */
launcher_driver.probe = launcher_probe;
launcher_driver.disconnect = launcher_disconnect;

/* Register this driver with the USB subsystem */
if ((result = usb_register(&launcher_driver))) {
pr_err("usb_register() failed. Error number %d", result);
return result;

static void __exit launcher_exit(void)
/* Deregister this driver with the USB subsystem */


I compiled this with the makefile, inserted the module and saw that my init call had successfully been called so I popped the launchers USB into my laptop and…. nothing.

I checked dmesg and saw it had been claimed by hid-generic, part of the usbhid module on my laptop!

[205211.636201] usb 2-1.2: >USB disconnect, device number 23
[205214.371289] usb 2-1.2: >new low-speed USB device number 24 using ehci_hcd
[205214.462969] usb 2-1.2: >New USB device found, idVendor=2123, idProduct=1010
[205214.462979] usb 2-1.2: >New USB device strings: Mfr=1, Product=2, SerialNumber=0
[205214.462985] usb 2-1.2: >Product: USB Missile Launcher
[205214.462990] usb 2-1.2: >Manufacturer: Syntek
[205214.468668] hid-generic 0003:2123:1010.000B: >hiddev0,hidraw0: USB HID v1.10 Device [Syntek USB Missile Launcher] on usb-0000:00:1d.0-1.2/input0

To get hidusb to release it, you can tell it to unbind using sysfs.

[nick@slimtop ~]$ ls /sys/bus/usb/drivers/usbhid/
2-1.2:1.0 bind module new_id remove_id uevent unbind
^^^ Our address
[nick@slimtop ~] sudo sh -c 'echo 2-1.2:1.0 > /sys/bus/usb/drivers/usbhid/unbind'
[nick@slimtop ~]$ ls
bind module new_id remove_id uevent unbind

To get it to bind to our driver we would have to poke it manually

[nick@slimtop ~]$ sudo sh -c 'echo "2-1.2:1.0" > /sys/bus/usb/drivers/launcher_driver/bind'

Checking dmesg again showed that the probe function had been called and we had our /dev/launcher0!

I now needed to update the information expected by the driver. The original launcher used by Matthias’ had different codes for most of the commmands so using the userspace information we could update the command codes and tweak the control codes.

#define LAUNCHER_NODE "launcher"

#define LAUNCHER_STOP 0x20
#define LAUNCHER_UP 0x02
#define LAUNCHER_DOWN 0x01
#define LAUNCHER_LEFT 0x04
#define LAUNCHER_RIGHT 0x08
#define LAUNCHER_FIRE 0x10

Our USB command code takes the form of:
where DATA is an 8 byte buffer with the first set to 0x8, our COMMAND_PREFIX.

For example, to send a fire command (0x10) we would use a usb_control_msg like this

int usb_control_msg ( struct usb_device *dev,
unsigned int pipe,
0x09, // Request
0x21, // Request Type
0x0, // Value
0x0, // Index
&buffer, // Buffer
sizeof(buffer), // Length of buffer
int timeout);

where buffer would be a blank char buffer of 8 bytes with the first and second bytes set to the COMMAND_PREFIX and command code respectively which you can see in this snipped from our launcher_write() function

if (copy_from_user(&cmd, user_buf, count)) {
retval = -EFAULT;
goto unlock_exit;

/* Prepare the buffer, noting the prefix */
memset(&buf, 0, sizeof(buf));
buf[1] = cmd;

/* The interrupt-in-endpoint handler also modifies dev->command. */
dev->command = cmd;

pr_debug("Sending usb_control_message()\n");
retval = usb_control_msg(dev->udev,
usb_sndctrlpipe(dev->udev, 0),

I won’t cover too much on the USB code as it is covered in far more depth in Matthias’ article and Greg KHs usb-skeleton.c in the kernel source tree.

To control our driver, we can send bytes from userspace to the /dev/launcher0 entry and I was able to repurpose Matthias’ launcher program to send the correct command codes to the device which I have added to the Git repository. When you create the executable and module using make, and assuming you have the right libraries, you will have a launcher_driver.ko and a launcher_control executable.

Insert the kernel module using insmod ./launcher_driver.ko and you can then start issuing commands to the launcher.

Unfortunately by default, the device node /dev/launcher0 is created as root:root with permission 0600 which means that you can either chmod/chgrp it or run the launcher as root(!) which is the simplest test:

sudo ./launcher_control -f

usbhid and the Handsy Driver

As we’ve looked at, usbhid tries to claim our device by default due to it looking like a Human Interface Device and I had to do a fair amount of digging to find out how to stop usbhid from claiming our device which I’ll recap for those who seek enlightenment.

If you look in the source code for /drivers/usb/usbhid/hid-quirks.c we can see a structure that defines a blacklist of HID devices.

static const struct hid_blacklist {
__u16 idVendor;
__u16 idProduct;
__u32 quirks;
} hid_blacklist[] = {

This shows a format of VENDOR_ID, DEVICE_ID and the HID_QUIRK mode which can be multiple values OR’d together and if we look further down the source, we can see the following function:

int usbhid_quirks_init(char **quirks_param)
u16 idVendor, idProduct;
u32 quirks;
int n = 0, m;
for (; n < MAX_USBHID_BOOT_QUIRKS && quirks_param[n]; n++) {
m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x",
&idVendor, &idProduct, &quirks);
if (m != 3 ||
usbhid_modify_dquirk(idVendor, idProduct, quirks) != 0) {
"Could not parse HID quirk module param %s\n",
return 0;

Which is an array passed in from hid-core.c in the following snippet:

/* Quirks specified at module load time */
static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
module_param_array_named(quirks, quirks_param, charp, NULL, 0444);
MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
" quirks=vendorID:productID:quirks"
" where vendorID, productID, and quirks are all in"
" 0x-prefixed hex");

This shows us that the quirk param values are read in the form of 0xVENDORID:0xPRODUCTID:0xQUIRKS so now we know how to get usbhid to use a quirk for our device, we need to know which one.

Defined in include/linux/hid.h are our quirks, we want to tell usbhid to just leave it alone so we’re going to use HID_QUIRK_IGNORE which has the value of 0x04.

Once we have this information we should be able to modprobe -r usbhid && modprobe usbhid quirks=0x2123:0x1010:0x04 … except that we can’t remove the module on our Fedora system…

[nick@slimtop ~]$ modprobe -r usbhid
FATAL: Module usbhid is builtin.

Oh dear. This means that the usbhid module isn’t loaded at runtime, instead it has been built into the kernel so we can’t change it from userspace as the kernel, with usbhid, is already running before the filesystem has been mounted so we will need to pass the parameter to the kernel in the form:
To do this, I edited my kernel command in /boot/grub2/grub.cfg to tell the builtin module about our device and add it to the quirks list.

echo 'Loading Fedora (3.6.2-4.fc17.i686)'
linux /vmlinuz-3.6.2-4.fc17.i686 root=/dev/mapper/vg_slimtop-lv_root ro SYSFONT=True usbhid.quirks=0x2123:0x1010:0x04 KEYTABLE=uk rd.luks=0 LANG=en_US.UTF-8 rhgb quiet

Finally, we can get our kernel module to load automatically by copying our launcher_driver.ko into the /lib/modules/`uname -r`/ directory and running depmod -a.

On rebooting, you should be able to insert your launcher and up will pop a /dev/launcher0 without usbhid getting handsy with it.


udev is the device manager for the Linux kernel. Primarily, it manages device nodes in /dev so we’re going to use that to manipulate the creation of our /dev/launcher0 entry.

There is a lot of information spread over the net on udev but it’s sometimes out of date and no longer relevant. It’s best to ask questions in IRC, copy existing rules (see /usr/lib/udev/rules.d/*) or just read the source to get the most up-to-date information.

To avoid having to run our launcher as root we can create a special rule for udev[1] to manipulate how the node is created. To do this you will need to create a new file in /etc/udev/rules.d/10-dreamcheeky.rules containing the following:


This tells udev that we want any events from the KERNEL that match /dev/”launcher?*” which is what our driver requests (the regular expression matches any number after our launcher string, such as 1,2,3 etc).
When that event KEY has been matched, we apply the two ASSIGN values which specify the permissions mode, 0666 or rw-rw-rw-, and that it should belong to the wheel group.

To test our rule, we need to know how udev sees our USB device so we do the following:

[nick@slimtop ~]$ find /sys/devices/ -name launcher0

To test our udev rule we run udevadm test as follows against our device path

[nick@slimtop rules.d]$ sudo udevadm test /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/usbmisc/launcher0
run_command: calling: test
adm_test: version 182
This program is for debugging only, it does not run any program,
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.

builtin_kmod_init: load module index
parse_file: reading '/etc/udev/rules.d/10-dreamcheeky.rules' as rules file <--- OUR RULES FILE
parse_file: reading '/usr/lib/udev/rules.d/99-systemd.rules' as rules file
udev_rules_new: rules use 249228 bytes tokens (20769 * 12 bytes), 42425 bytes buffer
udev_rules_new: temporary index used 76720 bytes (3836 * 20 bytes)
udev_device_new_from_syspath: device 0xb9009810 has devpath '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/usbmisc/launcher0'
udev_device_new_from_syspath: device 0xb9009b00 has devpath '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/usbmisc/launcher0'
udev_device_read_db: device 0xb9009b00 filled with db file data
udev_rules_apply_to_event: GROUP 10 /etc/udev/rules.d/10-dreamcheeky.rules:1
udev_rules_apply_to_event: MODE 0666 /etc/udev/rules.d/10-dreamcheeky.rules:1
udev_device_new_from_syspath: device 0xb901a540 has devpath '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0'
udev_device_new_from_syspath: device 0xb901a088 has devpath '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2'
udev_device_new_from_syspath: device 0xb90239b0 has devpath '/devices/pci0000:00/0000:00:1d.0/usb2/2-1'
udev_device_new_from_syspath: device 0xb9023cb0 has devpath '/devices/pci0000:00/0000:00:1d.0/usb2'
udev_device_new_from_syspath: device 0xb9024000 has devpath '/devices/pci0000:00/0000:00:1d.0'
udev_device_new_from_syspath: device 0xb901f220 has devpath '/devices/pci0000:00'
udev_device_read_db: no db file to read /run/udev/data/+usb:2-1.2:1.0: No such file or directory
udev_node_add: handling device node '/dev/launcher0', devnum=c180:0, mode=0666, uid=0, gid=10
node_fixup: preserve permissions /dev/launcher0, 020666, uid=0, gid=10
node_symlink: preserve already existing symlink '/dev/char/180:0' to '../launcher0'
udev_device_update_db: created empty file '/run/udev/data/c180:0' for '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/usbmisc/launcher0'
builtin_kmod_exit: unload module index

That’s it – you should be able to remove/insert your USB device and have /dev/launcher0 show up with the permissions and group you chose.


This has been a very long blog article but I hope this is helpful and serves to tie together a lot of good resources that seem spread thinly across the net so have fun and experiment!

The code for the userspace and driver is available on our Feabhas Github at with a single Makefile to build both projects.

I built this on Fedora 17 so your mileage may vary depending on your distribution/environment.

[1] Special thanks go to the #udev IRC channel on freenode (in particular the user falconindy) and these two resource pages:


October 13th, 2010

Niall Cooling

Director at Feabhas Limited
Co-Founder and Director of Feabhas since 1995.
Niall has been designing and programming embedded systems for over 30 years. He has worked in different sectors, including aerospace, telecomms, government and banking.
His current interest lie in IoT Security and Agile for Embedded Systems.

Latest posts by Niall Cooling (see all)

At Embedded Live 2010 I shall be presenting a half-day tutorial entitled “EMBEDDED PROGRAMMERS’ GUIDE TO THE ARM CORTEX-M ARCHITECTURE”.

Feabhas have been training embedded software engineers in languages and architectures for the last 15 years. For the last decade we have been using ARM based target systems for all our programming based courses (C, C++ and testing – ARM7TDMI) and embedded Linux courses (ARM926). However with the development and release of the new generation Cortex micros we are moving our training over to Cortex-M for the languages and Cortex-A for Linux.

As part of this exercise we have to spend lots of time getting to know the Cortex microprocessors in detail, looking at different implementations and various support tools and environments.

The majority of supporting material around the new generation of ARM Cortex-M architectures (M0, M3 & M4), unsurprisingly, focuses heavily on the key hardware specifics of the microcontroller core, with most coding examples being in THUMB2 assembler. However the majority of programming for the Cortex will be in the C programming language (recently a VDC report showed C is still head-and-shoulders above other languages for embedded programming )

Core Features

This class looks at all the really useful features added to the Cortex-M that makes it a truly excellent target environment for the embedded software engineer.  As a simple example many embedded processors do not support integer division in hardware (e.g. ARM7), so division typically handled by an intrinsic library function call or compiler ‘tricks’

The new Cortex-M3 has new signed and unsigned integer division instructions, that can also support modulo operation ( x % y )

There are many other features that I shall cover including unaligned-transfers, bit-banding and the new improved interrupt support architecture (NVIC).

However, there are three other significant supporting technologies that really help the software engineer.

  1. Cortex Microcontroller Software Interface Standard (CMSIS)
  2. Debug Support
  3. RTOS Support


Simply put, CMSIS is a collection of source files (.c, .h and assembler) to create a minimal board support package (BSP) for Cortex-M series processors. Very usefully, it defines a common way to access peripheral registers and define exception vectors. It also defines the register names of the Core Peripherals and the names of the Core Exception Vectors. So, instead of having to spend time and effort defining structs for register definitions for onboard devices (or hoping you development environment has already done this for you) you can be assured that they already exist. For example, the NXP LPC17xx family of microcontrollers support a watchdog timer. Being CMSIS compliant, then the supplied header LPC17xx.h defines the register layout and necessary #defines:

Debug Support

JTAG units, such as the Keil ULINK, have made target programming and source-level debug very affordable. However, for small pin count micros, the 4-wire JTAG is seen as quite expensive option (in terms of pure pin-count). As part of the Cortex-M core is support for a new serial-wire interface. The advantage being that it only requires 2-wires, which makes it very easy and affordable to support debug (and power) over a simple USB connection.

At the other end of the spectrum, ARM have added the option for an Embedded Trace Macro (ETM) unit, which allows features such as debug of events in real-time systems where the target cannot be halted and software profiling and code coverage.

RTOS Support

For someone who has a long background in Real-Time Operating Systems, I was very interested to discover how ARM has made it simpler and easier for an RTOS vendor to support the Cortex-M.  As you can guess CMSIS is a huge step forward, as it means once an RTOS has been ported using CMSIS, the core aspects will work on, say, all Cortex-M3 implementations.

As a simple example, pretty much all RTOS require a time-frame reference (the “tick” timer) for timeouts and delays, etc.  ARM has integrated this directly into the core (called Systick) rather than each silicon vendor having to implement their own count-up or count-down variant. There are already 20+ RTOSs running on the Cortex-M.

Also as, as an optional part of the Cortex-M3/M4 core is a memory-protection unit. An RTOS can make use of this to create a safer multitasking platform without the expense of a full-blow MMU.

Finally, what makes the Cortex-M so attractive from a embedded software engineers perspective is to abundance of low cost evaluation kit, such as mbed, LPCXpresso, STM32 Value line Discovery, Energy Micro Gecko Starter Kit, and Actel’s  SmartFusion to name just a small selection.

I hope to see you at Embedded Live 2010. If so please come and say hello.

We Have Met the Enemy and He Is PowerPoint

April 28th, 2010

Niall Cooling

Director at Feabhas Limited
Co-Founder and Director of Feabhas since 1995.
Niall has been designing and programming embedded systems for over 30 years. He has worked in different sectors, including aerospace, telecomms, government and banking.
His current interest lie in IoT Security and Agile for Embedded Systems.

Latest posts by Niall Cooling (see all)

This the headline to the central story in today’s New York Times. The story is about the overuse of PowerPoint by the US military, especially in Afghanistan. It centers around a particular PowerPoint slide (shown below) attempting to portray the complexity of US strategy in the region.

The article discusses that a Brig. Gen. H. R. McMaster banned PowerPoint presentations when he led the successful effort to secure the northern Iraq city of Tal Afar.

Leading on from this,  you may be aware, that next weeks UK event the Embedded Masterclass has also banned PowerPoint from its technical presentations. To quote from the website:

This year we have asked the presenters of the 40 min Technical Presentations to ‘abandon Power Point’ . Instead they will have a white board, a flip chart and hand-outs and of course – their wit and charm ! We want to bring a bit of life back into these kinds of events and raise the standards. We are hoping this will lead to a better and more inter-active presentation. It is already causing the presenters to think more carefully about what they intend to present and how it will be structured.

I understand the sentiment, but I’m sorry but No; PowerPoint is just a tool. Banning (or abandoning) PowerPoint is not addressing the root problem.

For anyone who wants to do a professional job of presenting then there are great reference materials out there (e.g. Presentation Zen, silde:ology, beyond bullet points, etc.).

In reality many poor presentations are due to a lack of a proper review process prior to the event(admittedly some people just can’t present). All presentations should be backed up by a hand-out technical paper and not just a print-out of the slides (eliminating the need for lots of technical detail on a slides). Finally, being someone who has to regularly present  5 days of detailed technical training on embedded systems, white boards and flip charts just aren’t big enough for a large audience (unless you can write REALLY BIG).

To combat this problem of free form notes to a large audience, at Feabhas we have been using a really cool tool called PaperShow to augment the slides. Ideally we’d use two projectors, but this isn’t typically practical. Alternatively you could go back to the “good old days” on OHPs, foils and pens.

As I’ll be at the Cambridge event (as we’re running an Embedded Linux training class) I’m really interested in how it actually works and my concerns will hopefully be proven wrong. Hopefully see you there…

Embedded Systems Conference – Silicon Valley

April 22nd, 2010

Niall Cooling

Director at Feabhas Limited
Co-Founder and Director of Feabhas since 1995.
Niall has been designing and programming embedded systems for over 30 years. He has worked in different sectors, including aerospace, telecomms, government and banking.
His current interest lie in IoT Security and Agile for Embedded Systems.

Latest posts by Niall Cooling (see all)

As I’m sure you’re well aware, the ash cloud from the Eyjafjallajokull volcano (which began erupting in mid-March) pretty much brought much of European airspace to a standstill over last weekend and into this week. Now that UK airspace has been reopened, it appears I can resume plans for my visit to the Embedded Systems Conference in San Jose next week.

The sessions I’m directly involved with are:

Examining ARM’s Cortex Microcontroller Software Interface Standard – CMSIS
Date/Time: Tuesday (April 27, 2010)   3:15pm — 4:15pm
In this session I shall be examining ARM’s Cortex Microcontroller Software Interface Standard (CMSIS –  typically pronounced C-M-Sis) . CMSIS aims to provide a framework of reusable components for software developers, silicon and compiler vendors to utilize. Aspects such a power-up boot management and interrupt control have been abstracted and defined by ARM for their Cortex-M family of microcontroller cores. I’ll spend time explaining the CMSIS framework, examining the code from a compiler and chip perspective, and finish off by discussing the pros and cons I see in such an approach.

Understanding Mutual Exclusion: The Semaphores vs. the Mutex
Date/Time: Wednesday (April 28, 2010)   12:00pm — 12:50pm
Location (room): ESC Theater 2
This presentation is based around much of the material in some of my previous postings (see RTOS related blog postings ). One of the things I like about ESC events is that some of the sessions are free. So if you happen to be attending just the exhibition, then you can still attend this session.

The State of Embedded
Date/Time: Wednesday (April 28, 2010)   4:00pm — 4:50pm
Location (room): ESC Theater 1
Finally, I have been invited to participate in an informal session along with Jack Ganssle and Dan Saks (moderated by Rich Nass of and EE Times) to discuss some of the latest trends in embedded systems. We did a similar session at ESC UK back October 2009, which was very well received. It shall be interested to see how being the token European with a US audience differs from the UK event. This is also a free session.

If you’re at the event look me up and say hello.

Why is technical training so hard to get funding for?

March 29th, 2010

Niall Cooling

Director at Feabhas Limited
Co-Founder and Director of Feabhas since 1995.
Niall has been designing and programming embedded systems for over 30 years. He has worked in different sectors, including aerospace, telecomms, government and banking.
His current interest lie in IoT Security and Agile for Embedded Systems.

Latest posts by Niall Cooling (see all)

Over many years of delivering technical training to the embedded systems sector, two questions have always bothered me:

  • Why, when the economy gets difficult, are training budgets one of the first things to get cut?
  • Why do delegates, who have waited months (sometimes years) to attend training, get pulled off mid-course?

Even though a myriad of articles tell us why businesses should invest in training during an economical downturn (Why Invest in Training During an Economical Downturn?) funding for training is very hard to come by. So why does this happen?

In reality there are only two types of training:

  • Must-do
  • Everything-else

Read more »

%d bloggers like this: