MicroC/OS-II

Jean J. Labrosse

Mentioned 9

This updated edition describes the design and implementation of the MicroC/OS-II real-time operating system and offers an extremely detailed and highly readable design study useful to students.

More on Amazon.com

Mentioned in questions and answers.

One thing I've always wanted to do is develop my very own operating system (not necessarily fancy like Linux or Windows, but better than a simple boot loader which I've already done).

I'm having a hard time finding resources/guides that take you past writing a simple "Hello World" OS.

I know lots of people will probably recommend I look at Linux or BSD; but the code base for systems like that is (presumably) so big that I wouldn't know where to start.

Any suggestions?

Update: To make it easier for people who land on this post through Google here are some OS development resources:

Other resources:

I found a nice resource named MikeOS, "MikeOS is a learning tool to demonstrate how simple OSes work. It uses 16-bit real mode for BIOS access, so that it doesn't need complex drivers"

Updated 11/14/08

I found some resources at Freebyte's Guide to...Free and non-free Operating Systems that links to kits such as OSKit and ExOS library. These seem super useful in getting started in OS development.

Updated 2/23/09

Ric Tokyo recommended nanoos in this question. Nanoos is an OS written in C++.

Updated 3/9/09

Dinah provided some useful Stack Overflow discussion of aspiring OS developers: Roadblocks in creating a custom operating system discusses what pitfalls you might encounter while developing an OS and OS Development is a more general discussion.

Updated 7/9/09

LB provided a link to the Pintos Project, an education OS designed for students learning OS development.

Updated 7/27/09 (Still going strong!)

I stumbled upon an online OS course from Berkley featuring 23 lectures.

TomOS is a fork of MikeOS that includes a little memory manager and mouse support. As MikeOS, it is designed to be an educational project. It is written in NASM assembler.

Updated 8/4/09

I found the slides and other materials to go along with the online Berkeley lectures listed above.

Updated 8/23/09

All questions tagged osdev on stackoverflow

OS/161 is an academic OS written in c that runs on a simulated hardware. This OS is similar in Nachos. Thanks Novelocrat!

tangurena recommends http://en.wikipedia.org/wiki/MicroC/OS-II, an OS designed for embedded systems. There is a companion book as well.

Linux Kernel Development by Robert Love is suggested by Anders. It is a "widely acclaimed insider's look at the Linux kernel."

Updated 9/18/2009

Thanks Tim S. Van Haren for telling us about Cosmos, an OS written entirely in c#.

tgiphil tells us about Managed Operating System Alliance (MOSA) Framework, "a set of tools, specifications and source code to foster development of managed operating systems based on the Common Intermediate Language."

Update 9/24/2009

Steve found a couple resources for development on windows using Visual Studio, check out BrokenThorn's guide setup with VS 2005 or OSDev's VS Section.

Updated 9/5/2012

kerneltrap.org is no longer available. The linux kernel v0.01 is available from kernel.org

Updated 12/21/2012 A basic OS development tutorial designed to be a semester's project. It guides you through to build an OS with basic components. Very good start for beginners. Related paper. Thanks Srujan!

Updated 11/15/2013

Writing a Simple Operating System From Scratch. Thanks James Moore!

Updated 12/8/2013

How to make a computer operating system Thanks ddtoni!

Updated 3/18/2014

ToAruOS an OS built mostly from scratch, including GUI

Updated Sept 12 2016

Writing your own Toy Operating System

Updated Dec 10 2016

Writing a Simple Operating System —from Scratch (thank you @Tyler C)

There are a lot of links after this brief overview of what is involved in writing an OS for the X86 platform.

The link that appears to be most promising (www.nondot.org/sabre/os/articles) is no longer available, so you'll need to poke through the Archive.org version to read it.

At the end of the day the bootloader takes the machine code of the kernel, puts it in memory, and jumps to it. You can put any machine code in the kernel that you want, but most C programs expect an OS so you'll need to tell your compiler that it won't have all that, or the bootloader has to create some of it.

The kernel then does all the heavy lifting, and I suspect it's the example kernel you want. But there's a long way to go between having a kernel that says, "Hello world" to having a kernel that loads a command interpretor, provides disk services, and loads and manages programs.

