Главная > Документ

Embedded Programming

Robert Carpenter

Table of Contents

1. Introduction 1

1.1. Intended Audience 1

2. Background 1

3. Provided Embedded System 1

4. General Microcomputer Features 2

5. Languages 2

1.2. ADA 2

1.3. C 2

1.4. (E)C++ 2

1.5. Java SE for Embedded 2

1.6. Arduino 2

1.7. Pick one! 3

6. Programming (getting started) 3

1.8. Arduino: Setup and Loop 3

1.9. Compiling 3

1.10. Uploading Your Hex 3

1.11. Running the program 4

1.12. Arduino: Compiling and Uploading 4

7. Debugging 4

1.13. Breakpoints please? 4

1.14. Saving State 4

1.15. CommentsError: Reference source not found 5

1.16. Arduino Debugging 5

1.16.1. Saving state 5

1.16.2. Serial print statements 5

1.16.3. LED – the little flashing light 5

8. Programming 6

1.16.4. Overall Program Size 6

1.16.5. Speed – Algorithmic Efficiency 6

1.16.6. Memory Usage 7

1.16.7. Approximations 7

9. The Real Time Operating System 7

1.17. The context switcherError: Reference source not found 8

1.18. When to use an RTOS 8

1.19. How to write programs for the RTOS 8

1.19.1. Debugging with the RTOS 8

1.20. Arduino RTOS? 9

10. Conclusion 9

11. References 10

Appendix A : Macro code for C 11

Appendix B : Inline functions 13

Appendix C : Arduino Code 14

Appendix D : Review Questions 16

Appendix E : Review Question Answers 16

  1. Introduction

An embedded system is an electronic device that incorporates one or more microprocessors within its implementation1. The devices vary from traffic lights, to cell phones, video game consoles to dishwashers, coke machines to electric toothbrushes; the list goes on and on. In recent history, embedded systems have become increasingly more prevalent as manufacturers attempt to cut re-engineering and production costs. In addition, this trend shows no signs of waning. The routers, switches, modems and hubs that are “the infrastructure of the Internet” are going to ensure that the embedded system “will become increasingly prevalent.”2 Even the PC that we all have come to think of as a 'computer' contains a whole handful of microprocessors.

Learning to program an embedded system is a useful exercise in reliability, performance, good coding practices, thorough testing, and sometimes even assembly language programmingError: Reference source not found. Often embedded systems are required to process arbitrary events in real time. This calls for efficient algorithms as a decision process exceeding the constraints of real time could result in the loss of life – an anti-lock braking system for example.Error: Reference source not found

The embedded system is defined by a set of rules that are concurrently liberating and constraining. The system is always application specific. Because the end product and its uses are known before hand unnecessary complexity (such as miscellaneous peripheral port addition) can be removed from the design of the software and hardware. However, the inflexibility of the embedded system programming means that it cannot be adapted to a new task without reprogramming3.

The system is also usually event driven,Error: Reference source not found reacting to the world around it. Often an embedded system is waiting on time for its event (i.e. a digital alarm clock).

An embedded system should also be efficient.Error: Reference source not found A stoplight that, when presented with a Mobile Infrared Transmitter (MIRT) transmission, fails to quickly preempt its normal cycle is not a working stoplight. Neither is an embedded system that fails to perform its task efficiently.

Part of the efficiency in an embedded system comes from the hardware design. It would be an inefficient use of money, space, and power requirements to use a general purpose Pentium processor in most embedded applications. “Smaller silicon area directly translates to lower production costs […] and lower power consumption,” with the trade-off of less processing power and speed. However, the specialized nature of the embedded system generally requires less of these precious resources.Error: Reference source not found

tended Audience

As I read and studied more and more I found that the topic of embedded programming has many facets. This article is written with the experienced software developer in mind – someone that has a hope of beginning embedded development but may not know where to begin. There are already a lot of well written books out there that cover the advanced embedded system software development techniques and most of them are easy enough to read. If you are a programmer hoping to break out of the desktop shell, this tutorial is designed to get you started.

  1. Background

The embedded system as we know it today is quite different from its predecessors. Early embedded systems were electromechanical computers designed for a specific task – they had to be re-engineered instead of reprogrammed. In the 1960s, embedded systems first started to take the shape similar to what we know today when solid state electronics were becoming popular. The first microprocessor was designed by Intel and only allowed for four-bit addressing to external ROM memory4. Later, manufacturers integrated ROM program memory, RAM register memory, and input/output registers into one package called the microcontrollerError: Reference source not found,5. The price of the microcontroller dropped over the years leading to the widespread use of embedded systems we see todayError: Reference source not found.

  1. Provided Embedded System

For the purposes of this tutorial I have been allowed to experiment with an embedded system called Arduino. It is an open source embedded system for program development on the Atmel ATmega8 microcontroller. The development environment provided for the Arduino is open source and cross platform software that includes a cross-compiler and USB programmer6. All of the code examples contained herein will be in the C-style language native to the Arduino environment (also called Arduino).

