The most exciting thing about this world is its ever changing quality.

Wednesday, May 20, 2009

Mockup short survey

If you are a completely stranger to mock object concept, wiki page is a good start! When and how to use mock object is as much a coding issue as a design choice. Things will get more tricky when the interdependence's among various components and third party APIs where the visibility is usually not ideal. You may also want to make sure the mock object can be easily replaced later stage by the real implementation. There is a general mix up that test framework is equivalent to mock objects, or offers mock up facilities. First thing is that is so not true although you might naturally decide to test your production code by creating some mock ups when those implementations from the other lazy boy do not turn up on time. In this sense, mock objects could be part of test harness definition. I have always believed that we should separate the mock object themselves from test framework as much as possible. Otherwise, you will be in the middle of confusions between test logic, mockup logic and production code fairy easily.
 
Here, I will only go through a few off-the-shelf mock object packages for different languages. 

C++: Googlemock, Not surprisingly, I typed "GMock" in google when I started this blog. As I thought it is safely to assume that there is nothing those people do not do. After some internal tips, Goolgemock eventually joined my starred projects. Googlemock is quite tightly bound with Googletest which I talked a bit in previous blog. Although in the latest release, it seems to break this dependency. Googlemock is pretty much based on expectation model by setting up the expected call results and validating later in the logic code. Just as a comparison, Mockcpp is a typical recall&replay model implementation. the reason I am not a particular fan of Mockcpp is that it confuses itself what it is from start, a test framework or mock objects package, or both?

C#: Rhino mocks originates from EasyMock.Net which was a pure recall&replay mocking model. Rhino mocks integrates the RR model with expectation model which NMock heavily relies on. One plus for me is that Rhino mocks seems to be quite independent to any test framework while NMock is normally used together with NUnit test framework. There is a simple comparison for some of the popular mock up schemes in .Net.

C: It is not that straight forward to adopt this concept to traditional C world and embedded system development. The group in Atomic object has definitely made some marks here by introducing Unity (an embedded unit test framework for C) and CMock to the embedded world, and also nice Eclipse plugins to make people like me life easier. So Kudos to Atomic!

Thursday, May 14, 2009

Linux real time kernel scheduling

While I am working on a real time design on TCP/IP protocol stack, I have the chance to clear the thread of real time scheduling capability on Linux 2.6 kernel and its variants. With O(1) scheduling and real time priority (0 - 99) task and scheduling policy support, standard Linux 2.6 kernel offers soft real time scheduling capability. The defer of the bottom half of interrupt also minimises the interference (delay) to scheduler via softirq and tasklet. I really like the double priority list (active and expired) design in the runqueue where the O(1) scheduling comes from and time slicing calculation, independent to the number of process in the run queue (and wait queue).


There is a hardcore test to prove Ingo's contribution. There are many detailed analysis of Real time Linux patch. This patch is maintained by Ingo Molnar, who is responsible for many other nice features in 2.6 kernel including O(1) priority and time slice calculation, CFS scheduler etc. In a nutshell, RT patch implemented both hard and soft interrupt service function as tasks. Hence instead of running in separate interrupt context, they will be running in kernel task context. RT patch also changed the spinlock from disabling preemption to mutex and introduce localised critical section. Priority inheritance is used to resolve the typical priority inversion problem. Again, this patch is known providing soft real time scheduling, with the best efforts.

RTAI:

RTAI (Real-Time Application Interface) is a real-time extension for the Linux kernel. It supports several architectures:
  • x86 (with and without FPU and TSC)
  • x86-64
  • PowerPC
  • ARM (StrongARM; ARM7: clps711x-family, Cirrus Logic EP7xxx, CS89712, PXA25x)
  • MIPS
RTAI provides deterministic response to interrupts, POSIX compliant and native RTAI real-time tasks. It consists mainly of two parts:
  • An Adeos-based patch to the Linux kernel which introduces a HAL (hardware abstraction layer)
  • A broad variety of services which make real-time programmers' lives easier. RTAI does provide implementations for scheduling policies as RMS, and EDF other than the standard ones offered by Linux 2.6 kernel such as SCHED_FIFO, SCHED_RR, SCHED_OTHER (where dynamic priority scheduling is enabled). SCHED_FIFO and SCHED_RR are normally used for real time tasks which are both static priority scheduling and both do not allow lower priority tasks to preempt higher priority ones, even when allocated time slices are exhausted (in SCHED_RR case). RTAI has a finer timer and also introduces a real time (non-blocking) FIFO for deterministic data transfer between tasks. The heart of RTAI implementation is the HAL layer between Linux kernel and different hardware, which makes this layer very much platform-dependent. The other arguable feature introduced by RTAI is allowing user space tasks to be scheduled via LXRT interface to achieve hard real time performance. It was reported that RTAI is integrated most desirable with Vanilla kernel (2.6.19).
  • Here is a good example project to start from. If you wish to carry out a quantative comparison of how much boost RTAI brings to you, this post gives a few bench mark measurements. Just in case, I put the installation guide here as well. To port your existing Linux programs to take advantage of RTAI, you might want to start from LXRT APIs. At last, if you want a quick summary to take away, here is your PPT. With a worse case report at 48 us scheduling latency and jitter in the range of 10's microseconds on its LXRT branch, RTAI is my favorite.
