Preface
My first book, “µC/OS, The Real-Time Kernel” is now 6 years old and the publisher has sold well
over 15,000 copies around the world. When I was asked to do a second edition, I thought it would
be a fairly straightforward task; a few corrections here and there, clarify a few concepts, add a
function or two to the kernel, etc. If you have a copy of the first edition, you will notice that
“µC/OS-II, The Real-Time Kernel” is in fact a major revision. For some strange reason, I wasn’t
satisfied with minor corrections. Also, when my publisher told me that this time, the book would
be a ‘hard cover’, I really wanted to give you your moneys worth. In all, I added more than 200
new pages, and re-wrote the majority of the pages I did keep. I added a porting guide to help you
port µC/OS-II to the processor of your choice. Also, I added a chapter that will guide you through
upgrading a µC/OS port to µC/OS-II.
The code for µC/OS-II is basically the same as that of µC/OS except that it contains a number of
new and useful features, is much better commented, and should be easier to port to processor
architectures. µC/OS-II offers all the features provided in µC/OS as well as the following new
features:
•
•
•
•
•
•
•
A fixed-sized block memory manager,
A service to allow a task to suspend its execution for a certain amount of time
(specified in hours, minutes, seconds and milliseconds),
User definable ‘callout’ functions that are invoked when:
a task is created,
a task is deleted,
a context switch is performed,
a clock tick occurs.
A new task create function that provides additional features,
Stack checking,
A function returning the version of µC/OS-II,
And more.
µC/OS-II Goals
Probably the most important goal of µC/OS-II was to make it backward compatible with µC/OS (at least from an
application’s standpoint). A µC/OS port might need to be modified to work with µC/OS-II but at least, the application
code should require only minor changes (if any). Also, because µC/OS-II is based on the same core as µC/OS, it is just
as reliable. I added conditional compilation to allow you to further reduce the amount of RAM (i.e. data space) needed
by µC/OS-II. This is especially useful when you have resource limited products. I also added the feature described in
the previous section and cleaned up the code.
Where the book is concerned, I wanted to clarify some of the concepts described in the first edition and provide
additional explanations about how µC/OS-II works. I had numerous requests about doing a chapter on how to port
µC/OS and thus, such a chapter has been included in this book for µC/OS-II.
Intended Audience
This book is intended for embedded system programmers, consultants and students interested in real-time operating
systems. µC/OS-II is a high performance, deterministic real-time kernel and can be embedded in commercial products
(see Appendix F, Licensing). Instead of writing your own kernel, you should consider µC/OS-II. You will find, as I
did, that writing a kernel is not as easy as it first looks.
I’m assuming that you know C and have a minimum knowledge of assembly language. You should also understand
microprocessor architectures.
What you will need to use µC/OS-II
The code supplied with this book assumes that you will be using an IBM -PC/AT or compatible (80386 Minimum)
computer running under DOS 4.x or higher. The code was compiled with Borland International’s C++ V3.1. You
should have about 5 MBytes of free disk space on you hard drive. I actually compiled and executed the sample code
provided in this book in a DOS window under Windows 95.
To use µC/OS-II on a different target processor (than a PC), you will need to either port µC/OS-II to that processor
yourself or, obtain one from µC/OS-II official WEB site at http://www.uCOS-II.com. You will also need appropriate
software development tools such as an ANSI C compiler, an assembler, linker/locator and some way of debugging
your application.
The µC/OS Story
Many years ago, I designed a product based on an Intel 80C188 at Dynalco Controls and I needed a real-time kernel.
At my previous employer, I had been using a well known kernel (let’s call it kernel ‘A’) but, found it to be too
expensive for the application I was designing. We then found a lower cost kernel ($1000 at the time) and started our
design with it. Let’s call this kernel, kernel ‘B’. We spent about two months trying to get a couple of very simple tasks
to run. We were calling the vendor almost on a daily basis to get help making this work. The vendor claimed that this
kernel was written in C. However, we had to initialize every single object using assembly language code. Although
the vendor was very patient, we decided that we had enough of this. Our product was falling behind schedule and we
really didn’t want to spend our time debugging this low cost kernel. It turns out that we were one of this vendor’s first
customer and the kernel was really not fully tested and debugged!
To get back on track, we decided to go back and use kernel ‘A’. The cost was about $5000 for development seat and
we had to pay a per usage fee of about $200 for each unit that we shipped! This was a lot of money at the time, but it
bought us some peace of mind. We got the kernel up and running in about 2 days! Three months into the project, one
of our engineers discovered what looked like a bug in the kernel. We sent the code to the vendor and sure enough, the
bug was confirmed as being in the kernel. The vendor provided a 90 day warranty but, that had exp ired so, in order to
get support, we had to pay an addition $500 per year for ‘maintenance’. We argued with the salesperson for a few
months that they should fix the bug since we were actually doing them a favor. They wouldn’t budge! Finally, we
gave in, we bought the maintenance contract and the vendor fixed the bug six months later! Yes, six months later. We
were furious but most importantly, late delivering our product. In all, it took close to a year to get our product to work
reliably with kernel ‘A’. I must admit, however, that we never had any problems with it since.
As this was going on, I naively thought, “Well, it can’t be that difficult to write a kernel. All it needs to do is save and
restore processor registers”. That’s when I decided to try it out and write my own (part time at night and on weekends).
It took me about a year to get the kernel to be just as good (and in some ways better) than kernel ‘A’. I didn’t want to
start a company and sell it because there were already about 50 kernels out there so, why have another one?
I then thought of writing a paper for a magazine. I first went to the “C User’s Journal (CUJ)” (the kernel was written
in C) which, I had heard, was offering $100 per published page when other magazines were only paying $75 per page.
My paper had 70 or so pages so, that would be a nice compensation for all the time I spent working on my kernel.
Unfortunately, the article was rejected! There were two reasons. First, the article was too long and the magazine
didn’t want to publish a series. Second, they didn’t want to have ‘another kernel article’.
I then decided to turn to Embedded Systems Programming (ESP) magazine because my kernel was designed for
embedded systems. I contacted the editor of ESP (Mr. Tyler Sperry) and told him that I had this kernel I wanted to
publish in his magazine. I got the same response from Tyler as I did from the C Journal: “Not another kernel article?”
I told him that this kernel was different, it was preemptive, it was comparable to many commercial kernels and that he
could put the source code on the ESP BBS (Bulletin Board Service). I was calling Tyler two or three times a week
(basically begging him) until he finally gave in (he was probably tired of having me call him) and decide to publish the
article. My article got edited down from 70 pages to about 30 pages and was published in two consecutive months
(May 1992 and June 1992). The article was probably the most popular article in 1992. ESP had over 500 downloads
of the code from the BBS in the first month. Tyler may have feared for his life because kernel vendors were upset that
he published a kernel in his magazine. I guess that these vendors must have recognized the quality and capabilities of
µC/OS (was called µCOS then). The article was really the first that exposed the internals of a real-time kernel so,
some of the secrets were out.
Just about the time the article came out in ESP, I got a call back from Dr. Bernard Williams at R&D Publications
(publisher of CUJ), 6 months after the initial contact with CUJ. He had left a message with my wife and told her that
he was interested in the article!??! I called him back and told him something like: “Don’t you think you are a little bit
late with this? The article is being published in ESP.” Berney said: “No, No, you don’t understand, because the article
is so long, I want to make a book out of it.” Initially, Berney simply wanted to publish what I had (as is) so the book
would only have 80 or so pages. I said to him, “If I going to write a book, I want to do it right.” I then spent about 6
months adding contents to what is now know as the first edition. In all, the book had about 250 pages to it. I changed
the name of µCOS to µC/OS because ESP readers had been calling it ‘Mucus’ which didn’t sound too healthy! Come
to think of it, maybe it was a kernel vendor that first came up with the name. Anyway, µC/OS, The Real-Time Kernel
was then born. Sales were somewhat slow to start. Berney and I projected that we would sell about 4000 to 5000
copies in the life of the book but at that rate, we would be lucky if it sold 2000 copies. Berney insisted that these things
take time to get known so, he continued advertising in CUJ for about a year.
A month or so before the book came out, I went to my first Embedded Systems Conference (ESC) in Santa Clara, CA
(September 1992). I then met Tyler Sperry for the first time and I showed him the first draft copy of my book. He very
quickly glanced at it and said something like: “Would you like to speak at the next Embedded Systems Conference in
Atlanta?” Not knowing any better, I said “Sure, what should I talk about?” He said what about “Using small real-time
kernels?” I said “Fine”. On the trip back from California, I was thinking “What did I get myself into? I’ve never
spoke in front of a bunch of people before! What if I make a fool of myself? What if what I speak about is common
knowledge? Those people pay good money to attend this conference.” For the next six months, I prepared my lecture.
At the conference, I had about 70+ attendees. In the first twenty minutes I must have lost one pound of sweat. After
my lecture, I had a crowd of about 15 or so people come up to me and say that they were very pleased with the lecture
and liked my book. I got re -invited back to the conference but could not attend the one in Santa Clara that year (i.e.
1993). I was able to attend the next conference in Boston (1994) and I have been a regular speaker at ESC ever since.
For the past couple of years, I’ve been on the conference Advisory Committee. I now do at least 3 lectures at every
conference and each have average attendance of between 200 and 300 people! My lectures are almost always ranked
amongst the top 10% of the conference.
To date, we sold well over 15,000 copies or µC/OS, The Real-Time Kernel around the world. I received and answered
well over 1000 e-mails from the following countries:
In 1995, µC/OS, The Real-Time Kernel was translated in Japanese and published in a magazine called Interface in
Japan. µC/OS has been ported to the following processors:
Analog Devices AD21xx
Advanced Risc Machines ARM6, ARM7
Hitachi 64180, H8/3xx, SH series
Intel 80x86 (Real and PM), Pentium, Pentium-II, 8051, 8052, MCS-251, 80196, 8096
Mitsubishi M16 and M32
Motorola PowerPC, 68K, CPU32, CPU32+, 68HC11, 68HC16
Philips XA
Siemens 80C166 and TriCore
Texas instruments TMS320
Zilog Z-80 and Z-180
And more.
In 1994, I decided to write my second book: Embedded Systems Building Blocks, Complete and Ready-to-Use
Modules in C (ESBB) and contains over 600 pages. For some reason, ESBB has not been as popular as µC/OS
although it contains as much valuable information not found anywhere else. I always thought that it would be an ideal
book for people just starting in the embedded world.
In 1998, I opened the official µC/OS WEB site www.uCOS-II.com. I intend this site to contain ports, application
notes, links, answers to frequently asked questions (FAQs), upgrades for both µC/OS and µC/OS-II, and more. All I
need is time!
Back in 1992, I never imagined that writing an article would have changed my life as it did. I met a lot of very
interesting people and made a number of good friends in the process. I still answer every single e-mail that I receive.
I believe that if you take the time to write to me then I owe you a response. I hope you enjoy this book.
Acknowledgements
First and foremost, I would like to thank my wife for her support, encouragement, understanding and especially
patience. Manon must have heard the words “Just one more week!” about a dozen times while I was writing this book.
I would also like to thank my children James (age 8) and Sabrina (age 4) for putting up with the long hours I had to
spend in front of the computer. I hope one day they will understand.
I would also like to thank Mr. Niall Murphy for carefully reviewing most of the chapters and providing me with
valuable feedback. Special thanks to Mr. Alain Chebrou and Mr. Bob Paddock for passing the code for µC/OS-II
through a fine tooth comb.
I would like to thank all the fine people at R&D Technical books for their help in making this book a reality, and also
for putting up with my insistence on having things done my way.
Finally, I would like to thank all the people who have purchased µC/OS, The Real-Time Kernel as well as Embedded
Systems Building Blocks and who, by doing so, have encouraged me to pursue this interesting past-time.
Introduction
This book describes the design and implementation of m C/OS-II (pronounced "Micro C O S 2") which stands for
Micro-Controller Operating System Version 2. µC/OS-II is based on µC/OS, The Real-Time Kernel which was first
published in 1992. Thousands of people around the world are using µC/OS in all kinds of applications such as
cameras, medical instruments, musical instruments, engine controls, network adapters, highway telephone call boxes,
ATM machines, industrial robots, and many more. Nu merous colleges and Universities have also used µC/OS to
teach students about real-time systems.
µC/OS-II is upward compatible with µC/OS (V1.11) but provides many improvements over µC/OS such as the
addition of a fixed-sized memory manager, user definable callouts on task creation, task deletion, task switch and
system tick, supports TCB extensions, stack checking and, much more. I also added comments to just about every
function and I made µC/OS -II much easier to port to different processors. The source code in µC/OS was found in two
source files. Because µC/OS-II contains many new features and functions, I decided to split µC/OS-II in a few source
files to make the code easier to maintain.
If you currently have an application (i.e. product) that runs with µC/OS, your application should be able to run,
virtually unchanged, with µC/OS-II. All of the services (i.e. function calls) provided by µC/OS have been preserved.
You may, however, have to change include files and product build files to ‘point’ to the new file names.
This book contains ALL the source code for µC/OS-II and a port for the Intel 80x86 processor running in Real-Mode
and for the Large Model. The code was developed on a PC running the Microsoft Windows 95 operating system.
Examples run in a DOS compatible box under the Windows 95 environment. Development was done using the
Borland International C/C++ compiler version 3.1. Although µC/OS-II was developed and tested on a PC, m C/OS-II
was actually targeted for embedded systems and can easily be ported to many different processor architectures.
µC/OS-II features:
Source Code:
As I mentioned previously, this book contains ALL the source code for m C/OS-II. I went through a lot of efforts to
provide you with a high quality ‘product’. You may not agree with some of the style constructs that I use but you
should agree that the code is both clean and very consistent. Many commercial real-time kernels are provided in
source form. I challenge you to find any such code that is as neat, consis tent, well commented and organized as
µC/OS-II’s. Also, I believe that simply giving you the source code is not enough. You need to know how the code
works and how the different pieces fit together. You will find this type of information in this book. The organization
of a real-time kernel is not always apparent by staring at many source files and thousands of lines of code.
Portable:
Most of m C/OS-II is written in highly portable ANSI C, with target microprocessor specific code written in assembly
language. Assembly language is kept to a minimum to make µC/OS -II easy to port to other processors. Like µC/OS,
µC/OS-II can be ported to a large number of microprocessors as long as the microprocessor provides a stack pointer
and the CPU registers can be pushed onto and popped from the stack. Also, the C compiler should either provide
in-line assembly or language extensions that allow you to enable and disable interrupts from C. µC/OS-II can run on
most 8-bit, 16-bit, 32-bit or even 64-bit microprocessors or micro-controllers and, DSPs.
All the ports that currently exist for µC/OS can be easily converted to µC/OS-II in about an hour. Also, because
µC/OS-II is upward compatible with µC/OS, your µC/OS applications should run on µC/OS-II with few or no changes.
Check for the availability of ports on the µC/OS-II Web site at ‘www.uCOS-II.com’.
ROMable:
µC/OS-II was designed for embedded applications. This means that if you have the proper tool chain (i.e. C compiler,
assembler and linker/locator), you can embed µC/OS-II as part of a product.
Scalable:
I designed µC/OS-II so that you can use only the services that you need in your application. This means that a product
can have just a few of µC/OS-II’s services while another product can have the full set of features. This allows you to
reduce the amount of memory (both RAM and ROM) needed by µC/OS-II on a product per product basis. Scalability
is accomplished with the use of conditional compilation. You simply specify (through #define constants) which
features you need for your application/product. I did everything I could to reduce both the code and data space
required by µC/OS-II.
Preemptive:
µC/OS-II is a fully-preemptive real-time kernel. This means that µC/OS-II always runs the highest priority task that is
ready. Most commercial kernels are preemptive and µC/OS-II is comparable in performance with many of them.
Multi-tasking:
µC/OS-II can manage up to 64 tasks, however, the current version of the software reserves eight (8) of these tasks for
system use. This leaves your application with up to 56 tasks. Each task has a unique priority assigned to it which
means that µC/OS-II cannot do round robin scheduling. There are thus 64 priority levels.
Deterministic:
Execution time of all µC/OS-II functions and services are deterministic. This means that you can always know how
much time µC/OS-II will take to execute a function or a service. Furthermore, except for one service, execution time
of all µC/OS-II services do not depend on the number of tasks running in your application.
Task stacks:
Each task requires its own stack, however, µC/OS-II allows each task to have a different stack size. This allows you to
reduce the amount of RAM needed in your application. With µC/OS-II’s stack checking feature, you can determine
exactly how much stack space each task actually requires.
Services:
m C/OS-II provides a number of system services such as mailboxes, queues, semaphores, fixed-sized memory
partitions, time related functions, etc.
Interrupt Management:
Interrupts can suspend the execution of a task and, if a higher priority task is awakened as a result of the interrupt, the
highest priority task will run as soon as all nested interrupts complete. Interrupts can be nested up to 255 levels deep.
Robust and reliable:
µC/OS-II is based on µC/OS which has been used in hundreds of commercial applications since 1992. µC/OS-II uses
the same core and most of the same functions as µC/OS yet offers more features.
Figures, Listings and Tables Convention:
You will notice that when I reference a specific element in a figure, I use the letter ‘F’ followed by the figure number.
A number in parenthesis following the figure number represents a specific element in the figure that I am trying to
bring your attention to. F1-2(3) thus means look at the third item in Figure 1-2.
Listings and tables work exactly the same way except that a listing start with the letter ‘L’ and a table with the letter
‘T’.
Source Code Conventions:
All µC/OS-II objects (functions, variables, #define constants and macros) start with OS indicating that they are
Operating System related.
Functions are found in alphabetical order in all the source code files. This allows you to quickly locate any function.
You will find the coding style I use is very consistent. I have been adopting the K&R style for many years. However,
I did add some of my own enhancements to make the code (I believe) easier to read and maintain. Indention is always
4 spaces, TABs are never used, always at least one space around an operator, comments are always to the right of code,
comment blocks are used to describe functions, etc.
The following table provides the acronyms, abbreviations and mnemonics (AAMs) used in this book. I combine some
of these AAMs to make up function, variable and #define names in a hierarchical way. For example, the function
OSMboxCreate() reads like this: the function is part of the operating system (OS), it is related to the mailbox
services (Mbox) and the operation performed is to Create a mailbox. Also, all services that have similar operation
share the same name. For e xample, OSSemCreate() and OSMboxCreate() perform the same operation but on
their respective objects (i.e. semaphore and mailbox, respectively).