In the Arduino world () written programs are called sketches. These sketches are linked automatically with included libraries as needed to enable serial communication or easier control of peripherals. All this is done automatically by the Arduino IDE.Error: Reference source not found

  1. General Microcomputer Features

The average desktop computer contains a whole host of features. Sound and 3-d video processing are commonly built into the motherboard. Enormous storage space is provided in the form of the hard drive. Communications hardware in the form of modems and Network Interface Cards are among many cheap peripherals that can be added onto the motherboard. And two (sometimes more) forms of user input: keyboard and mouse.

The typical microcomputer comes in the form of a small industrial-centipede-looking electronic component and does not have all the flashy tricks and features of the desktop environment. Instead, a microcomputers’ feature set is focused on processing speed and memory size. Many microcomputers boast more than one analog to digital converter on chip and more digital read/write pins.

The Arduino platform natively sports fourteen digital read/write pins and six analog to digital converters. Three of its digital pins are capable of pulse-width-modulation.

  1. Languages

Today, with the abundance of embedded programming environments available, a programmer has their choice of what language to use when developing embedded software.


Ada was originally developed for use in real-time embedded systems. It has many built in features such as type-explicit dynamic memory management, run-time type checking, exception handling, generics, and run time checking to prevent common programmer errors such as off-by-one and array access out of bounds errors.

Because of many of the built in features Ada is the language of choice for embedded systems used by the Department of Defense7,8 and it is often used in “avionics, weapons (including thermonuclear weapons), and spacecraft.”Error: Reference source not found

Grammatically, Ada is similar to pascal but it has a heavier emphasis on English words instead of symbols. It is also very structured, requiring each code block to be closed.


The C language is getting to be old but is still in popular use. It was originally developed in the late sixties by AT&T as a general programming language and was made popular due to its close relationship with the Unix operating system.

Its built in allowances for low-level assembly- like code make it very attractive to embedded programmers. It is very easy to insert a section of assembly code right into the middle of a C program where the language itself is not able to provide the required features, making it useful for machine-specific driver development.Error: Reference source not found

Its syntax has propagated into most modern programming and scripting languages and so it is widely used and understood.

The long history of C means that many compilers with a variety of optimizing, compressing, and error checking features exist.Error: Reference source not found


C++ is the bigger, object-oriented brother of C. Its object oriented nature means it works well for desktop systems but has some drawbacks for the embedded system. Many of the features built into the language are not applicable to embedded systems but require a considerable size and speed overhead, thus making it a difficult choice.

If C++ is the big brother of C, then EC++ is the middle child (E is for Embedded). It is a simplification of the object oriented structure of C++ with embedded applications in mind. “Development tools supporting EC++ are already available, but EC++ is not yet a widespread language.”Error: Reference source not found

1.5.Java SE for Embedded

Java is a platform independent language developed by Sun Microsystems primarily for use on the internet.Error: Reference source not found The major drawback of using java in an embedded system is its dependence on the Java Virtual Machine (JVM), the required environment inside which compiled java programs run. For a Java program to run on an embedded system, a JVM and the byte-code interpreter must be implemented in and reside on-chip. Java compilers that output machine-specific code do exist, which lift this requirement.Error: Reference source not found

Java’s benefits for the embedded system include automatic garbage collection and easy multithreaded applications.Error: Reference source not found,9

Java syntax is considered C-style.


The Arduino microcomputer development environment is designed to be programmed in the Arduino language, which is based off of the Wiring language (also an embedded language.)10,Error: Reference source not found It is based off of C-style syntax but has several features implemented that take away a lot of the headache of writing software for the embedded platform.Error: Reference source not found

1.7.Pick one!

Even with all these choices at hand, by far the most common language used for embedded software and driver development is C Error: Reference source not found,Error: Reference source not found – probably due to its longevity and practicality as a language that will continue to be maintainable for years to come7. However the assembly language is not to be ignored. Almost always a small amount of assembler code will be used to program the more delicate parts of an embedded application (interrupt handling, input-output, etc.).7 Whatever language you choose, be sure to have a good reference manual and a development environment that supports embedded systems.

  1. Programming (getting started)

Just like writing software for a personal computer, a set of tools is required for writing and compiling the high level programming language into machine code and then inserting it into execution space in memory. On the surface, most of these tools are the same for embedded development: a text editor, compiler, linker and loader. Digging deeper, some of these tools have been modified and may even require some extra work to get everything to flow smoothly through the programming process.

In an embedded system, where conventional facilities such as keyboard and character screen are rare, programming technique is of greater importance. Proper planning comes in handy in a computer application but it is nearly a necessity for any significant amount of success in the embedded world. It is a wise desktop application programmer that saves time collecting algorithms for future use, but an algorithm collection for embedded systems is downright necessary – the level of abstraction is simply too great to justify recoding anything.Error: Reference source not found

1.8.Arduino: Setup and Loop

In the desktop computer programming world, every C program must have a main() function. It’s where the program begins its execution. The compiler requires a start point, but from there on, the program defines its own execution path until somewhere it ends.