You might want to consider subscribing to ACM to get access to their older literature - there are lots of articles in the late 80's and early 90's in early computing magazines about how to create alternative OSs. There are likely books that are out of print from this era as well. You might be able to get the same information for free by looking up the indexes of those magazines (which are available on that site - click "index" near the magazine name) and then asking around for people with a copy.

Lastly, I know that usenet is dead (for so sayeth the prophets of internet doom) but you'll find that many of the craggy old experts from that era still live there. You should search google groups (they have dejanews's old repository) and I expect you'll find many people asking the same questions a decade or 1.5 ago that you're asking now. You may even run across Linus Torvalds' many queries for help as he was developing linux originally. If searches don't bring anything up, ask in the appropriate newsgroup (probably starts with comp.arch, but search for ones with OS in the name).

Minix is a lot smaller, and designed for learning purposes, and the book to go with it is a good one too.

Update: I guess Minix 3 is a bit of a different goal, but Minix 2 (and of course the first version) were for teaching purposes.

I mean how and why are realtime OSes able to meet deadlines without ever missing them? Or is this just a myth (that they do not miss deadlines)? How are they different from any regular OS and what prevents a regular OS from being an RTOS?

You might find it helpful to read the source of a typical RTOS. There are several open-source examples out there, and the following yielded links in a little bit of quick searching:

A commercial RTOS that is well documented, available in source code form, and easy to work with is µC/OS-II. It has a very permissive license for educational use, and (a mildly out of date version of) its source can be had bound into a book describing its theory of operation using the actual implementation as example code. The book is MicroC OS II: The Real Time Kernel by Jean Labrosse.

I have used µC/OS-II in several projects over the years, and can recommend it.

I'm writing C code for an embedded system (dsPIC33 platform), and I'm considering building up a reusable code library to use among multiple projects.

What are the best practices for tying the library to each project?

Obviously the library will have some hardware-specific (and thus project-specific) dependencies, so it's reasonable to assume that it will be compiled with each project (instead of linked in binary form).

What I've come up with so far is to keep the library centrally located, but require a project-specific libraryConfig.h that includes function definitions, macros, etc. This requires that the library include the header in its own code, which means that the project source directory will need to be in the include path (not just the library source directory). That kind of messes up the distinction between #include "" and #include <>, doesn't it?

Is this how it's done normally?

A very good question and the answer isn't simple. Several things to consider. Here are a few opinions from my experience so far.

Common Code vs Project-Local Copy