Xenomai:
Originally from RTAI/fusion branch, Xenomai focuses on extensibility, portability, and maintainability while RTAI is focused on performance such as real time scheduling, latencies, etc. A good comparison article could be found here.

Supported architectures are:
  • x86: from i386 to latest Pentiums and AMD's, UP and SMP
  • x86_64
  • PowercPC (follows DENX tree):
  • Freescale family: PowerQUICC I, PowerQUICC II, PowerQUICC III, ..
  • AMCC family: 405, 440, ..
  • PowercPC 64 (follows DENX tree):
  • PA6T
  • IA64 (discontinued since v2.5)
  • ARM cores:
  • Integrator/CP ARM 1136
  • PXA
  • SA1100-based
  • Freescale iMX21/csb535fs
  • Atmel at91rm9200 (tested on CSB637)
  • Samsung S3C24xx
  • Intel ixp4xx
  • Atmel at91sam926x
  • Motorola i.MX family
  • Analog Devices Blackfin BF52x, BF53x, BF54x and BF56x
I do like the robot project from Hannover. A good serial port driver comparison between RTAI and Xenomai is available on Capitain. The other major focus of the Xenomai project is to help creating emulators of traditional RTOS APIs that ease the migration from these systems to a GNU/Linux-based real-time environment. As of now, the following real-time interfaces
are available:
  • pSOS+ emulator
  • VRTXsa emulator
  • VxWorks emulator
  • uITRON implementation
I could really see Xenomai playing an interesting role in the real time virtulisation applications rather than providing powerful generic emulation interfaces for multiple RTOSes. Minute virtual machine in Xenomai comes with a graphical debugger named Xenoscope that allows tracing the execution of real-time software at source code level in a simulated environment. This tool shows precisely how the multiple threads running in the system work together sharing the resources of a given real-time interface (e.g. who is locking a semaphore, which thread has been readied or suspended by a given system call, and so on).

-------------------------
- Real time application  -
-------------------------
-     RTOS emulators     -
-------------------------
-  Xenomai nanokernel  -
-------------------------
-   Host software arch    -
-      (e.g. RTAI-x86)      -
-------------------------

RTLinux (To be updated)

Monday, May 11, 2009

Mysterious network interface

Any types of Linux network interface drivers will initialise an instance of net_device data structure. Here is a very concise summary of what is happening between NIC hardware and before IP Protocol stack is invoked.

Packet reception:
DMA packet memory copy is completed -> NIC hardware interrupt ISR is invoked -> Receive interrupt detected -> gather the buffer containing raw packet into a socket buffer (avoid coping: we can set up socket buffer to point directly at DMA space.) -> place packet onto queue (by protocol input function) -> Queuing layer kicks in -> softIRQ threads to process the scheduled interface

Packet transmission:
(Based on registered queuing discipline and scheduler) Queuing layer (dev_queue_xmit) invokes Hard_start_xmit -> Hard_start_xmit checks hardware buffer -> Hard_start_xmit puts socket buffer in driver's local queue and enable the Transmit Interrupt

Status notifier chain: This is really just a linkedlist of functions to be called on event for notification, nice and simple (to my like). Registering is actually appending callback function point to the list in this case. netdev_chain is the implementation for NIC.

As a bonus for whoever is reading this, the following are comments for in the include/linux/netdevice.h
/*
 * The DEVICE structure.
 * Actually, this whole structure is a big mistake.  It mixes I/O
 * data with strictly "high-level" data, and it has to know about
 * almost every data structure used in the INET module.
 *
 * FIXME: cleanup struct net_device such that network protocol info
 * moves out.
 */
struct net_device {...}

Saturday, May 09, 2009

What went wrong

2 years exactly, since I joined CD. Boy, it was not easy for me to make up my mind to leave, even though it is crystal clear to me now that the right choice is made.

What went wrong then? Well, maybe nothing has to be wrong for anyone to move on. This is probably the case for me. Retrospectively speaking, I have had to take many extreme steps to make things happen in a very much traditional business, structure-wise and culture-wise, which is obviously conflicting with the product and technology the business was setup to achieve, unfortunately. Do I regret what I have done? No, not a second. I have done what it takes to make improvement in many dead corners, and get things done. Sometime I think myself more of a doer rather than a speaker. However, there are things I could have done, more at least...

Two things learnt, know when to play dumb and conscious effort. Knowing when to ask the right questions, when to build a escalator to encourage others to climb up and realise, able to face and tackle their own ambiguious areas, will actually go a longer way than fighting through alone. A successful leader should not only be able to visage and direct the way, more importantly, to carry people with you.

I am not a huge fan of spiritual walk or meditation as such, but Dona's conscious self has given a quite concise definition as what it takes to make conscious efforts. Here goes:

"Effort is work directed toward a specific goal. The word effort implies trying. With effort, there is something you want to achieve. ... Conscious effort is that action which is chosen, that effort which chooses action other than that determined by unconscious forces, habitual reaction. "