Simple embedded applications are often state machines – the initiation of an event by the user (or time) forces the software from one state into another and the lack of event forces the software to wait.Error: Reference source not found The waiting process should be an infinite closed process loop, with “each part of the code [being] processed in sequence endlessly.”Error: Reference source not found Even if the primary task of the system is fulfilled, the program still runs its main loop.1

The basic structure of an embedded program consists of two states: startup and the main loop. At startup, a subroutine is called which will initialize the system and its peripherals. After the startup is called, the main loop will begin execution. The main loop will then repeat as long as the mechanical functioning requirements of the device are satisfied. This distinction can be seen in the desktop computer as well.

In the Arduino, this startup and loop format is obvious with the two required subroutines: setup() and loop(). At startup, the setup() subroutine is called once. As soon as it exits the loop() subroutine is called. Each and every time the loop() returns, it is re-called, thus demonstrating the infinite looping behavior.


The compilation process is identical to that of a standard desktop program up until the program is prepared for actual execution. At that point the executable image file (usually .bin or .hex) must then be run through a locator to allow the program to be stored in static read-only memory. The locater takes place of the operating system’s loader program by specifying ahead of time what the memory offset will be in the embedded system – something usually taken care of at run time by the loader.Error: Reference source not found The process is simple and involves only modifying a few bytes of data at the beginning of the image.

1.10.Uploading Your Hex

Before the embedded system can be started the binary image file will need to be uploaded or burned into the microcomputer’s internal program ROM. The process for this varies depending on the system, but special purpose devices called programmers are common and are used when the microcontroller is not already wired into the host circuit. Some embedded systems, such as the Arduino, come with a development circuit which has at least one method of uploading the program image to the microcontroller.Error: Reference source not found The interface style can vary from a serial or parallel cable to USB (on newer circuits), and sometimes a custom ICSP header (In Circuit Serial Programmer). The Arduino development circuit has a USB port and an ICSP header.Error: Reference source not found

The entire upload process shouldn’t take more than a few minutes as most embedded programs are only a few Kilobytes (e.g. A typical CD player only needs ~18KB, and a fax machine ~30KB).Error: Reference source not found

Some development environments even provide the option to automatically upload the image to the host system after compilation.

nning the program

Unlike the common desktop computer, the embedded computer does not have a point and click interface to start a programs execution. No .exe file is stored on a hard drive that needs to be loaded into memory. Fortunately it is much simpler. The embedded system only needs to receive power and the program stored in ROM will begin execution. Because an embedded system is only designed for one function: to run the program it holds, it does so whenever it can.

1.12.Arduino: Compiling and Uploading

Write a program for the Arduino. Go ahead.

When you are done, plug the Arduino into your PC’s USB port, click the upload button and push the reset button on the Arduino. If you see lights flashing on and off, your sketch is being uploaded. Your program will begin execution about ten seconds after the upload is complete.

  1. Debugging

Humans are not naturally perfect.

“The kid who brings home straight A grades thrills his parents. Yet we get an A for being 90% correct. Perfection isn’t required. Most endeavors in life succeed if we score an A, if we miss our mark by 10% or less.

“Except in software. 90% correct is an utter disaster, resulting in an unusable product. 99.9% correct means we’re shipping junk. One-hundred K [Sic] lines of code with 99.9% accuracy suggests some 100 lurking errors. That’s not good enough. Software requires near perfection, which defiles the nature of intrinsically error-prone people.” – Jack GanssleError: Reference source not found

Even if we strive to write perfect software, utilizing all the techniques available to us today (structured programming, diagramming, pair-programming, flow-charting, good top-down design, etc.) our software will still not be perfect. It is possible that the only perfect program we will ever write is the ubiquitous Hello-world first program. Nevertheless, striving for perfection is not useless.

No matter how many times we comb our code, it will break. An embedded system provides a unique challenge not only in programming method, but also in debugging method. The common absence of a display capable of continually updating the status of numerous variables and the lack of debugging tools such as a breakpoints, and step-by-step watched execution can make debugging a chore. Luckily the embedded system provides some facilities that can cleverly be used for locating and exterminating bugs.

However, compared to debugging a PC application inside an IDE, embedded debugging is an ugly chore. Utilize every available tool to minimize the appearance of bugs in the first place. Many times, especially when dealing directly with the onboard memory, I scratched out a picture on paper to describe what I couldn’t visualize in my head.

1.13.Breakpoints please?

Most experienced programmers can quickly debug a program with breakpoints. The problem with debugging embedded computer programs is that the mechanism that provides breakpoints and their usability, the development environment, does not exist natively in the embedded platform. In recent years a lot of hardware development has added technologies that allow for the breakpoint-like debugging style. Some of these technologies are JTAG connectors, In Circuit Emulators, and debugWire. However, while incredibly useful, the hardware and software to support these debugging technologies is not cheap.

Part of the problem with implementing breakpoints in an embedded system lies in the lack of appropriate hardware to view the programs current location in execution and the state of variables when stopped. Perhaps a bigger problem is that, by definition, an embedded system is a real-time system. Halting program execution to inspect the state of things effectively removes the system from the environment for which it was built.11

