You are currently browsing the archives for the General category.

My Top 5 Podcasts

December 23rd, 2015

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)

For the final blog post of the year I’ve decided to do something a little different; I hope that’s okay?noun_15457

Due to the nature of the job, the technical team at Feabhas spend a lot of time travelling. This means many an hour spent in the car driving to and from client sites; often involving navigating the wonderful M25 London orbital [car park!]. We all while away this time in different ways, some prefer music, others radio (which, being in the UK means we’re very well served with the array of BBC stations).

I, however, have been a long term fan of podcasts. From having my first fruit-based music device I have listened to podcasts especially on long drives. Over the years many people have asked me what I listen too, so I though it might be useful to finally share my listening habits. So here are my ‘current’ top 5.

Kermode and Mayo’s File Review (better knows a ‘Wittertainment’)

My first podcast is not a technology show, but a film podcast. Another “benefit” of spending lots of time on long-haul flights and hotel rooms is I get to watch a lot of films (which drives my family to despair). The live broadcast of the BBC Radio 5 Live Friday afternoon show is wrapped in a weekly podcast.

It is one of those shows that has many ‘in-jokes’; the longer you listen the funnier it gets. I have had many a time where I have been in tears of laughter on my own in the car. Just excellent.

Typical show length ~2 hours

Security Now

Ever since first reading “The Cuckoo’s Egg” back in 1990 (on my honeymoon of all things!) I have been developed a real interest in computer security. From an embedded guy’s perspective many aspects of security and their breaches have been of passing interest (e.g. SQL injection attacks, cross-site scripting, etc.) as they’re “not part of my world’. However with our headlong rush into IoT and connected systems I predict this is going to have the largest impact on the embedded software community for many a year.

SN has been running for over 10 years now (an amazing achievement) and is hosted by Steve Gibson and Leo Laporte. They make a great double-act, and as someone who spends their time training software engineers, I appreciate Steve’s ability to take complex subjects and make them simple (but not dumb). Leo is also a great technologist, having a good, broad understanding of technology trends through his running of the TWiT.tv Netcast Network.

Each show now is typically around two hours long. Every other week (when not overwhelmed by security news) there is a Q&A show. I must admit if I’m getting behind I will skip the questions part of the Q&A show (but not the preamble before the questions which covers this weeks security news). I find the show very pragmatic and suitable for people who are not security professionals. In addition, Steve keeps both show notes and a textual transcription of the show on his site . I have found this useful where there is something I have heard while driving (or walking the dog) and want to look into further. For example, this year I’ve spent a lot of time looking at SSL/TLS and DTLS for IoT where I found Steve’s coverage of SSL/TLS a useful starting point for further research.

Typical show length ~2 hours

TED Radio hour

Hopefully you’re already aware of TED (Technology, Entertainment and Design) Talks; if so, then this show takes a common theme (e.g. the Open Source World, Playing with Perceptions) and brings together a number of different TEDTalks by interviewing the presenters, interlaced with clips from their talks. The host, Guy Raz, does an incredible job of bringing out the story behind the talk and making you want to immediately get online and watch the full, original, talk. I really like this as it exposes me to aspects of our world I wouldn’t necessarily consider. For example, a recent show focused on “Quiet” and explored ways to find quiet in our busy lives.

Typical show length ~50 mins

FreakonomicsRadio

I was drawn to this podcast as I’d previously read the excellent book Freakonomics by Steven D. Levitt and Stephen J. Dubner. The book was published back in 2005 with the podcast starting in 2010. Fundamentally it’s a show (following on from the premise of the book) about how economics effect decisions in our everyday lives. The subject areas vary widely; from crack gangs though to real-estate agents. The shows always make me consider my own viewpoint (e.g. show 210 “Is It Okay for Restaurants to Racially Profile Their Employees?”) even when I didn’t appreciate I had one! I also really like when the show wanted to ask for donations to continue (I do do a monthly donation) they did an episode exploring the issues and economics : show 141 “How to Raise Money Without Killing a Kitten”.

Being on NPR, the show is, naturally, U.S. centric; but still a very worthwhile listen.

Typical show length 30-45 mins

Infinite Monkey Cage

Another offering from the BBC; this show is a bizzar mix of hard science and comedy. People who know me well might be surprised by this choice as I’m not a great fan of one of the hosts, the acclaimed physicist Brian Cox’s TV programmes (e.g. The Wonders of… series). However, on this show, his very witty co-host, Robin Ince, brings a nice balance to the show. There are also typically a two or three additional guests helping bring the show along.