One important decision is whether to use "common" library code that is updated automatically from a central location (your company's "reuse library"), or whether to keep a project-local copy.

This is discussed in detail in this SO question.

The benefit of a central library is that work done once can benefit many projects. The difficulty with a project-local copy is that any bug fixes and improvements aren't contributed back to the central library, and any bug fixes in the central library may not be brought into your project.

But a potential difficulty with using a central library is if people on their particular modify it in an uncontrolled way to suit their project, and it unintentionally breaks other projects. I've seen that personally, in "common" code that became full of #ifdefs and regularly broke other projects.

To get good value out of common code aka central reuse library:

The library:

  • must have well-defined requirements, API, and unit tests
  • must avoid project-specific code; it should be general-purpose
  • should have a mechanism for cleanly setting project-specific settings (this can be seen as part of the API, effectively)
  • must have a formal release process, with version numbers and fixes, issues must be tracked.

Individual projects:

  • shouldn't automatically and blindly get "the latest", but should be able to get a particular "release" with a specified version number. Then projects should have control over if/when they update to a newer version. The project should be able to clearly track, "we are using version 1.2.3 of library xyz".
  • should avoid "forking" the library code if at all possible. E.g. avoid adding project-specific "features" to the library code.
  • should track any local modifications to the library code
  • should regard bugs as library bugs, to be fixed in the central library if at all possible. The company should have processes to fix them in the central library, test the library with its own unit test suite (probably improving the unit tests to catch the bug in future). Then release a new version of the central library as needed, and deploy to other projects if/when those projects see fit.

If a company doesn't have such a process in place, then a project should just make a local copy of a piece of code (say, copied from a previous project) and then take full project-local responsibility from then on. You're still getting some benefit from reuse in that situation, because you're not rewriting it from scratch.

Project-Specific Configuration

If the code needs project-specific configuration, ideally that should be kept to as small a part of the code as possible--not scattered through a bunch of source files. Ideally, a single header file. But quite possibly a .C file as well (say, if you need to define some look-up tables). The library should provide a template, with the options well-commented.

For a good example of how this can be done, see the µC/OS-II RTOS (book) by Jean Labrosse, from Micrium.

I have to choose a thesis topic soon and I was considering implementing an operating system for an architecture that is not x86 (I'm leaning towards ARM or AVR). The reason I am avoiding x86 is because I would like to gain some experience with embedded platforms and I (possibly incorrectly) believe that the task may be easier when carried out on a smaller scale. Does anyone have any pointers to websites or resources where there are some examples of this. I have read through most if not all of the OSDev questions on stack overflow, and I am also aware of AvrFreaks and OSDev. Additionally if anyone has had experience in this area and wanted to offer some advice in regards to approach or platform it would be much appreciated.

Thanks

Seems like you should get a copy of Jean Labrosse's book MicroC/OS.

It looks like he may have just updated it too.

http://micrium.com/page/press_room/news/id:40

http://micrium.com/page/home

This is a well documented book describing the inner workings of an RTOS written in C and ported to many embedded processors. You could also run it on a x86, and then cross compile to another processor.

If you choose ARM, pick up a copy of the ARM System Developer's Guide (Sloss, Symes, Wright). Link to Amazon

Chapter 11 discusses the implementation of a simple embedded operating system, with great explanations and sample code.

I have worked extensively on AVR microcontrollers. I haven't had a proper OS course at UNI..not from a CS branch, but I want a book that gives me generic OS concepts as well as RTOS concepts for embedded systems. Any suggestion?. Something that details a particular OS like TinyOS or FemtoOS would be nice, but I want something with API based examples/codes as well.

Any suggestions ?

At least 3 (well, 4) books come to mind immediately:

We're students developing a mid-size (~ 4.5 feet tall) humanoid robot as a sponsored research project in college. The major tasks that the robot should be able to perform include: moving around (forward, backward, sideways), running, picking up objects. We're considering using a hard real-time operating system to control the robot. However, since we're new to this field with practically no background in embedded systems or operating systems, and there are a wide range of options available, we're not sure which one would be a suitable choice. We've come across the following (in brackets is our current impression of them):

  1. RTLinux (now dead, kernel 2.4.x, gcc 2.95 (so difficult to build), little to no documentation)
  2. FreeRTOS (good community and documentation, popular, ported to many architectures)
  3. uc-OS II (small, clean core, light-weight)
  4. RTAI (Linux-based)

I have a number of questions:

  1. Which of the options would be better suited for this project? I know this sounds a little subjective, but any advice would be greatly appreciated. If you feel some important information is missing, please do point that out.
  2. I've come across something called the CONFIG_PREEMPT_RT patch for the Linux kernel, which grants hard real-time capabilities to the kernel. There are also pre-compiled kernels with this patch available for Debian-based distributions. Would that alone be sufficient for our requirements?
  3. We have very little knowledge of operating systems in general. Is it necessary for us to learn about them first? If yes, what is a good, short primer to the subject?

UPDATE: Thank you for your incredibly detailed answers. It's clear that we're going about this the wrong way; diving in with no knowledge and vauge requirements certainly would be bad. We'll have to sit down and chalk out exactly what we need. As and when we're sufficiently ahead with that, we'll try to figure out a suitable OS. Let's see how that works out. I'm also going to read Chapter 2 of MicroC OS II: The Real Time Kernel.

Your choice of OS is unlikly to be determined by the "humanoid robot" constraint, there is no specific "humanoid robot OS", and certainly no OS would be determined by how tall such a robot is! ;-) ! The critical factors are

Other factors may be important such as:

  • Communications and I/O requirements (e.g Ethernet, TCP/IP, USB, WiFi).
  • File system support

although these need not necessarily be an intrinsic part of the OS in all cases, since third-party platform independent libraries are available in many cases, but where you need them, integration with the OS can be helpful since it avoids you having to deal with thread-safety and resource locking yourself.

Neither of the options you have suggested would likely make into my list.

Anything Linux based will require an MMU (unless using uCLinux or its derivitives, but MMU support is one of the few good reasons for using Linux in an embedded system). Linux is not intended to be a real-time OS and any real-time support it has is pretty much an after-thought, and will seldom be as deterministic as a true RTOS. Any Linux will also require significant memory resources just to boot-up, expect a minimum of 4Mb of RAM for anything usable, while RTOS kernels such as FreeRTOS and uC/OS-II require only about 4Kb - you are comparing chalk with cheese here. That said they do not have the utility of a Linux based OS such as file-systems, or networking support (although those can be added as stand-alone libraries).

If you are going to be performing the motion-control and sensor/actuator functions on the same processor as your cognitive functions, then you certainly need a deterministic RTOS. If however the platform will be a distributed system with separate processors dealing with motion-control and other real-time sensor/actuator I/O, then you may get away with a simple RTOS kernel or no OS at all in the I/O processors (which can also then be smaller, less powerful processors) and a GPOS in the cognitive (decision making and planning) processor.

I have evaluated FreeRTOS recently, it is minimalistic, simple and small, providing only the basic threading, timing and IPC mechanisms and little else. It works, but so do many other more attractive options, both commercial and non-commercial. I compared it with Keil's RTX kernel (included with their MDK-ARM tool suite), and the commercial Segger embOS. It has significantly slower context switching time that the other two candidates (though still in the microseconds on a 72MHz Cortex-M3, and faster than anything you are likely to achieve with Linux).

uC/OS-II is well designed and documented (in Jean Labrosse's book), and is great if you aim were to see how an RTOS works. Its biggest failing is its very restrictive priority scheduling scheme, which is efficient for very small targets, but possibly not as flexible as you might like. Each thread must be assigned a distinct priority level so it has no support for round-robin scheduling, useful for non-real-time background tasks. uC/OS-III fixes that shortcoming, but again so do many other options.

If your target processor has an MMU I strongly suggest the use of an OS that supports it in such a way that each thread or process is protected from any other, the system will be far more robust and easy to debug, especially when developed as a team. In such an OS an errant task that would otherwise stomp on some other thread's resources with non-deterministic and generally hard to debug results, will instead cause an exception and halt right where the error occurred, rather than perhaps sometime later when the corrupted data gets used.

You probably need not restrict yourself to a free or open-source RTOS, many vendors allow free use for education and evaluation. I would strongly suggest that you consider QNX Neutrino, it is free for non-commercial and academic use, and has the most robust intrinsic MMU support available in any RTOS, and all the development tools you need including the Eclipse based Momentics IDE are included. It is more than just a mere scheduling kernel, including support for all the services you would expect of a complete OS. It runs on ARM, x86, SH-4 PowerPC and MIPS architectures. Running on x86 is particularly useful since it means you can test and evaluate it, and even develop much of your code in a VM running on your desktop.

Another alternative that is true hard-real-time, while supporting OS services beyond mere scheduling and IPC, is eCos. It has a native, POSIX and uITRON API, standard drivers for CAN, ADC, SPI, I2C, FLASH, PCI, Serial, Filesystems, USB and PCI and more, and includes TCP/IP networking support. It is a complete OS in that sense, but unlike Linux is not monolithic; it is scalable and statically linked to your application code, so that features you do not use are simply not included in the runtime binary. It runs on ARM, CalmRISC, Cortex-M, FR-V, FR30, H8, IA32, 68K/ColdFire, Matsushita AM3x, MIPS, NEC V8xx, PowerPC, SPARC, and SuperH. Again in theory you could run the IA32 (x86) port it on a VM on a PC for test and development of high level code, though you'd have to get that working yourself unlike QNX's out of the box evaluation.

Added regarding:

We have very little knowledge of operating systems in general. Is it necessary for us to learn about them first? If yes, what is a good, short primer to the subject?

This then is perhaps not the time to start learning Linux (although it has the advantages of wide familiarity and community support, it has a lot of stuff you will not need, and a lot of available support resources will not be familiar with real-time control systems applications.

Chapter 2 of Labrosse's uC/OS-II book gives a general overview of RTOS concepts such as scheduling, synchronisation and IPC that are applicable to most RTOS not just uC/OS-II. Similar material is presented in Jack Ganssle's recent RTOS Fundamentals course on EETimes (it is similar perhaps because it is sponsored by Mircium and uses uC/OS-II as a case study, but it is similarly general for the most part).

My solution to getting a quick start in any subject is to Google the subject with "101" after it (a common introductory course number in academia). "RTOS 101" will get you some starting points of admittedly varying quality - check the reputability of the source, if it is a company, they may be peddling a specific product, if it is a hobbyist, they may have some insights, but perhaps a narrow view (often relating to specific favourite hardware), and may not have the rigour of an academic paper.

Added regarding CONFIG_PREMPT_RT:

It does not render Linux a hard real-time OS. It may be suitable for some applications. If you are doing PID motion control (rather than using a dedicated controller or separate processor), or any kind of closed loop feedback control for that matter, this patch will not enable it in my opinion, at least not reliably. I found this: A comparison of real-time Linux approaches. It discusses a number of approaches to using Linux in real-time applications, including CONFIG_PREMPT_RT. It discusses these in detail in part C.

I have been working as an embedded software engineer on mostly 8 bit micro-controller firmware and desktop/mobile applications development for the past five years.

My work on a WinCE project (in which I got introduced to .NET CF) was short lived. I did use core APIs for interrupt processing, peripheral communication, etc...but again, not exactly a pure RTOS environment. In order to get together more solid experience for growing more in the embedded field, I want to work more with RTOSes.

Will buying an evaluation board with an RTOS and putting together a project at home be regarded as a good experience or will an online course be more useful? I am just not clear as to what will be regarded as good experience. Any suggestions or directions will greatly help me. I have a passion for the field but just a need a point in the right direction.

Thanks for any help in advance.

Regards,

Subbu

I would suggest looking at either:

  • FreeRTOS - an increasingly widely used open source RTOS with plenty of documentation on its own website. There are commercially supported versions (SafeRTOS and OpenRTOS) too.

  • Micro C/OS-II, either via Jean Labrosse's book, or the evaluation (or both of course). The book's second chapter is a good general overview of a typical RTOS, the bulk of it describes the kernel in detail, and is less important if RTOS usage rather than implementation is your goal.

  • eCos; an extensive and scalable RTOS including capabilities extending beyond mere kernel scheduling and IPC. The one book on the subject does little more than collect information that is available elsewhere, such as that provided in the previous link.

For simple projects that just need a kernel, I would suggest FreeRTOS for cost, functionality, and support. For more sophisticated boards with networking, filesystems, USB, etc., where perhaps a heavyweight OS such as Linux does not meet resource or real-time constraints, I would suggest eCos. Micro C/OS-II is good if you want to investigate how an RTOS kernel works under the hood in great detail.

Before you buy a board, I suggest that you experiment with the x86 ports of some of the above in a VM on your PC perhaps, or use an old PC you are not otherwise using.

In an embedded project, we're supposed to implement a task scheduler with different priorities, the project implementation is in C and is run on an Arduino device.

Now that we're in the researching phase, one question popped but nobody had experience enough to have a certain answer:

How is it possible to control the execution time of a function? How do we keep track of time before the function returns so we can interrupt it for example when a time-out occurs?

One suggestion was to use fork(), but since Arduino does not include an operation system, there's no kernel to handle a thread. Or am I wrong?

Any input will be helpful, thanks a bunch,

In an embedded system a task scheduler is the core of an operating system (usually an RTOS), so you are being asked to implement one not to use one.

A simple example of how such a scheduler works is described in Jean Labrosse's boot Micro C/OS-II. It describes a complete RTOS kernel with scheduling and IPC. For your project you can take the description of this core and implement your own (or you could use the included source code).

Such a kernel works by scheduling at certain OS calls and on a timer interrupt. A context switch involves storing the processor registers for one task and replacing then with teh registers for another. Because this register save/restore includes the stack-pointer and program counter, control is switched between threads.

It may be that simpler forms of scheduling (rather than preemptive) scheduling are called for. One method is to implement task functions that run to completion and where necessary store their own state and are implemented as state-machines, and then have a simple loop that polls a timer and call's each 'task' function according to a schedule table (that includes the periodicity of the task and a pointer to its function, so that say one function will be called every second, while another will be called every millisecond.

I found one here http://mjc88.0catch.com/ but then some files and description is missing. Please direct me to one, complete open source OS, which is realistic to be build by a single person and i can extend it with my ideas.

One popular choice for this sort of thing is uC/OS. If you buy the book you get a CD with all the source code etc.

You can have a look at that book: Tanenbaum: Operating Systems Design And Implementation