Due to these effects, breakpoint debugging is generally not available for the small-scale embedded developer.

1.14.Saving State

Saving the current system state to non-volatile memories onboard the microcomputer for later retrieval is a very effective and economical way to get a run-time snapshot of what is going on inside the microcomputer.

“Consider writing a generic snapshot-dump routine that you can invoke anywhere in the code. Program it to perform the most frequently used logging tasks like saving registers. You’ll certainly use it a lot throughout any one project, so the hour or so spent coding a useful routine will pay for itself many times over.”Error: Reference source not found

A generic subroutine that saves a few global variables and maybe also those handed through parameters can be quickly called inside a possibly buggy section of code. In order to get the information out of the memories, another program will have to be loaded into the microcontroller that will scan for and somehow read and erase the saved information for analysis.

mentsError: Reference source not found

“More has been written about comments than any other part of programming, but proper commenting still remains one of the most serious and commonplace deficiencies in the industry.”

Any programmer that has read a book on programming technique, style, debugging, or efficiency knows that people think comments are useful. Moreover, anyone that has revisited code after a few years or even sometimes a month knows how cryptic code can be, even when it is read by the same person that wrote it. Writing a good set of comments to describe what is going on behind all the variable and function names might take an extra investment of time in the beginning but it will save a much greater amount of time later when you are trying to figure out what was going through your head six months previous.

The aspect of describing in English words what is being accomplished in a subroutine often has the wonderful side effect of helping the writer to actually understand what is going on. So often programmers attack a problem by throwing a handful of code like a snowball should be thrown. Writing out what is planned before the code is written clarifies where logical divisions into subroutines should be defined. When the average programmer spends 90% of their time on maintenance,Error: Reference source not found well defined logical flow and subroutine divisions are essential. Defining the formal parameters and return values for a function is great, but working out the mechanical details in English will help the overall scope of the project or function to take shape in less time and with greater accuracy.

1.16.Arduino Debugging

In addition to the standard debugging methodologies, the Arduino platform presents some specific challenges and assets to the debugging programmer.

While not having access to the proprietary Atmel debugWire technology did not allow the Arduino developers to allow for source-level debugging like breakpoints, they did do a good job of allowing for less accurate but still useful debugging techniques.

1.16.1.Saving state

A system snapshot is probably the only common embedded debugging technique that can easily provide aid in the debug process for the Arduino.

The basic approach would be to implement a subroutine to save variables to flash memory (or export them to a host computer through the serial port). If the snapshot was saved to flash memory a simple program to echo the flash contents through the serial port would provide the necessary data export. Use the internal millis() function to set an execution interval and the routine is complete. (See 1.20Arduino Code for an example of this timing method.)

1.16.2.Serial print statements

If the part of the program that is being debugged is not time sensitive then the easiest debugging method is probably to take advantage of the serial communication libraries that are provided. The IDE provides a usable serial monitor to view the output from the sketch.

Unfortunately the code must indeed not be time sensitive. If any communication is made with coprocessors, seeding the code with Serial.println(…) statements may fix (or even worse, create!) timing issues that are unrelated to other algorithm-related bugs. Even still, creative and intuitive use of the serial communication facilities at hand can reveal bugs by the dozens.

1.16.3.LED – the little flashing light

The blinking LED is the embedded equivalent of the ubiquitous Hello World program that nearly all introductory programming classes teach.12 The Hello World program for the desktop computer teaches the fundamental nature of how to get the computer to communicate to you what it is doing and the state of the system or variables. The blinking LED, being the embedded equivalent, also teaches the same, albeit at a much higher level of abstraction.

If serial debug statements are not available (if, for example, the serial library causes the overall sketch size to exceed the memory limitations of the Arduino), the more primitive methods of debugging can still be of help. Although it can be tedious to stare at one or two flashing lights to verify the current state of the program, it is better than staring blankly at a little grayish black centipede-looking computer that appears to be doing nothing.

It is relatively easy to cause a correctly wired LED to light up:



And to shut off:


(See 1.20Arduino Code for more complete examples Arudino code.)

  1. Programming

The embedded computer is usually very limited by slow execution speeds and static memory space.Error: Reference source not found While a desktop computer, through disk caching, has a virtually unlimited amount of memory, the embedded system has a hardware defined amount of available memory. When making the shift from the desktop programming environment to the embedded computer, concentrated effort should be shown to minimize program size, create efficient and accurate algorithms, and use available memory efficiently.

1.16.4.Overall Program Size

Some programmers, especially those that come from the PERL world, are especially adept at compressing their algorithms into miniscule space. When working on embedded systems, programmers tend to think that they need to crunch too. The truth is, without the standard operating system overhead that dominates most of the size of the PC application, the average program is quite small.Error: Reference source not found

Resist the temptation to crunch programs down to their bare bits by recycling variables and combining statements. In reality the program space saved is quite small and the deficit created in the ability to understand the program later by yourself or someone else is too great a risk to justify the effort. Yes, the computer is tiny and space is limited inside it, but there is quite a bit of room for your program inside that little chip.