Following on with a common theme from the previous two podcasts (TED and Freakonomics) I like this show as it attempts to explore subject areas that wouldn’t always be foremost in your mind (e.g. the apocalypse and space travel). An great intellectual show that doesn’t dumb down the subject and makes me think.

Typical show length ~30 mins

Honourable mentions

If you’re doing any form of longish commute I recommend trying the different podcasts out. Personally I use the Downcast app to listen to my podcasts in preference to the native apps.

Are there any really good ones out there I’ve missed? If so please leave me a comment or let me know on twitter (@feabhas).

So that’s pretty much it for 2015 from the team at Feabhas. We hope you’ve appreciated the blogs that we’ve put out (with Glennan doing such a sterling job on Modern C++ subjects). We’re already lining up blogs for 2016, but if there are areas you feel we could address better please let us know.

Otherwise, I wish you all a Merry Christmas from all at Feabhas and look forward to 2016 where we’ll have some new major announcements!

Thanks you all for your support.

Niall.

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.

Conclusion

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.

References

1. Fiat Chrysler Jeep Cherokee hack
http://www.wired.com/2015/07/hackers-remotely-kill-jeep-highway/

2. Elk Cloner
http://www.theregister.co.uk/2012/12/14/first_virus_elk_cloner_creator_interviewed/

3. Shellshock
https://shellshocker.net

4. Zigbee hack
Def Con 23

5. GPS Spoofing
Def Con 23

On BashLite and Shellshock

November 19th, 2014

A number of people have been in touch with me about the fact that our Linux courses use an embedded target system that deploys BusyBox as standard and that there’s a “known exploit” doing the rounds called BashLite.SMB – this is obviously a cause for alarm!… Right?

WRONG!! Never one to shy away from defending my beloved Linux I wanted to make a quick public service announcement to say that this appears to be a fairly run-of-the-mill piece of malware riding on the coat tails of the significantly more dangerous ShellShock vulnerability which should be patched!

Busybox itself was never vulnerable to the Shellshock exploit due to it’s usage of an alternative shell – ash – which isn’t a bug-for-bug implementation of Bash.
BashLite is a backdoor opening, information stealing tool that can also be used as part of Command & Control based attacks and is typically the second prong of an attack that has already granted access to the system – either by ShellShock itself (you’re not running unpatched Bash on your device are you?) or by administrators and/or implementers deploying backdoored scanners to check their devices for ShellShock.

My advice is to keep devices off of the Internet during development, make sure they’re clean, keep your dev machines up-to-date with the latest patches, don’t ship devices that rely on components that have a history of bugs (and don’t expose said component via the web!), design and utilise an update strategy – preferably one that can be automated – and don’t trust everything you read on the internet!

If you’re really concerned about security and the types of attacks faced by embedded Linux users and how they work then I heartily recommend our new Secure Linux Programming course.

 

 

Acorn Goes to Market with RISC Microprocessor

November 6th, 2014

No I’ve not lost the plot, this was actually the headline from Electronics back in August 1985!

Recently my father was clearing out his loft at home and came across a couple of bagfuls of “rubbish” (garbage) which was full of various memorabilia from my degree days.  Among the various artefacts, to my great surprise, I came across a photocopy  of this article.

For those of you, like me, who were involved in electronics at that time, it’s a real trip down memory lane. Some of the notable snippets are:

Acorn’s ARM chip (for Acorn RISC machine)…

The ARM chip packs 25,000 transistors onto a small 50-mm² chip

The chip is about twice as fast as a VAX-11/780

Limited samples of the board [containing the ARM] are available for about $2000

For all those feeling nostalgic I have attached the original article for your enjoyment.

Page 1: Arm p1

Page 2: Arm p2

However, I’m guessing there is a whole swath of you who weren’t even born; they were the days and you don’t know how lucky you are, etc. (and all the other things old people say…)

Rapid Application Development with Python

March 11th, 2014

Following on from my previous post on Python and our new course on Python for Test Engineers which takes an elementary approach, I felt it was time to pay homage to that wonderful language once again but this time focusing on its applicability for Rapid Application Development.

The Higher Level the Language; The More Productive the Programmer

