System programming for embedded Linux

The performance and stability of a system ultimately depends on how well you use the resources of the underlying operating system. This class explains how to make effective use of the facilities of the POSIX compliant Linux GNU C library when implementing embedded devices. Attendees will begin with the basics of file handling, device I/O and memory and process management. They will learn how to use signals safely, how to compartmentalize an application into multiple processes and threads and the trade-offs between various types of Inter Process Communication using sockets, message queues and shared memory.

The material and lab sessions are designed for engineers working on embedded devices, and hence there is an emphasis throughout on robust design, efficient use of resources and real-time behaviour. All lab exercises are cross-compiled and tested on a BeagleBone embedded development board.

Download course details as a PDF
Click here for information about booking a course


4 days


£1950 (excluding VAT)

Upcoming courses

None scheduled: contact us to request a quote



  • Good understanding of the C language


  • Familiarity with Linux or Unix command-line
  • Familiarity with Linux development tools such as make and gcc


Copies of the presentations and lab notes, plus sample code and worked solutions for the labs.

Hands-on labs

An essential part of the training are the lab sessions, which take approximately 50% of the time. We normally work in pairs using a modern development board such as the Beaglebone. Each group will also need a laptop or desktop to run the system development tools. We will provide a bootable USB memory stick with an appropriate version of Linux and cross tool-chain so there is no need to install Linux beforehand.


Developing for embedded Linux

  • The tool-chain: choosing, installing and testing
  • Application program interfaces: the POSIX standard
  • Open source licenses: GPL/LGPL, BSD, etc


  • Debugging a remote target device using gdb and gdbserver

Files and devices

  • Files and file-related API: waiting for several things to happen with select() and poll()
  • Devices: everything is a file. Interfacing with a simple device driver. Using the ioctl() function to access device-specific operations


  • Process life cycle: fork(), exit() and exec()
  • Scheduling: real-time and non-real-time policies; setting priority and niceness


  • Virtual memory and its consequences
  • Allocating from the heap and stack
  • Mapping memory using mmap


  • Standard and real-time signals
  • Writing robust signal handlers
  • Signal masks and how to handle signals synchronously

Real-time Linux kernels

  • Kernel preemption
  • The real-time PREEMPT_RT patch

Inter-process communication

  • Pipes
  • Shared memory and semaphores
  • Message queues
  • Sockets: internet and UNIX (local). Stream and datagram connections

POSIX Threads

  • Thread life cycle: pthread_create(), pthread_exit(), pthread_join()
  • Scheduling threads: real-time and non-real-time
  • The thread stack and how to set the stack size

Thread synchronisation

  • Synchronisation using mutexes; priority inversion and priority inheritance
  • Condition variables: producer and consumer threads
  • Thread cancellation and clean-up operators

Time and timers

  • Timer accuracy: high-resolution timers, POSIX clocks and timers
  • Measuring time
  • Periodic tasks