An astute attention to the process flow of an algorithm and the whole program should provide areas that can be simplified without eradicating the sense of good top-down design and flow.

1.16.5.Speed – Algorithmic Efficiency

Desktop computer programmers often try to make their programs efficient – maximizing performance.Error: Reference source not found As long as the program runs fast enough, they are in the green. When excessive wait times start factoring into the use of the program something is done to speed up the process. This habit is worsened by the high speed of the modern computer: the difference between a sloppy algorithm and a well written algorithm may be a massive one thousand clock cycles, but the processor eats that up in one tenth of a second or less.

Part of the definition of an embedded system specifies that it must be reactive. For it to be fast enoughis not acceptable. The system must respond or it is called broken. For this reason, speed is often considered a constraint for an embedded system.Error: Reference source not found

Ninety percent of programming time is spent on maintenance. It only makes sense to spend time writing software that can easily be maintained.13 Unfortunately readability and speed are often at opposite ends of the programming spectrum because structured code “consists of a modular collection of smaller functions that call one another as required,”Error: Reference source not found and each and every function call or return has a significant processing overhead. The number of effective function calls in a program after it is compiled can be greatly reduced without affecting program structure and readability in a few ways.

Inline functionsError: Reference source not found

One way of minimizing the number of actual function calls without sacrificing the readable, maintainable structure that has been implemented is to use an inline function in place of a normal function. In C/C++, the inline keyword as a function prefix tells the compiler to treat the function as a bit of code that will be inserted wherever the function call is found.

Function inlining has the benefit of removing function call overhead by inserting the body of a function in the place of a function call. The obvious tradeoff is that, if a function is called numerous times or is a large body of code, the bloated program image (from the extra copies of the function) can be a problem for systems with very little program storage memory.

Macro functions (or parameterized macros)14

A macro function is like an inline function but it is processed differently. A compiler that supports macros is allowing “an identifier to be associated with a text string.”15 Macros are handled by the pre-processor and so the compiler never knows the difference. A macro function is simply a parameterized macro definition. Because a macro can only be one line, the allowable complexity of a macro function is reduced considerably and the worry about the program size becoming bloated from overuse is removed. (For more information, see 1.20Macro code.)

Many of the simpler functions in an embedded system can be reduced to macro functions. If your language supports them, macros can be a very effective way to minimize the work that a processor actually has to do while still allowing for some semblance of organization, and if used creatively enough, can even make source code more portable between different processors.

1.16.6.Memory Usage

In a desktop computer system, memory is virtually infinite. If memory starts to become sparse, disk caching algorithms can swap out other programs from memory to allow complex algorithms to use as much memory as is needed. An embedded system’s memory is not so vaguely defined. Embedded microcomputers contain a static RAM sizeError: Reference source not found.

The average microprocessor has less than a megabyte of built in memory – including program space, RAM, and non-volatile memories like EEPROM and Flash. The ATmega168 microcomputer is one of two options for the Arduino development board and contains a total of just over 17KB onboard memory (16KB Flash, 512B EEPROM, 1KB SRAM).

With paper-and-pencil arithmetic, there is no limit to the number of digits that numbers can have. However, numbers processed by a computer use hardware that is designed to handle a limited number of binary digits (‘bits’).”Error: Reference source not found

When creating variables for use in programs consider the application and its requirements. If a variable truly needs to hold a floating point decimal, make a float. But most circumstances do not require the use of enough decimal places to justify the required space (probably 4 bytes). When working with floats the cost is even greater due to the arithmetic processing overhead. Often loop counters can be stored as a char or byte to save space over an int. Be careful to check the constraints on your variables though. When a signed variable overflows, it goes negative. If a loop counter overflows, the loop becomes an infinite loop.


My dad went to mechanical engineering school with a slide rule. He tells a story of modern rocket scientists being asked to land on the moon using only three decimal places. Apparently they said it can’t be done within an acceptable margin of error. However, the scientists of forty years ago supposedly did it.

At the most basic level, computers are just glorified calculators. Nearly every program written to do something substantial has a basic requirement of complex math functions – especially modern games. At some point, either because of mechanical limitations or due to slack in the method of calculation, a computer can no longer guarantee the accuracy of the function it is calculating. Calculating to this extreme is a very good way to exhaust a lot of time and energy for a few percent error decreases. The trade off is between accuracy and time: “Given the correct algorithm and enough computer time, any desired level of precision is possible.”Error: Reference source not found

Whether or not the scientists of forty years ago were able to successfully land on – and return from – the moon with only three decimal places on their slide rules, a computer approximation of a root or logarithm is probably acceptable to the typical embedded application.

Truthfully, the side of the speed versus precision debate that you sit on depends wholly on your application. A ±10% error may be acceptable when using the sin() function to draw a circle on the screen, but is it really acceptable for a weapons targeting system? On the other hand, I wouldn’t want to be the fighter pilot waiting for the targeting computer to calculate a missile trajectory to my enemy.