I love writing Python. I’ll be honest, it’s the closest I’ll get to writing executable pseudo-code which best mirrors how my mind works and I’m sure I can’t be alone in this. When coding in Python, its dynamic nature means you can sculpt and remodel your code as you express your ideas; this process gives a better understanding of the codes impact as well as providing more accurate estimates for how long a given task will take as there are fewer unknowns in the language itself.

“But Python is for high level applications!” – sorry but the world of embedded is evolving, Embedded Linux is everywhere with its “everything is a file” interface for things that were predominantly the domain of device drivers – I can manipulate framebuffers, SPI and I2C busses and GPIO using Python and even microcontrollers, that last bastion of embedded, are getting in on the action with the recently Kickstarted Micropython which brings Python further into traditional “deeply embedded” territory.

Python as a System Programming Language

An argument I get from other developers is that Python isn’t a real systems programming language – yes, you can script in it but that’s not how “Real coders” write software. Well, when those real Scotsmen, uh, coders take time from etching ones and zeroes directly into their hard disc platters and explain what they mean it typically comes down to a misunderstanding of Pythons capabilities.

“I need threading”

Cool, we’ve got you covered but was that plain threading, process-based threading or maybe just a few recurrent timers?

“Uh, swell, but I also need IPC/Networking”

Sockets, Signals etc? Pick one, pick all of them? Maybe you just need to serialise some data?

“I also need serial comms”

OK, not built in but how about the cross-platform PySerial?

“And what about my existing programs?”

Nice, did you want to extend Python by wrapping your code in a library? Interacting with your program? Or why not embed Python into your existing program?

Python can handle all of those things with aplomb and also affords you ready-to-roll web services, file handling, parsing of data in XML/JSON form or plain text using regular expressions. Maybe you want to interact with the latest pluggable devices using PyUSB and you’ll lose track of the many ways to show a Graphical User Interface that it’s more akin to a beauty pageant.

As we move forward, multimedia is increasingly a key part in product development, many devices need to push and manipulate video and sound and once again, Python provides a huge leg up whether via simple graphics manipulation using Pillow, image processing using scikit-image or even live and post-processing of video using gstreamer or MoviePy respectively.

Mmm, a delicious cinemagraph that’s generatable in ~3 lines of Python with MoviePy

Reducing Time to Market

Time to market is the phrase that pays in the world of product development – it defines our coding deadlines, the features we can ship with and the very nature of our products and we’re always under pressure to reduce it.
Research indicates [1] that designing and writing a program in Python (or similar scripting language) typically takes half as long and requires half as much code as an equivalent C or C++ program.

Given that the number of lines we, as programmers, can write in a given time is constant and not dependent on the language or its type we can infer that with a higher level language such as Python, we get a much higher instructions-per-line metric and developers only have to spend half as long coding as our C++ wielding brethren. I can be more productive than if I was using C++ safe in the knowledge that the same task will require less code in Python.

This is how we get our minimum viable product, this is how we crush our time to market – we code smarter, not harder.

Of Data Types and Paradigms

Data types are important as they define the information we can hold in a variable. Built-in types are a godsend in Python – we have lists, dictionaries, sets and many more and we don’t need to track down and incorporate 3rd party libraries to provide neither them, nor the functions to manipulate them.

This ability to develop as you prototype means that you can develop supporting routines as you go and so to do the types of data you will need to handle which means you can pivot and rearchitect as you develop your software.

Python is a multi-paradigm language (urgh, sorry!) that allows us as programmers to use procedural, object-oriented and functional where it makes sense without shoe-horning one into the other.

One thing that has been on the increase is that Python is entering into areas traditionally aligned with domain specific tools such as Matlab and similar but as the power of Python is becoming apparent, modelling in one language and porting it to something like C is losing out to the decision to model, develop and code in just one language.

Add-on Libraries such as NumPy, SciPy and many others allow a combined model of modelling and deployment that affords huge benefits in a multi-disciplinary team as everyone speaks the same language: Python.

Good enough is good enough

Python isn’t just a prototyping language – you don’t need to throw away any of your code, companies are readily using Python for their deployed products as they evolve from RAD ideas to fully-fledged, production ready programs.

Python may not be everyone’s cup of tea and it has its limitations – it’s never going to offer the performance per watt you’d get from hand-coded assembly – but more often than not it’s good enough to get to market and, as companies are finding out, it’s good enough to keep you in the market.

Inquire today about how we can help you kick start your development process with Python.

