Tasks

For discussion of multitasking, we need to define a task. In its simplest form a task is any one thing to done by a controller. Think of an army with an overall mission to accomplish and many individual soldiers to carry it out. The overall mission, ”Drive out that dictator,” is the job, but the tasks might be, ”Drive this supply truck to the front lines,” or, ”Sit in this trench until ordered to advance.” For a controller, a task might be to wait for and process input from a keyboard or to keep a motor running at a set speed. A task can be as simple as a single routine having a few lines of code, or it can be an entire set of nested routines. Task divisions can be arbitrary as long as they relate to the functional parts of the overall job. Most important, tasks represent a way of thinking that logically divides the job and leads to the effective use of the microcontroller.

Priority

Should a task ‘move to the head of the line’ when other tasks have been waiting longer to run? Having different priorities in a system implies that some activities are more important or more urgent than others. We are used to degrees importance in the realm of politics and big business, and we expect to yield to fire trucks and ambulances because they have greater urgency. The same thing can be applied to individual tasks. Issuing a pulse to a stepper motor may be more urgent than the computing an average. Stepper pulses must come at regular times, whereas a computation can be done whenever time is available. The first-level processing of incoming readings is more important than subsequent processing if the new readings will be overwritten by the next readings if they aren’t processed and moved. In a realtime system the priority may be a measure of importance or urgency, or it can reflect the duration of a task–a very short task could run with higher priority because it will be over and done quickly, rather than any inherent degree of importance.

Preemption

Should a task not just move to the head of the line, but stop and replace the task that is currently running? If so, it has preempted the running task. The concept isn’t difficult but the implementation can be challenging because the preempted task could be in the middle of something that shouldn’t be interrupted and, at a minimum, the various registers must be saved so the preempted task can resume where it left off when it gets to run again.

Realtime Thinking

Most courses treat multitasking as an advanced topic. I hope your perspective will change as you come to see that it is the most fundamental part of efficient programming and deserves your attention as early as possible. Once you understand it, you can have your microcontroller look like it is doing many things all at the same time—it will never seem to be unavailable and will always be checking for something to do.

Beyond single-program thinking

If you have used only traditional techniques of programming, you will find, as your applications grow more time-critical, that a single program approach becomes awkward. When you have several external hardware devices that need to be served at the same time, your challenge is to make sure each device is satisfied.

Perhaps all your software has only had one thing happens at a time…in sequence (that is why computers were called sequential machines). If a speech chip had to say something, you programmed the processor to put out the appropriate code, pulse the write line, and then wait until the phrase was done before going on to check for some new input from the keypad. Nothing could be recognized while the processor was waiting for the ‘done’ from the speech chip. To move on in your programming skills you must develop a new way of thinking about program flow…you can’t let the flow get stuck if something isn’t ready yet.

Realtime

Although the term means different things to different people, I apply realtime to any system that respond to inputs and supply outputs fast enough to meet user or external hardware requirements. For example, a keyboard entry system is realtime if it gives you some feedback quickly enough for you to feel confident that the system “heard” you. If a “beep” is fed back to you within 100mSec, you feel confident that the system recognized the input “right away.” So, a keyscan routine that repeated every 100mSec would probably meet the requirement of fast enough. Likewise, your eyes and brain cannot assimilate new digital display information more quickly than perhaps 5 times a second….numeric values that are rapidly changing might better be updated only a few times a second. On the other hand, a stepper motor ought to be sent a new step pulse at a regular time with millisecond precision, so this is a much more critical time requirement. Most serial ports have a single-character buffer, so at 9600 baud every incoming character must be picked up within about 1mSec (10 bits @9600 bits/Sec=960 char/Sec »1mSec). Outgoing (asynchronous) characters can go whenever the processor is not busy, assuming there is no other time constraint on message transfer. The same considerations would apply to collecting data via an A-D converter. Depending on how rapidly the incoming voltage is changing, the reading might need immediate retrieval or might be held for quite some time. How rapidly should a flow valve be adjusted for a process? How quickly should a motor be supplied a new speed setting? All of these are questions relating to what is fast enough.

Efficient Design With Microcontrollers (Part 3)

Efficient software is easy-to-understand software that runs faster and requires less code.

