How an Interrupt Driven Embedded System Can Save You Power
What is an interrupt driven system?
Our lives revolve around energy. This is a fact I’m reminded of every time there’s a bad storm in my area and the electricity goes out. In the world of advanced driver assistance systems (ADAS) power also reigns supreme. Semi-autonomous and self-driving cars need more and more sensors to operate effectively, making low power operation increasingly important. It just so happens that how you interact with all of those sensors has a huge effect on your system’s energy consumption. There are three main schemes you can use to gather data from your sensors: continuous polling, fixed interval processing, and interrupt processing. Out of these three options, interrupt processing will save you the most power by gathering data only when data is available. There can be a few problems, though, that you’ll need to watch out for when using interrupts.
Data Gathering
As I said before there are essentially three ways to handle events or gather data in a system: polling continuously, polling at intervals or handling events triggered by interrupts. Let’s quickly go through how each of these work
-
Continuous Polling - This is by far the simplest way to handle events. In this arrangement, your code will check on peripherals continuously until one raises an event flag. Once that marker has been noticed, your program will take care of that event and then go back to polling.
-
Interval Polling - In this method instead of polling continuously you poll at certain increments. Let’s say you have a LIDAR array that completes 20 full 360° sweeps in one second and stores each sweep for processing. You could set your program to sample that data at 20Hz and get a full 360° picture every time.
-
Interrupt Processing - With this scheme, your program doesn’t poll its peripherals to see if they’re ready, it waits for them to interrupt the program. So, whenever a sensor has something to say to the processor it will send an interrupt signal, asking the controller to stop whatever it’s doing and handle that event.
Use interrupts to make your system more energy efficient.
Why Are Interrupts More Efficient?
Utilizing interrupt service routines (ISRs) in your program can help you greatly reduce your system’s power usage. They do this by keeping your microprocessor from continuously running in idle loops that do nothing. Interrupts are also more simple to implement than interval polling.
Remember that with continuous polling, and even interval polling, your microcontroller unit (MCU) is checking peripherals regardless of whether they are ready. If you have a system that is constantly updating anyway, this may not be a big deal. However, if you’re checking a sensor 10 times a second and it only updates once per second, you’re just burning power the other nine times. Most MCUs now have sleep states they can enter when not executing instructions. Using interrupts allows your system to wake on events, deal with whatever is happening, and then go back into power saving mode.
If you know exactly when a sensor will be ready to communicate you might think about using interval-based polling. After all, you won’t waste energy because you know when events are coming up. Time-based architectures are difficult to implement, though, and the same effect can be achieved with easy to use interrupts.
Make sure not to corrupt any data when executing ISRs.
What To Watch Out For
Interrupts can be powerful but come with a risk, just like pointers in C. If you alter variables or other parts of your code during an ISR you could upset the program when it returns to main. In addition, you need to be aware of how long your code will take to handle an interrupt event.
When writing ISRs you need to take care not to disturb any essential data in the main program. There is always a risk of upsetting another variable or piece of memory on accident, which is why it’s important to test your system while it’s running. Usually, an interrupt will save what’s in your registers and other critical pieces so that your program can resume normally after the ISR is finished. That being said, you should still take care not to write over critical variables or otherwise disturb whatever function might be running when an interrupt occurs.
Sometimes you’ll have critical functions that must finish their operations before an interrupt can be handled. Be very careful when disabling interrupts for these pieces of code, as you can then introduce long interrupt latencies. You may not care right now if your system is signaling that tire pressure is low. Though you’ll care a lot more if one of your ultrasonic sensors is saying that your car is about to crash into something. To keep latency down you should assign your functions and ISRs different priorities so that mission-critical code is always executed. You should also re-enable interrupts as soon as possible in your normal code and during ISRs.
There are lots of different ways to make your code perform more efficiently, but not all of them have to do with compiler optimizations like loop unrolling or function inlining. Sometimes the way your code interacts with other parts of the system can have an even greater effect. Using interrupt processing instead of any kind of polling will almost always save you energy. Just be careful that you don’t corrupt your program in an ISR or ignore a critical interrupt signal.
As I just said, your sensor communication is only part of the issue. The software you choose to make your program can also greatly impact the performance and efficiency of your system. TASKING has developed a wide variety of products that are made specifically for smart vehicles. They have pioneered things like a standalone debugger and an excellent static analysis tool that can help you write fast and excellent code.
Have more questions about handling peripherals? Call an expert at TASKING.