“Time and tide wait for no man.”Geoffrey Chaucer
Our opening quote dates back to the middle ages—believe it or not, long before the inception of the educational and informative NetBurner Learn Blog. While there is some controversy about whether Chaucer is quoting from an earlier source, if he were still around, he would no doubt be writing for the Learn Blog.
But what do time and tide have to do with operating systems? And would Chaucer have a clue as to what an operating system is?
In this article, we cover some key differences between a real time operating system (RTOS) and some other varieties. In the process, we hope to help you realize why NetBurner’s Epic RTOS is the OS you never knew you wanted, until now.
You of course know what an OS is; in fact, you’re almost certainly using some kind of operating system right now to read this article. Let’s start with a quick review anyway, to give us a basis for understanding what “Real Time” means when applied to an OS…
What is an Operating System?
Modern computers, regardless of make or model, are invariably extremely complex devices. Using them every day, we bask in the light of our high resolution color monitors. Doing so, we take our computers for granted. Rarely do we think about all of the pieces and parts that are lurking “under the hood.”
A typical computer comprises an almost bewildering array of elements and devices. These all must work together in concert to provide the services of the system as a whole.
Major compute elements may include the CPU (Central Processing Unit), high-speed cache memory, DRAM (Dynamic Random Access Memory), mass storage devices (HDD, SDD, DVD-ROM, etc.), network interface hardware, GPUs (Graphics Processing Units) and many other peripheral devices such as printers and plotters.
Courtesy of your OS, your computer seems to be able to do several things at once. For example, when you start a print job, you can go right back to editing the next version of your file, or reading your email, or playing Breakout… all while you’re listening to the latest MP3 hit streaming in over the network. How is your computer able to do all these things at the same time?
Behind the Magic: Tasks
In reality, each of those operations, called “tasks,” is being sliced and diced by your OS. This is called “multitasking”. Your OS allocates a certain amount of time for each task to operate, and gives time to the next task—maybe while the first is waiting on an I/O, or maybe just because it’s the next task’s turn. It just seems like everything is happening at once.
Sophisticated operating systems make all of this possible, if not dead simple. OSs provide a scaffold, an underlying structure and interface definition. This enables computer users and the producers of computer hardware of all kinds to easily meet on common ground.
Additionally, they provide a more or less standardized platform enabling software developers to create the amazing solutions to everyday problems that we have come to rely on. We expect our spreadsheets, CAD/CAM programs, and even our guilty pleasures—the fantastic space adventures and shoot-em-up games we love—to just be there and run as needed. And developers no longer need to worry about what kind of graphics card we’re using, or the details of how a specific monitor will display the text and graphics of a program’s output. They write for a generic interface standard, and the OS and device manufacturers take care of the rest.
Some common operating systems
If you’re at your desk, you’re probably using one of the “big four” OSs right now… Windows, macOS (formerly OS X), Linux, or Unix. If you’re reading this on your phone or tablet, it’s likely using one of these: Android, iOS, or maybePalm Os or Blackberry or some flavor of Windows…
Some of these OSs are more agile than others. Linux, as an example, is a relatively “light-weight” operating system—especially if you’re comparing it to that 300-pound gorilla, Windows 10. Sure, your PC may run faster and slicker on Linux. However, your embedded device may have requirements that Linux is just not capable of meeting.
But are any of those systems truly suitable for IoT? More often than not, standard, consumer OSs try to be all things to all men. Their universal nature prevents them from dealing effectively with one of the most important elements that IoT devices are preoccupied with; namely, the focus of this article, time.
One Drawback of Standard Operating Systems
Like the appointment secretary in an office, operating systems must schedule a multitude of programs so as to make the best use of available time and resources. The secretary uses an appointment calendar, coordinating individual availability, lunch breaks, conference rooms, international time-zones, and so forth, to produce the best outcome for all involved. An OS may use one of several standard scheduling algorithms that have been devised for this purpose—First Come, First Served; Shortest-Job-Next; Multiple Level Queues, and etc. Perhaps the simplest, most commonly used approach is Round-Robin Scheduling.
But typical operating systems aren’t overly concerned with priority (which task is more important). To be sure, their device drivers handle some time-dependent input and output in frequent, short bursts. However, at a higher level, task switching between programs typically occurs in a round-robin fashion that can be arbitrarily delayed. Programs have no guarantee of timeliness when running.
In fact, you’ve probably experienced the frustration of a program temporarily “locking up” while you wait for your favorite OS to do some memory “garbage collection” or other essential housekeeping task. Like the White Rabbit that Alice encountered in Wonderland, your program may end up running late for a very important date. This is not cool! IoT devices have needs that simply can’t wait!
Devices Need OSs, Too!
Thank goodness, there is a class of operating system designed with time explicitly in mind. Now that the Internet of Things is the latest rage in embedded systems, companies everywhere are creating increasingly sophisticated network-connected devices. Perhaps you’re working on one now, or have an IoT device in the planning stages. As a developer, you don’t need or want to know every detail of the hardware your code is running on. But the time has come to think about the topic we began this article with: namely, time.
“Real-world” devices often interface to time-dependent physical hardware, or to processes that must happen not only in a particular sequence, but also on a specific schedule. The RTOS, or Real Time Operating System, is specifically tailored to accommodate time in the real world. An RTOS can deal not only with wall-clock and calendar time intervals, but also with the far more stringent time requirements of things like elevators, automobiles, and aircraft.
While your desktop OS tries to be everything to everybody, there are things a simpler—but better suited—RTOS can do much better.
Anything You Can Do, I Can Do Better!
Can an RTOS really do “anything” better? Well, maybe not anything… But an RTOS can certainly do the things a typical Internet of Things device or embedded system needs better than desktop OSs. Included with every NetBurner IoT development kit, let’s take a look at the core features of NetBurner’s RTOS, the epitome of a superior Real Time Operating System.
How is an RTOS Different?
In an RTOS, time is of the essence. A good RTOS gives the programmer a set of tools that enable precise control over the scheduling of time-dependent tasks. Using them, of course, requires thoughtful design by the programmer—a subject worthy of plenty of study and practical experience. However, understanding the basics is fairly simple.
Program tasks are preemptive, meaning that the highest priority task always runs—for as long as, and whenever it needs to. In NetBurner’s RTOS, the number of available task priorities is defined as OS_MAX_PRIOS in the file ‘constants.h’. Priority values can range from OS_MAX_PRIOS-1 (the highest task number, which is the lowest priority) to 1, (the highest priority available).
But, here is a key point that is very important to note: whenever a task has completed whatever actions may be important at that time, it must yield control so that lower priority tasks can run.
A task gives up time by blocking (also called pending) on some condition or event. What does that mean? The task can use a function to ask the underlying RTOS to take over. This allows other tasks to run until some predefined condition is satisfied. This can be a simple time delay, or a complex combination of inputs, timing, and other contingencies. In NetBurner applications, this is often done with a call to OSTimeDly() or some other RTOS Blocking Function.
A Real World Example
For example, suppose you’ve been asked to record runner times in the 100 meter dash at the upcoming Summer Olympics in Tokyo. You look at the record of past results, and see that timings for the dash are recorded in hundredths of a second.
You know you’ll need several logically independent tasks to do the job: a very high speed clock task to track time elapsed since the starting gun; a camera task watching the finish line; a scoreboard task displaying the time for the crowd to watch; a network task transferring status and results to officials; a logging task to preserve the data for posterity; probably others you’ll figure out as you go along.
The highest priority task in the timekeeping clock you create for the event will be a “tick” task that tracks real-time at least ten times faster (milliseconds). When it sees the millisecond clock tick over, it adds 1/1000 of a second to its millisecond count. Every 100 milliseconds, the task also increments the 1/10th second counter. It proceeds to do this for each digit in the timekeeping clock.
That timekeeping task must be the highest priority, or the system could lose track of the elapsed time. However, once it completes its work, unless it blocks and yields time to the next most important task, the system won’t do its job! That task is the camera watching for each runner to cross the finish line.
There is an overhead camera staring at the finish line. It can “see” each runner approaching, and then crossing the line. When that happens, the task takes the current value of the timekeeping clock, stores it in association with the runner’s name, and then pends to yield time for any lower priority tasks to run. For example, that scoreboard task, or that task that transmits status and results to a broadcast announcer.
When all lower priority tasks have completed, the system “Idle Task” will run until another task “wakes up” and takes over.
By the way, actual Olympic timing in our modern age is now recorded in microseconds.
Shared Data Protection
Multiple processes in a Real Time system often need to share data. More than one process may need to modify the data. If data access isn’t carefully controlled, it can become corrupted and the system operation will fail.
An RTOS provides multiple mechanisms for ensuring that shared data is accessed and updated in a reliable manner. Let’s look at several of the NetBurner RTOS mechanisms that accomplish this, along with some examples of how they might be used in the real world.
The term “semaphore” from the Greek meaning “sign bearer,” came into use in the early days of railroads. Semaphores were used to signal locomotive engineers by means of easily seen mechanically operated flags. The flags warned the engineer of conditions ahead in order to prevent trains from colliding at a crossing.
In a real-time IoT device, a Program Semaphore may be used to allow multiple tasks to update some data at the same time without corruption. For example, suppose that identical parts made by identical machines on opposite sides of a storage bin are being added to the bin. At the same time workers remove parts from the bin to fulfill orders. We want an accurate count of the total number of parts in the bin at all times. We also want to ensure that the bin doesn’t overflow. A semaphore can regulate access to the total parts count variable, allowing each machine to safely update the total in turn. They will account for parts removed, and turn the production machines on or off to prevent the bin from overflowing.
How Semaphores Saved Snoopy
Let’s have some fun and get a better understanding of semaphores… This time, you’re Snoopy, piloting a souped-up Sopwith Camel. “Curse you, Red Baron!” you shout, coming out of your Immelman turn right on your nemesis’ tail.
You line him up in your crosshairs. As you’re about to squeeze the trigger on your Vickers machine guns, you hesitate…
Did you implement the semaphores correctly? The guns are mounted on the fuselage, behind the prop. The last thing you need is hot lead shattering your propeller to splinters! Those rounds had better be precisely timed, perfectly coordinated with the position of the blades…
But there’s no time to stress over the matter; you’ll find out soon enough.
Trigger engaged, you see tracer rounds streaking toward the Fokker DR1. You pull back slightly on the stick. Just as your rounds begin piercing the fabric of his tail section, the Baron pulls into a steep climb and out of your sights.
The good news, however, is that your prop is still spinning. It pulls you past him and out of range of his nasty guns. Better yet, none of your bullets hit your prop! The semaphores you established to synchronize the Vickers firing pin with the position of the prop blade must have done their job. Thankfully you won’t be spinning to earth!
As that was the last of your ammunition, you continue forward. In your mirror, you see the Red Baron execute a hammerhead stall and head off into the sunset to fight another day. Meanwhile, you head back to your laptop to tweak your aiming software…
In a similar fashion, RTOS semaphores are used to coordinate the operation of more than one task, enabling tasks to coordinate in time.
The NetBurner RTOS also facilitates the creation of bit-mapped flags. A semaphore can block on only a single event. Similar to a semaphore, a flag goes beyond a single event. This enables a task to set and act upon a collection of status bits that define a logical combination of multiple events.
Queues and FIFOs
A queue is a very useful mechanism that allows multiple independent tasks to both read from and write to a common data stream, without “stepping on” one another’s toes.
In the NetBurner RTOS, the only difference between the two is that they handle different kinds of data; queues handle a fixed number of pointers to data, while FIFOs are linked lists of data structures.
You could think of queues as somewhat like the sections of this marble maze where the marbles are forced to stay in line as they pass through…
Warning! Watch at your own risk: this video is so addictive, you may not be able to turn it off!
Hey! If you’re going to be critical, go somewhere else!
Just kidding; we love constructive feedback. But, in this context, “critical” means something your task must accomplish without interference.
Sometimes a logical operation needs exclusive access to resources from start to finish. Under normal circumstances, those resources might be preempted by a higher priority task. By declaring a critical section at the beginning of the operation, a task can gain exclusive access to a resource until it is done using it.
Suppose for example you’ve built a cake decorating machine. You have one task assigned to inserting colored icing into the lettering syringe. You also have another task assigned to squeezing the icing out into letters and words.
Do you want to be sure a word is completed, start to finish, all in the same color? Make that operation a critical section, and the color change won’t take place until the word is completed.
Conclusion: An (R)TOSs-Up?
NetBurner may have just the right RTOS for you… Or, just maybe, the project you’re looking at might need something more—or less—sophisticated. Ultimately, only you can make that determination, but NetBurner Learn Blog articles may help you figure it out.
Arduino, NetBurner RTOS, and Raspberry Pi
For example, in a previous Netburner Learn Blog article, we offer a detailed comparison of three significantly different approaches—Arduino, NetBurner, and Raspberry Pi—to IoT. Now that you “get” the basics of what an RTOS has to offer, if you’re trying to decide which way to go, that article may be just what you need to arrive at a good conclusion.
Our engineers are always eager to help, so please contact us with your questions, or feel free to leave comments below.
- OS or O/S — An Operating System manages a computer’s hardware and software
- Real-Time — The ability to deal with time-dependent events
- RTOS — Real-Time Operating System
- Multitasking — Multiple tasks can run without fixed hand-offs
- Preemptive — The highest priority task always runs
- Semaphore — A tool for preventing unwanted task interaction
- Mailbox — A tool for inter-task communication
- FIFO — A First In, First Out queue for data
- Priority — The level of importance at which a task runs
- Blocking — Task suspension waiting for some event, such as an input or output
- Pending — Synonym for blocking
- Round-Robin — A popular method of scheduling tasks, one after another in a fixed sequence
- Idle Task — A system task that runs when no other task is active
- DRAM — Dynamic Random Access Memory
- HDD — Hard Disk Drive, a kind of mass storage device
- SDD or SSDD — Solid State Disk Drive, like an HDD but faster, without moving parts
- DVD ROM — Digital Video Drive-Read Only Memory – an optical mass storage device
- GPU — Graphical Processing Unit
- IoT — The Internet of Things, namely, devices of all kinds connected to the network so they can provide information to and/or be controlled by remote applications
- IoT Device — Any internet-connected product, i.e. pretty much any “thing” with an on/off switch