[1] http://page.mi.fu-berlin.de/prechelt/Biblio/jccpprtTR.pdf

The Top 5 Things I’ve Learnt about Git

January 31st, 2014

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)

During the last couple of years, internally we’ve moved over to using Git as our Revision Control Old_Git_Wit___RGB___small_2System (RCS). It’s been an interesting exercise, especially where, like me, you’ve come from a traditional model (such as subversion or even back to good old SCCS). I’m sure you’ve all got your own “top 5” and I don’t necessarily expect you to agree with me, but here’s my key learning points:

#1 “Branch always, branch often”
At the outset this was certainly the biggest mindset change*. In many RCSs, branching is particularly “heavyweight” and merging branches (and branches of branches, and branches… you get the gist) can be, to say the least, challenging. So you could end up being counter-productive by trying to avoid branching unless absolutely necessary.

It couldn’t be more different using Git, and once I’d “got it”, then it is an instinct to always work on a branch. I guess it all fits in with the aim to keep work cycles too much shorter timeframes, so branching and merging must be trivial. There is an excellent tutorial to help learn branching on Git.

#2 “Don’t ignore your .gitignore
You know you’re going to need it, so do it before you start any real work. It’ll just save you a whole load of tidying up later on (ok so maybe this is an age thing? don’t procrastinate!). There are even a language specific .gitignore templates at https://github.com/github/gitignore, so no excuses.

It’s also worth getting to know the basics of the pattern matching that can be used in the .gitignore file, they’re well documented.

#3 “GitHub is not Git”
Maybe it’s my onset of senility, but initially it wasn’t exactly clear where Git ended and GitHub started. Most of the early stuff I looked at to help understand and learn Git almost always used GitHub to host your project. In hindsight it’s all obvious (well of course it’s just a web-based hosting service for software development projects that use Git), but at the time I can say my understanding was a little “fuzzy” around the edges.

Two things really helped; first the excellent book Pro Git written by Scott Chacon which you can find online at http://git-scm.com/book. I found it so useful to I also bought the eBook (Kindle) version.

Second, moving to BitBucket away from GitHub. In fact we use both, GitHub for our publicly hosted projects and BitBucket for internal work. This just made it plainly obvious where Git ended and GitHub/BitBucket started.

#4 “Quickly learn how to undo”
There are many ways to mess it up, if you really try. Committing without adding, modifying files without branching (see #1), committing unwanted files (see #2), not pushing changes (see #3) and the list goes on (and I’ve done them all).

Be assured, you can always fix it, from a simple commit-amend to, probably one of the coolest things, being able to create a branch from a stash. But I’d highly recommend spending a bit of time understanding unstaging as opposed to unmodifying a file.

Using Git is very much about understanding workflow and typically messing up means you’ve not quite got your workflow model running smoothly. The nice folks at Atlassian have put together a set of guides on workflow.

#5 “Initially do all your work on the command line”
For Linux people (and hopefully most programmers on a Mac), this doesn’t need saying as why would you do it any other way? However for all those Windows-based people (and in the embedded world this is the majority) then there is a tendency to use graphical tools. Both GitHub and BitBucket offer graphical frontends to managing Git local/remote repo’s but without understanding the underlying Git model (which you only really get from using it at the command line) then it’s easy to get lost.

I didn’t find the GitHub Windows client tool especially friendly, whereas SourceTree from Alassian I found a more intuitive client. Nevertheless I’d still rather work at the shell.

So that’s my top 5; What have I missed (remember you’ve got to drop one to add one)?

What would I do differently? certainly I’d read “Pro Git” cover-to-cover much sooner than I did. Otherwise, as usual, just throw yourself in and have a go.

Now what was that someone said about Mercurial being better…

* Actually the initial challenge was getting used to say “Git” outside of its usual context in the UK.

Style vs. Substance in C programming

June 21st, 2013

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)

In an email from UBM Tech this week there was a link to an article titled “A Simple Style for C Programming by Mansi Research“. It was actually authored back on May 2010 by Meetul Kinariwala but appeared this week under the what’s hot section, so I thought I’d take a look [advice to the reader; don’t bother].bad-clothing_16

The problem with guides like this is that style is a very subjective area (as any parent will tell you how their kids like to point out your lack of style). Programming is no exception and you could argue with C being such a compact language, it suffers more than many other languages.