A lot of work has been done by a lot of people to find easier ways to compute acceptable approximations for roots, trig functions, logarithms, polynomials, sorts, searches, and any other computationally intensive function. With documented algorithm research publicly available in a library or on the internet, implementing a slow, inefficient, or inaccurate algorithm for your complex math function is ill-advised.

  1. The Real Time Operating System

In a desktop computer, a long list of programs is all required for the computer to stay usable. Programs to manage user input, USB devices, data storage devices, networking, and to update the display are all required to run concurrently. However, until recently a computer could only physically execute one program at a time. The illusion of a multitasking computer comes from the operating system switching between all programs at high speed – each program gets a small section of time to run on the processor. The benefit of the operating system is that it allows separate programs to be written to be independent of each other, versus the alternative of requiring one huge program to handle all of the various tasks.

In larger embedded projects, such as cell phones and other consumer electronics, the same problem arises. The embedded system must

“manage what amounts to a number of individual and distinct sets of software. […] A big monolithic program tries to handle all of these functions using carefully constructed logic to sequence all activities and (perhaps) interrupts to drive some of the I/O operations. The logic that starts off as beautiful, highly organized structure usually crumbles into a convoluted mess with each new feature and bug fix.”Error: Reference source not found

In writing software for a complex embedded system, one huge subroutine-divided program can be written to manage the display, user interface, and computation tasks, or each task can be divided into software modules – “more or less independent programs that share all the same resources.”Error: Reference source not found

1.17.The context switcherError: Reference source not found

In order to allow for each task to be given a time slot on the processor, a context switcher is given control of the processor at regular intervals. In essence, the context switcher is the point for implementing the RTOS. It is the heart of its operation. When the context switcher is run it saves the register data for the previous task and loads the register data for the next task. It then hands over control of the processor to the next task.

To determine which software module, or task, to activate each time tasks are switched, one or more scheduling algorithms are implemented in the context switcher. Depending on the RTOS implementation, smarter scheduling algorithms can yield better performance results for different systems. Common scheduling algorithms include Round-Robin, time slicing, and rate monotonic scheduling.2Error: Reference source not found

1.18.When to use an RTOS

Part of the benefit of modern electronics is the self-sustained and modulized nature of devices is almost at a plug-n-play level of interoperability. Most simple liquid crystal displays have a built in display controller (usually an HD44780 or compatible) that takes care of updating the display from internal memory. Many common electronic components are similar and only require intermittent serial programming to remain functional.Error: Reference source not found Devices that take advantage of display controllers or similar co-processors are actually capable of (and required to) execute more than one program at a time.

There is a fine line between needing simultaneous tasks and needing to casually update discrete systems at unimportant intervals. In embedded applications where multiple tasks need to appear to happen simultaneously, an RTOS should be used to handle the load of switching between the separate tasks. Commonly, any embedded system that requires real time response to user input (such as updating a display to match what key on a keypad was pressed) will require an operating system to keep the code clean looking and (more importantly) the system responsive.

1.19.How to write programs for the RTOS

When a real time operating system is running the show, an entirely different approach to programming the embedded system must be taken.

“In many ways the RTOS twists our programming thinking inside out. Instead of partitioning a problem into subroutines, break it up into complete executable units. Think in terms of concurrent activities, not routines that execute only when called.”Error: Reference source not found

Each task should be divided into its own program. If a display and keypad are present, “make one task a keypad handler. Let it run all of the time, passing keypad results to other tasks through a data structure.”Error: Reference source not found Some other tasks could be: updating the display coprocessor, logging data to memory, communicating with other devices in a network, or managing other user input devices.

1.19.1.Debugging with the RTOS

With the added benefits of concurrent tasks executing at the same time, debugging can become really complex. With the context switcher regularly switching which task has control of the processor, it is easy to imagine a linear relationship between time and the task that currently has control of the processor. However, it is important to realize that, due to the rapid and unpredictable succession of tasks through the processor, it is not a viable solution to expect to debug inter-task communication under this model.Error: Reference source not found

If, instead, we “conceive of a model where all the tasks are running simultaneously,”Error: Reference source not found we can approach debugging in a much more reasonable way. Even better, programming tasks for this model should result in tasks that are even more independent and secure in their data modification.Error: Reference source not found

Because of the shared resource model that the RTOS permits, the ability to save the current state of the microcomputer is still an effective method of debugging. Simply create a task that will execute once per second and copies registers and memory locations, especially the task control data structures. With a snapshot debug task you can easily watch all tasks, including the task scheduler.

1.20.Arduino RTOS?

As the Arduino bootloader and software now stand, in version 0007, no RTOS exists.

  1. Conclusion

In this modern age the desktop computer surrounds us, but its very nature is limited. The large display and power requirements make the desktop computer inefficient and expensive to use for almost all portable applications.

Enter the embedded system. The reduced complexity of the embedded system removes some of the benefits that the desktop computer allows: a large screen, flexible user input, and near unlimited processing power. But the embedded system, because of its reduced complexity, allows for much more freedom than even a laptop computer. The scope of an embedded application is limited only by budget and imagination.