Software Development Strategies

  1. Top-Down Development This is an approach to programming which relates to understandability and the use of functions. Essentially, it is an approach that starts with the broad overview (the “top”) and then moves (“down”) to the details. Using such an approach, you first write the main program (the main() function in C). In doing so, you make liberal use of functions that you have yet to write and assume that later on you will write them and that they will perform in specified ways. For example, if your final application needs a printing device, during development call a (at that moment non-existent) printf() function with a pointer to the desired message. If you need an A-D reading, during early development assume some function will exist to return the reading when called. Once you’ve written the main program, the “down” of “top-down” consists of writing the first level of functions. These in turn may use other functions, which you will also write later. Finally, you write the detailed drivers—the most basic functions. (If you would like to see an example of this 3-level programming, start with Figure 21.1 on page 236 and then follow the code in the rest of that chapter.) Continue reading

Efficient Design With Microcontrollers (part 2)

Efficient Electronic Hardware [taken from C and the 8051]

  1. Use as few supply voltages as possible. With the right analog devices, a logic supply (usually 5V, but recently going as low as 2.7V) can often suffice. Microphone signals and most sensor signals never get that big. There is no law that all analog processing must be done with ±15V. Often, if the signal goes into an A-D converter and the signal-to-noise ratio is not a problem, it is unnecessary to amplify it to such levels.
  2. Use as little current as you safely can, and design so the high current drains are the shorter duration ones. Continue reading

Efficient Design With Microcontrollers (Part 1)

[I take the next few posts from C and the 8051]

An efficient microcontroller application involves designing with a minimum of external hardware necessary to allow the software to keep up with all of its tasks.

Efficient is not always an intuitive or even obvious concept. With many years’ experience in assisting customers and teaching students, I have strong personal opinions about what constitutes efficient use of microcontrollers and enumerate a few below:

  1. Transfer as much of the project’s functionality as possible to software. Only if you can have just one processor, and it is quite busy, should you allow yourself more hardware.
  2. Use as few port pins as possible.
  3. If you transfer debouncing and calibration to software, you reduce construction costs and simplify hardware troubleshooting. (Debouncing is discussed beginning on page 321.)
  4. Use functions rather than straight-line programming so code can be re-used.
  5. Use tables, interpolation, and simplified calculations with the smallest-sized variables to make code faster and smaller with simpler math operations.

This is what I mean by “efficient.” Next time I will describe what I see as efficient hardware. Some of these ideas date back many years. Do you think they are outmoded with the higher-performance ICs available today?

Moderated Comments Only

I am getting strange (no follow) comment traffic with no written content and nothing to do with my posts or the site, so I am forced to require all comments to be moderated. I apologize for the delay for those of you with actrual comments–I have no desire to limit friendly (or critical) comments, and anything on topic will be approved. I will try to approve every day.

Why the personal computer diverged from the embedded computer

It may surprise you “young” readers to hear that for many years there was no difference between a computer used for dedicated applications and one that could run different programs at different times! When Intel’s 8-bit 8008 gave way to the 16-bit 8086 they also produced the 8-bit-interface 8088; the next step had the 80286 but still had the (I believe 8-bit-interface) 80186; the 80286 led to the 386, and the 486. after “4″ the marketing folks substituted “Pentium” for “5″; since then the non-dedicated program market has moved out of sight. Continue reading

A new e-book?

In checking if this (newly moved) web site was coming up on search engines, I did a search for the title, C and the 8051. It was a surprise!

I have known for some time that my ex-publishers chose to (illegally) permit the third edition on Google books and that someone had scanned in the entire 4th edition (also illegally). After chafing for a bit and exploring what steps might be necessary to fight it, I decided it wasn’t worth the effort. Those who want to Xerox about 500 pages will find it costs as much or more than buying the official book and still leaves them without a cover or binding. Continue reading

When knowing Assembly Language is good

Is it vital to programming to know how the computer works? No…probably not with the high-end applications of today. I have only a vague idea of how WordPress is combining the pieces of this post onto your screen and have never made a study of HTML or PHP. But when you are working with low-end computers, closer to the actual machine operations, it can make a difference. Continue reading

Microcontrollers and Emulators

It has been quite some time since integration capabilities first allowed the processor, memory, and I/O to all go on one chip and the name changed from microprocessor to microcontroller

The problem in the early days was the development process–it was quite feasible to get a large quantity of a device built with a fixed program permanently integrated (if you were using a micro in a high-volume application such as an engine controller in an automobile), but getting just one device with a new iteration of a program you were developing was a different matter. Continue reading