Hacker News new | ask | show | jobs
by bradfa 1412 days ago
Tangent: reading this, all I could think was "you're allocating memory in a motor controller?!?" and then "you're using interrupts in a motor controller!?!". Surely the bug write up was good and it is interesting, but all of the actual hard real time systems I've ever seen or talked to engineers who actually worked on them always avoided interrupts and never allocate memory. Both of these activities in hard real time code can produce very unexpected results which may be similar to what the author found with enabling the ADCs in rapid succession.
4 comments

Here "allocation" is all fixed size things pulled from a fixed size buffer at startup. Technically malloc is compiled in the firmware, but it isn't used for anything but some C++ runtime initialization confirmed with debugger breakpoints. The only dynamic use of memory is the call stack, which has only fixed size local variables and limited depth recursion.

Similarly, "interrupts" may not mean what you are thinking. The highest priority interrupt is one attached to the PWM timer that operates the primary control loop that operates in interrupt context. As of a few months ago this is slightly more complicated to accommodate some "soft" quadrature decoding, but the principle is still the same that all motor control is performed in an interrupt context and nearly nothing else is.

Everything else, like CAN communication, is performed in a polling manner in the "main" loop.

Are you out of timers? IIRC the STM32 series typically has timer peripherals that can be configured as encoder inputs.
No, but out of pins connected to timers with the appropriate capabilities.
The "standard" motor control setup for FOC is to do the ADC measurement synchronously with the PWM, to sample the current while the low-side switch is closed. Then the flux angles and voltages are computed immediately afterwards, and the PWM duty updated for the next cycle. This all happens in the interrupt, in a very hard real-time system -- start missing interrupts and all hell breaks loose.

PWM is run as fast as you can get away with, 20 kHz minimum (human hearing). The controller spends maybe 80% of itw time in interrupt context, leaving main context for tasks that are not time-sensitive.

> always avoided interrupts

I'm curious... how does one achieve precise timing without interrupts?

Cycle counting is common. Other options exist like a tight loop watching a counter register etc.
Cycle counting is dead for ARM chips with their wait states and instruction pipelines and lazy stacking. Works great for PICs though.
> Tangent: reading this, all I could think was "you're allocating memory in a motor controller?!?" and then "you're using interrupts in a motor controller!?!".

to be fair, that STM32 from what I can see benchmarks at 550 in CoreMark which puts it above a Pentium I, it's not like they're using a 8051 or a PIC16F... there's likely a lot of spare CPU time