Although the limited facilities of the embedded system can make programming and especially debugging difficult, there are is a whole set of tools to help fill in where the system lacks. In addition, modern desktop debugging techniques can be applied with a little ingenuity.

Specifically, the Arduino development board for the ATmega8/168 series microcontroller allows for a number of complex tasks to be easily achieved by the beginner embedded system programmer. The USB connectivity and built in serial port make uploading programs and debugging much easier than most embedded development platforms.

The limited memory and processing speed make the embedded system the perfect place to practice efficient and effective programming skills.

When the boundaries of the embedded processor start to feel constricting, a real time operating system can help ease the pain of the single task style inherent to most processors, but especially oppressive in the embedded system where processor speed is already at a premium.

All this boils down to an entirely different take on computer programming. The ubiquitous windows application is no longer the brick wall around the programming talent that you possess. Break out of the computer programming mold and into the embedded world.

  1. References

  1. Macro code for C

(Extracted from C: An Advanced IntroductionError: Reference source not found, see Reference)

Simple Macro Definitions:

#define NULL 0

#define EOF (-1)

#define GET getc(stdin)

After the above macro definitions have been processed, every occurrence of NULL, EOF and GET will be replaced by the corresponding right hand side. For example, every occurrence of


will be replaced by the string


Macros can be used to make limited changes in the syntax of a language. For example, the macro definitions

#define begin {

#define end }

can be used to make C programs take on a pascal-like appearance. Using these definitions, a while statement can be written as

while (e)






Parameterized Macro Definitions:

The second form of the macro definition is a parameterized version of the first form. Prior to the replacement of identifier by the token-string, all occurrences of the formal parameters in token-string are replaced by the corresponding actual parameters. Actual parameters in a macro must be separated by commas.

Some examples of parameterized macro definitions are

#define getchar() getc(stdin)

#define putchar(x) putc(x,stdout)

#define MAX(x,y) ((x)>(y)?(x):(y))

#define MIN(x,y) ((x)>(y)?(y):(x))

#define UPPER(c) ((c)-`a` + `A`)

/* “c” must be lower case */

#define LOWER(c) ((c)-`A`+`a`)

/* “c” must be upper case */

Definitions of the macros getchar and putchar are taken from file stdio.h; macros MAX and MIN return the maximum and minimum parameter values, respectively; macros UPPER and LOWER return the lower or upper case character corresponding to their arguments, respectively. […]

A parameterized macro call is similar to a function call. […]

  1. Inline functions

(See 1.16.4 Overall Program Size)

/* An example of what inline function declarations might look like: */

