5 ms·
>Keep ISRs small I disagree. If you have interrupt priorities then you can treat your interrupt service routines as the highest priority tasks. As an example l
by barbegal 6y ago
>Keep ISRs small
I disagree. If you have interrupt priorities then you can treat your interrupt service routines as the highest priority tasks. As an example lets imagine a drone controller which has two functions it needs to perform in real time: it needs to vary the PWM signal to the motor controller and it needs to acknowledge radio packets. An interrupt is raised when the accelerometer has new data and another is raised when the radio has received a packet. You could write ISRs which just queues the accelerometer data and radio packets so they can be dealt with by a flight control task and a radio task respectively. Alternatively, you could run the whole of the flight controller inside the accelerometer ISR. This reduces copying of data and context switches. Because the accelerometer ISR now takes longer you need to use the radio ISR to acknowledge the radio packets itself. You split the radio task into two tasks: a low priority task for processing commands and the ISR task which does the acknowledgements.
> Avoid blocking function calls
This can be rewritten as never call functions that block on an action of a lower priority task. It leads to priority inversion in normal tasks and deadlocks in ISRs.
- nsajko 6y ago> I disagree. If you have interrupt priorities then you can treat your interrupt service routines as the highest priority tasks. ... I think "Keep ISRs small" is still a good guideline for most cases. Big interrupt handlers require more system-wide knowledge to verify (e.g., stack space, maximal latency, priority problems, ...). They introduce more coupling into the system, in other words. Of course, this should not be some hard rule, rather just a rule of thumb. I wouldn't like it if some policy like this prevented you from choosing the optimal solution in a case like you suggested.
- barbegal 6y ago> Big interrupt handlers require more system-wide knowledge to verify I think the point I'm trying to make is that sometimes following the rule of "make your ISR small" actually makes this worse because your bigger high priority task can be interrupted or you turn interrupts off or mask interrupts and you end up with even more complexity.
- aidenn0 6y agoSometimes following rules-of-thumb blindly will make things worse. This is one reason why we call them "rules of thumb" rather than e.g. "laws." Another example: if you are shipping over a million units, then adding hardware to simplify software starts to look like a bad trade-off since BOM starts to dominate NRE.
- Gibbon1 6y agoFat ISR's are often really hard to debug. And the more complex state an ISR has the harder it is to communicate with it. That's because with an ISR you are in a state of sin because you always end up with duplicated state.
- lmilcin 6y ago> I disagree. I disagree. I think the idea of "keep ISRs small" is that it is easier to spend time polishing your ISRs to be as small as possible than deal with long ISRs. As soon as you have long running (long is a relative thing) it is extremely difficult to guarantee any behavior of the system.
- barbegal 6y ago> As soon as you have long running (long is a relative thing) it is extremely difficult to guarantee any behavior of the system. I understand your sentiment but simply pushing the work into a task doesn't make guaranteeing the behavior of the system any easier. And I argue that in some cases, it makes it more difficult, if you can eliminate an entire task by putting its processing in an ISR then that reduces the complexity. Handling priority inversion correctly is the example that springs to mind.
- craftinator 6y agoI think that in some cases, large ISR tasks make sense. But, ISRs by nature occur at times not known at compile time, meaning that the longer an ISR runs, the less you'll know about system behavior at compile time. So, if you know that you need a long running process triggered by an ISR, that's fine, make it so; but as a general rule of thumb, the shorter the ISR, the more deterministic your system is. Those ISR runtimes need to be designed to be good fits for the system, or they can cause problems.
- brandmeyer 6y agoRe: ISR priorities. I agree with you somewhat. Technology is always changing. Many architectures don't have a rich interrupt controller. A system built to take advantage of the Cortex-M NVIC will have different characteristics than one that doesn't. For those who are unaware, the NVIC effectively turns the interrupt handling system into a hardware-based FIFO strict realtime task scheduler. The only hard limit is that since all of the tasks are executed on the same stack frame that you need an interrupt stack large enough for the maximum nesting depth. You can safely do much more work in an interrupt handler with such a system than you can in a classical non-nested interrupt-handling system.
- kahlonel 6y ago> You split the radio task into two tasks: a low priority task for processing commands and the ISR task which does the acknowledgements. You contradicted yourself here. You moved the code out of radio ISR to application code, thus keeping the radio ISR small.
- nsajko 6y agoActually, she/he moved the code for acknowledging radio packets into the ISR, relative to the the "by the book" solution of having minimal ISRs.
- kahlonel 6y agoWhy didn’t they move the command processing into the ISR too then?
- nsajko 6y agoI assume the command processing was simply not a predictably small enough of a workload to fit into the time budget for an ISR. Besides, that is irrelevant for his point, he already gave an example of a "big" ISR, it doesn't have to be even bigger.
- kahlonel 6y ago> not a predictably small enough workload Which means ISRs can grow too big. And that’s the reason keeping ISRs as small as possible should be your goal.
- nsajko 6y agoI mean, I (and most people on this thread...) agree with you, I believe it is almost always "nicer" to be consistent and have minimal ISRs. But her/his point (as I interpret it, at least) was that in some situations a somewhat larger ISR may make sense.
- 6y ago
- gHosts 6y agoTry this as a way of thinking about it.... ISR's are random events that preempt your scheduler. Deferred Service Routines run in the same thread as your scheduler. It's excruciatingly hard to write (correct) code that can be interrupted and have it's internals monkeyed with at any clock cycle. Thus the ISR/DSR handoff is a way of sequencing events into a manner the scheduler can handle sanely. Most ISR's are written to be preemptible, it ack the interrupt and enable interrupts. Thus the chance of losing an event is very small. The larger your isr the more you're into the realm of "excruciatingly hard to write (correct) code". Your scheduler may be very simple... eg. only one thread as you described above, but my point applies.
- deepspace 6y agoJust a small correction, related to your specific example. Controlling the motor is a real-time digital control system task, and it needs to be executed at exact time intervals, otherwise you introduce noise and instability into the control loop. "Accelerometer has new data" is a terrible trigger for the control loop. You always want to execute the controller at fixed intervals, triggered by a timer interrupt. Once you enter that timer ISR though, you are correct. You need to run the whole thing, starting with adjusting the PWM according to the result of the previous control loop, then sampling the sensors and finally running the control algorithm, all before exiting the ISR. This is the epitome of a "hard real-time" requirement.
- barbegal 6y ago> Controlling the motor is a real-time digital control system task, and it needs to be executed at exact time intervals This is correct but also the accelerometer data needs to be sampled at the same interval. For this reason, running the control algorithm in lock step with the sensor may be sensible.
- deepspace 6y agoTrue, but sensors do not generally output data at fixed intervals, which is why the most common method is to have the control loop run on a timer interrupt and to have it sample the sensor.