One of the many good things about the MISRA-C guidelines is that it clearly separated out the issue of style vs. coding guidelines, i.e. [Guidelines for the Use of the C Language in Critical Systems, ISBN 978-1-906400-10-1, page 9]

5.2.2   Process activities expected by MISRA C
It  is  recognized  that  a  consistent  style  assists  programmers in understanding  code  written  by others. However, since style is a matter for individual organizations, MISRA C does not make any recommendations related purely to programming style. It is expected that local style guides will be developed and used as part of the software development process.

I couldn’t have put it better myself.

Clearly for larger teams a style guide is a useful and important part of the development process.

A whole host of style issues can be addressed with a “pretty printer” tool such as Artistic Style. These simply allow you to define a standard model for items such as ‘{‘ alignment, tab-to-space ratio and spacing within expressions [e.g. if (a&&b) vs. if ( a && b ), etc.].

However there are many style issues that can’t be addressed with automation, for example naming convention. People of a certain age will have been unfortunate enough to have to use Hungarian notation, which, at its roots, had a good underlying principle (embedded type information in the name). That said, Hungarian notation is, in my opinion, an abomination.

One of those coding styles that always make me want to spit feathers is putting a literal on the left of a comparison expression, e.g.
if (10 == var)
I know, you think it’s a great idea as it stops you accidentally writing:
if(var = 10)

Yes it does, but that also tells me you’re not using any form of static analysis tool (e.g. PC-lint, Coverity, QAC, etc.) which means you’ve got much bigger problems that accidentally assigning 10 to the variable!

My major issue is that, for someone who ends up reviewing a lot of other people’s code, it acts as a mental ‘speed bump‘; I wouldn’t say “if ten is equal to var?“‘ I’d say “if var is equal to 10?“, so why write it that way? Surely we want to make code a readable as possible and I’d argue (10 == var) is just ‘bad‘ style.

Probably the biggest issue I regularly come across is that most company coding standards

  • do not differentiate between rules that are there for safety/security reasons (e.g. Functions shall not call themselves, either directly or indirectly) and rule purely for style (e.g. for pointer variables place the * close to the variable name not pointer type)
  • do not have automation of rule checking; if it’s not autometed it won’t get enforced.

As I’ve already said, I’m not against coding style guidelines, quite the contrary I think, when well done, they aid code readability across a project/company. But what’s really needed is a coding meta-style guide (i.e. a guide to what a coding style guide should address).

For example, a coding style guide should consider the structure of a C file, e.g. ordering items within a file based on some defined criteria, such as:

  • Context then definition
  • External then Internal
  • Public then Private
  • Functional grouping
  • Type grouping
  • Alphabetic sorting

The meta-style-guide tells you that you should consider file structure; the actual-style guide tells you, for you project, how a C file should be structured.

Googling the web hasn’t thrown up any meta-style guides, so here at Feabhas we’re undertaking to develop an open, community driven, meta-style guide. We haven’t defined the best model yet (github, google+, etc.), but as soon as we do I’ll ensure it’s published here.

In the meantime feedback/comments on the meta-guide would be welcome.

UPDATE
I have subsequently come across the following resource that is a great meta-guide C Style: Standards and Guidelines and I highly recommend a visit.

Python – The everyman’s language

May 17th, 2013

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

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).

Problem?

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.

IDLE

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.

Summary

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

Default construction and initialisation in C++11

November 22nd, 2012

Glennan Carnie

Technical Consultant at Feabhas Ltd
Glennan is an embedded systems and software engineer with over 20 years experience, mostly in high-integrity systems for the defence and aerospace industry.

He specialises in C++, UML, software modelling, Systems Engineering and process development.

Latest posts by Glennan Carnie (see all)

Default constructors

In C++ if you don’t provide a constructor for the class the compiler provides one for you (that does nothing):

image

This, of course, isn’t very useful so typically we write our own constructors to initialise the attributes of our class.  However, as soon as you write a (non-default) constructor the compiler stops providing the default constructor:

image

The normal solution is to write our own default constructor.  In C++11 there is syntax to allow you to explicitly create the compiler-supplied constructor without having to write the definition yourself:

image

So far, this doesn’t seem to have gained us very much; if anything it feels like syntax for the sake of it.

 

Non-static member initialisation

C++ has, for some time, allowed initialisation of static member variables in the class declaration.

image

This was allowed because the static member is allocated at compile time.  C++11 has extended this notation to include non-static members as well:

image

