Posts Tagged ‘rtos’

New Mobile Phone OS Market Share Data

Thursday, March 26th, 2009 Michael Barr

Fast Company magazine yesterday reported the latest statistics on mobile web browsing. Not surprisingly, people with iPhones are the dominant users of mobile Internet.

Included in the article are statistics about the market for mobile phone operating systems. The shakeup in the OS market share mix over the past six months (August 2008 to February 2009) are nothing short of astonishing:

  • iPhone up from 10% to 50%
  • RIM down from 32% to 21%
  • Windows Mobile down from 30% to 13%
  • Palm down from 19% to 7%
  • Android up from 0% to 5%

Clearly, Windows Mobile and Palm OS are really taking it on the chin from iPhone and Android.

Now if Apple could just get their task priorities right so I could listen to music without hiccups while browsing…

RTOS Myth #5: You Need One

Monday, February 23rd, 2009 Michael Barr

The Myth: You need a real-time operating system (RTOS) to make your embedded software easy to implement and maintain.

The Truth: Three positive implications of the use of a preemptive priority-based RTOS must be weighed against ten negative implications. An RTOS works well in some scenarios, but overly complicates the design of many other systems.

Annual surveys of the readers of EETimes and Embedded Systems Design generally find that about half (50%) of embedded software developers work on projects that utilize a commercial RTOS, such as VxWorks or uC/OS-II. Due to a sampling bias stemming from the correlation between big teams and RTOS use, the number of new products containing an RTOS is likely much lower than 50%.

Contrary to popular belief, a real-time operating system (RTOS) is not the answer to all of your design problems. When chosen for the wrong reasons, the presence an RTOS can make the firmware design more complicated rather than less. In addition, preemption increases the opportunity for race condition and non-reentrancy bugs. Finally, the inclusion of an RTOS has other costs, such as additional RAM and ROM/Flash.

By my calculations, preemption has three principal positive implications and ten negative implications. For example, one positive is that an RTOS can help separate the timing (i.e., which code is running on the CPU when?) from the application-level algorithmics. The problem is decomposed into a less “fragile”/more maintainable firmware design.

However, the use of separately-coded parallel tasks also complicates the software. Without the RTOS, the only possible race conditions occur between communicating interrupt service routines and the background loop in main(). Additional tasks increase the need for communication and synchronization factorially.

Perhaps the most interesting tradeoff concerns responsiveness to interrupts. Although what an RTOS does is to divide up the spare CPU time not used by any interrupt service routine (ISR) between pseudo-parallel running tasks (i.e., a set of C functions that don’t return), one negative side effect is slower CPU response to interrupts. The interrupt latency is higher with an RTOS than without.

Don’t get me wrong, sometimes an RTOS is a valuable tool. But don’t go using one simply to put its name on your resume. You may instead find yourself languishing in an overly-complicated and buggy embedded software design at your present job.

The “RTOS Alternatives” course by Netrino Institute includes full coverage of these tradeoffs, including details of each of preemptions three positives and all ten of the negative implications of a commercial RTOS.

Go back to RTOS Myth #4.

RTOS Myth #4: The RTOS is in Charge

Friday, June 6th, 2008 Michael Barr

The Myth: The operating system is in charge and it decides when to switch from one application task to another.

The Truth: A real-time operating system (RTOS) is a very different beast than a multi-user desktop operating system, such as Linux. In fact, an RTOS is simply a library of functions plus a timer tick interrupt handler.

The only opportunities for an RTOS to effect a context switch from one task to another are:

1. If a running task deletes itself (or exits, if your OS allows that). In this case, a function in the RTOS library detects the lack of a running task and can directly invoke the scheduler function to select the next task to run.

2. When a running task blocks, which can only happen by making a function call into the RTOS library.

3. If a running task creates a new task with a priority higher than it’s own.

4. When a previously blocked task of higher priority is unblocked, which could happen as a result of:

a. The running task made a function call into the RTOS library (e.g., semaphore post).

b. An interrupt service routine executed with that side effect.

These four (or, five, if you prefer) points of entry into the RTOS are the only mechanisms by which control of the CPU can be transferred from one task to another. They are called “scheduling points”.

The implication here is that your application code is actually in charge. If it were to avoid calling into the RTOS library while simultaneously disabling interrupts, the running task could steal control of the CPU for any length of time.

Go back to RTOS Myth #3 or forward to RTOS Myth #5.

Toward a Better Mutex API

Wednesday, March 19th, 2008 Michael Barr

A few months ago I blogged that mutexes and semaphores are distinct RTOS primitives. Unfortunately, the APIs of today’s most popular commercial RTOSes only add to the confusion for application programmers.

For example, consider the VxWorks API, which not only forces mutexes and semaphores into an inappropriately common-looking API (semMXxx vs. semCXxx) but also adds a third “binary semaphore” type (semBxxx). Micrium’s popular uC/OS-II API is preferable to this in that it at least has just two primitive types (OSMutexXxx and OSSemXxx). But the uC/OS-II API also forces programmers to use similar function name suffices–Post() and Pend()–with each.

I propose a new and clearer API such as the following, which is based loosely on uC/OS-II’s current API:


int OSSemCreate(SEM * phSem, int cnt)
int OSSemPost(SEM hSem)
int OSSemPend(SEM hSem, int timeout)

int OSMutexCreate(MUTEX * phMutex)
int OSMutexGet(MUTEX hMutex)
int OSMutexPut(MUTEX hMutex)

Wind River would do well to eliminate semBxxx functions and rename the semCXxx functions as semXxx. In addition, the VxWorks API for mutexes should be changed to something like mutexXxx.

Note, too, that this new API is intended to force each mutex object to be created in the ‘available’ state (i.e., value = 1), as it already is in uC/OS-II. An additional feature of the mutex API should be that any OSMutexPut() call by a task that does not currently own that mutex should fail with an appropriate error code. Together these easily used mutex functions ensure correct usage of mutexes by application developers.

RTOS Myth #3: Mutexes are Needed at the Task Level

Wednesday, March 12th, 2008 Michael Barr

The Myth: Mutexes are a useful intertask synchronization primitive, which you should expect to use frequently.

The Truth: Mutexes are a necessary feature of all real-time operating systems. However, best practice is to use them only inside functions that must be reentrant. That is, you should use mutexes only inside functions that are or could be called by two or more tasks.

Mutexes, as their name suggests, enforce mutual exclusion and thus eliminate race conditions between tasks. A mutex can be used to protect a global data structure accessed by two or more tasks. However, doing this properly requires that each user task have the actual address of the global data and allows for bugs in the failure of one task to acquire and release the associated mutex properly.

It is preferable always to abstract or encapsulate said global data structure as an object, which can only be read or written through a set of reentrant function calls. That way, both the address (and possibly internal format) of the data structure can be hidden and the mutex calls can be ensured to be coded correctly.

Note that mutexes are also necessary inside functions that control hardware through I/O registers, which are effectively global data structures.

Of course, a priority inheritance capability should be present within the mutex API (put there by the RTOS vendor) to ensure that priority inversions cannot occur.

Go back to RTOS Myth #2 or forward to RTOS Myth #4.