inline int max(int x, int y){

return ((x)>(y)?(x):(y));


inline int min(int x, int y){

return ((x)>(y)?(y):(x));


/*Ex1 using the inline functions makes the object code behave as if this had been written: */




printf(“%d is greater than %d”,((x)>(y)?(x):(y)), ((x)>(y)?(y):(x)) );




/*Ex2 using the functions as if they were not inlined makes the object code behave as if this had been written: */




printf(“%d is greater than %d”,max(a,b),min(a,b));




The example Ex2 would require the processor to create and destroy two extra stack frames.

  1. Arduino Code

A sample program that will flash an LED connected to pin 13 of the Arduino.

/* flash an LED every 1/2 second */

byte ledPin = 13;

byte ledState = 0;

void setup(){



void loop(){


ledState =! ledState;

delay(500); //in miliseconds


A sample program to that will light an LED according to the status of another digital pin.

/* light up an LED according to the state of a switch */

byte ledPin = 13;

byte switchPin = 12;

byte ledState = 0;

void setup(){

pinMode(ledPin, OUTPUT);

pinMode(switchPin, INPUT);


/* the loop function is essentially a circular function, since it gets executed again after every return. */

void loop(){


ledState = digitalRead(switchPin);


A sample function from the Arduino tutorial demonstrates using the internal clock to time code execution at regular intervals.Error: Reference source not found

/* Blinking LED without using delay

* --------------------------------


* turns on and off a light emitting diode(LED) connected to a digital

* pin, without using the delay() function. this means that other code

* can run at the same time without being interrupted by the LED code.


* Created 14 February 2006

* David A. Mellis

* http://arduino.berlios.de


int ledPin = 13; // LED connected to digital pin 13

int value = LOW; // previous value of the LED

long previousMillis = 0; // will store last time LED was updated

long interval = 1000; // interval at which to blink (milliseconds)

void setup()


pinMode(ledPin, OUTPUT); // sets the digital pin as output


void loop()


// here is where you'd put code that needs to be running all the time.

// check to see if it's time to blink the LED; that is, is the difference

// between the current time and last time we blinked the LED bigger than

// the interval at which we want to blink the LED.

if (millis() - previousMillis > interval) {

previousMillis = millis(); // remember the last time we blinked the LED

// if the LED is off turn it on and vice-versa.

if (value == LOW)

value = HIGH;


value = LOW;

digitalWrite(ledPin, value);



  1. Review Questions

  1. What is the purpose of an embedded system?

  2. What are some of the benefits of embedded programming?

  3. What are some of the challenges of embedded programming?

  4. What is the typical limitation on embedded programs, memory or speed?

  5. What are some examples of embedded computers in the world today?

  1. Review Question Answers

  1. The purpose of an embedded system is to provide cheaper re-engineering and feature set changes for an electronic product.

  2. Not being limited to the desktop or internet computing platforms.
    Not being limited to the scope of an operating system

  3. Debugging

  4. Trick question: both.

  5. Cruise control, stoplights, computer keyboards, guitar distortion effects, sound boards.

1 The obvious exception to this rule is the implementation of a self-destruct mechanism in the system – a weapon perhaps?

2 The round robin algorithm implements thread priorities and gives every task its fair chance to run, in priority order. The rate monotonic scheduling algorithm uses a formula to compute which tasks will take the longest to execute and gives each task its chance based on the execution time. Error: Reference source not found

1 Lewis, Daniel W. Fundamentals of Embedded Software: where C and assembly meet. Upper Saddle River, New Jersey: Prentice Hall, 2002.

2 Grehan, Rick, Robert Moote, Ingo Cyliax. Real-time programming: a guide to 32-bit embedded development. Reading, Massachusetts: Addison Wesley Longman, Inc., 1998.

3 Leupers, Rainer. Code Optimization Techniques for Embedded Processors: Methods, Algorithms, and Tools. Boston: Kluwer Academic Publishers, 2000.

4 The Intel 4004 Home. Brandon Gray Internet Services, Inc. 5 April 2007 </qa4004.htm>.

5 /wiki/Embedded_system

6 Arduino - HomePage. 6 April 2007 </>

7 “Ada (programming language).” Wikipedia, the free encyclopedia. 7 April 2007. Wikimedia Foundation, Inc. 8 April 2007 </wiki/Ada_programming_language>

8 Ganssle, Jack G. The Art of Programming Embedded Systems. San Diego, California: Academic Press, Inc., 1992

9 “Java SE Embedded Use.” Sun Microsystems, Inc. 6 April 2007 /javase/embedded/index.jsp

10 Wiring. Hernando Barragán. 4 April 2007. <.co/>

11 “Ten Secrets of Embedded Debugging.” . CMP United Business Media. 2 April 2007. </showArticle.jhtml?articleID=47208538>

12 Belotsky, George. “Black Box with a view, Part 2.” . 2 February 2006. O’Rilley Network. 2 April 2007. </pub/a/onlamp/2006/02/02/microcontrollers.html?page=1>

13 Walls, Colin. Embedded Software: the works. Burlington, MA: Elsevier, 2006

14 Belotsky, George. “Black Box with a view” . 10 March 2005. O’Rilley Network. 2 April 2007. </pub/a/onlamp/2005/03/10/microcontrollers.html>

15 Gehani, Narain. C: An advanced introduction. Rockville, Maryland: Computer Science Press, 1985.

Скачать документ

Похожие документы:

  1. Report to the department of education employment and workplace relations national study into the successful transition of indigenous children into schools project report rft 13226

    ... particular literacy and numeracy skills embedded in the learning activities. ... the MCEETYA–funded report on successful transition programs from prior-to- ... , 2, 29-37. Heaviside, S., Farris, E. & Carpenter, J. (1993). Public School Kindergarten Teachers ...
  2. Report on computational science and engineering support activities at daresbury laboratory 2000/2001

    ... for hierarchical programming using combinations of OpenMP and MPI. Report on ... in ChemShell include Mechanical Embedding Electrostatic Embedding (for QM codes GAMESS ... .uk/CFS. [5] J. Nieplocha and B. Carpenter, Armci: A Portable Remote Memory Copy ...
  3. Report of the Second Meeting of the Ad Hoc Technical Expert Group on Biodiversity and Climate Change * * Note by the Executive Secretary Introduction

    ... Fourth Assessment Report and Technical Report V1 on Climate ... and ways of embedding the preferences of local ... and linkages with other programs. In particular, policies ... . 2005a; ,W.N., Hughes,T.P., Folke,C., Carpenter,S.R. & Rockstrom,J. (2005b) Social- ...
  4. 1997 research and publications report table of contents

    ... I, 1997, 'An embedded technique for discovering implicit ... Deakin University Jayasinghe L Y, Marriott P J, Carpenter P D, & Nichols P D, 1997, ... International Symposium on Mathematical Programming 1997', August, ... Study - Interim Report 1. A report to the ...
  5. Abelló, P., Carbonell, A., Torres, P. (2002). "Biogeography of epibenthic crustaceans on the sh

    ... the pycnogonid mentioned in this report. Carpenter, G. H. (1892a). "A new Nymphon ... how reliable are computer parsimony programs used in systematics?" Zeitschrift für ... Herdmania momus (Ascidiacea; Pyuridae), gonad embedded in paraffin, SEM Miyazaki, K., ...

Другие похожие документы..