What this syntax means is: in the absence of any other initialisation the value of data should be set to 100.  This is, in essence, a little bit of syntactic sugar around the MIL to save you having to write the following:

image

Putting it all together

Combining non-static member initialisation with default constructors allows us to write code like this:

image

There are possibly two ways to view this:  either it’s a new (and uncomfortable) syntax to learn that just adds more variety (and confusion) to the language; or that C++’s default initialisation was ‘broken’ (and we learned to compensate) and this is the syntax that should have always have been.

I Dream of a Cheeky Missile Launcher

October 12th, 2012

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[] =
{
{ USB_DEVICE(LAUNCHER_VENDOR_ID, LAUNCHER_PRODUCT_ID) },
{} /* 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
pr_debug("launcher_open\n");
/* 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;
pr_debug("launcher_close\n");
/* 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;
pr_debug("launcher_read\n");
return retval;
}

static ssize_t launcher_write(struct file *filp, const char __user *user_buf,
size_t count, loff_t *off)
{
int retval = -EFAULT;
pr_debug("launcher_write\n");
/* 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;

pr_debug("launcher_probe\n");

/* Set up our class */
class.name = 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)
{
pr_debug("launcher_disconnect\n");
/* Give back our minor. */
usb_deregister_dev(interface, &class);
}

static int __init launcher_init(void)
{
int result;
pr_debug("launcher_disconnect\n");

/* 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 */
usb_deregister(&launcher_driver);
}

module_init(launcher_init);
module_exit(launcher_exit);

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_CTRL_BUFFER_SIZE 8
#define LAUNCHER_CTRL_REQUEST_TYPE 0x21
#define LAUNCHER_CTRL_REQUEST 0x09
#define LAUNCHER_CTRL_VALUE 0x0
#define LAUNCHER_CTRL_INDEX 0x0
#define LAUNCHER_CTRL_COMMAND_PREFIX 0x02

#define LAUNCHER_STOP 0x20
#define LAUNCHER_UP 0x02
#define LAUNCHER_DOWN 0x01
#define LAUNCHER_LEFT 0x04
#define LAUNCHER_RIGHT 0x08
#define LAUNCHER_UP_LEFT (LAUNCHER_UP | LAUNCHER_LEFT)
#define LAUNCHER_DOWN_LEFT (LAUNCHER_DOWN | LAUNCHER_LEFT)
#define LAUNCHER_UP_RIGHT (LAUNCHER_UP | LAUNCHER_RIGHT)
#define LAUNCHER_DOWN_RIGHT (LAUNCHER_DOWN | LAUNCHER_RIGHT)
#define LAUNCHER_FIRE 0x10

Our USB command code takes the form of:
REQUEST_TYPE | REQUEST | VALUE | INDEX | DATA
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[0] = LAUNCHER_CTRL_COMMAND_PREFIX;
buf[1] = cmd;

/* The interrupt-in-endpoint handler also modifies dev->command. */
spin_lock(&dev->cmd_spinlock);
dev->command = cmd;
spin_unlock(&dev->cmd_spinlock);

pr_debug("Sending usb_control_message()\n");
retval = usb_control_msg(dev->udev,
usb_sndctrlpipe(dev->udev, 0),
LAUNCHER_CTRL_REQUEST,
LAUNCHER_CTRL_REQUEST_TYPE,
LAUNCHER_CTRL_VALUE,
LAUNCHER_CTRL_INDEX,
&buf,
sizeof(buf),
HZ*5);
...

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[] = {
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
...
{ USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
...

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) {
printk(KERN_WARNING
"Could not parse HID quirk module param %s\n",
quirks_param[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:
module.parameter=OPTIONS.
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 rd.md=0 rd.dm=0 rd.lvm.lv=vg_slimtop/lv_root SYSFONT=True usbhid.quirks=0x2123:0x1010:0x04 KEYTABLE=uk rd.luks=0 rd.lvm.lv=vg_slimtop/lv_swap 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

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:


KERNEL=="launcher?*",MODE="0666",GROUP="wheel"

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
/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/usbmisc/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'
ACTION=add
DEVNAME=/dev/launcher0
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/usbmisc/launcher0
MAJOR=180
MINOR=0
SUBSYSTEM=usbmisc
UDEV_LOG=6
USEC_INITIALIZED=684838211
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.

Conclusion

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 https://github.com/feabhas/dreamlauncher 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:

%d bloggers like this: