On Sat, Jan 28, 2023 at 9:04 AM Gregory Nutt <spudan...@gmail.com> wrote:
> On 1/28/2023 7:15 AM, Max Kriegleder wrote: > > I am using the tickless OS setting with 1 USEC_PER_TICK and ultimately > > I want to control a stepper motor where I need to delay toggling of > > pins for very short and accurate amounts of time to achieve a certain > > movement profile of the motor - just for information, maybe I am > > thinking in the wrong direction > > It has been some time since I have heard measurements of interrupt entry > latency and context switch times for the OS, but I do remember some > older measurements on an STM32 F4: It required around 10 uS to do > either. Modern MCUs can probably do better but, in any case, you are > working beyond the resolution of the interrupt/context switch capability. > > If for example, you receive a timer interrupt then perform a context > switch to run a task, that would be expected to require something like > 20 uS on an STM32 F4. Could that be the issue? > > You can reduce that interrupt latency by using a separate interval timer > with a high priority, zero latency interrupt; you can eliminate the > context switch by performing the pin toggling in the interrupt handler. > That would still result in a significant, but smaller, delay Controlling stepper motors by toggling pins at "exactly" the right time is an example of something I would probably use a zero latency interrupt for; be aware, though, that doing so will probably require register stuffing since you can't call any OS facilities from a zero latency interrupt. Zero latency interrupts require support in the CPU architecture. I know that ARM supports it and it works great in NuttX. These interrupts exist "outside" the operating system and add no operating system overhead. Even when the operating system is in a critical section or any mechanism that would otherwise delay a task switch or interrupt service, a zero latency interrupt *will* interrupt that and execute right away. In my projects, the latency isn't really critical as long as it's consistent; it's the jitter (variance in latency) that I need to be zero. Since they exist outside the operating system, there is some complexity to rendezvousing from zero latency interrupts back into code that exists "inside" the operating system. You can't, for example, wake up a task from within a zero latency interrupt. In my projects, in order to trigger normal code, the last thing in my zero latency interrupt is to trigger a normal interrupt, for which I use some otherwise unused interrupt vector; within that interrupt, I can wake up tasks, etc. That separate interrupt is not zero latency and therefore its execution might be somewhat delayed but it can wake up tasks, etc. A bit more on stepper motors: I did a project where I controlled steppers using step and direction outputs. In my case, I needed the direction pin to be set first, then I needed the step pin to be pulsed 10us later for 1us. Instead of trying to do this in software, I used the timer peripherals of the MCU. This used a STM32 part. I don't have the information in front of me right now but if I recall correctly, I connected the step signal to a timer-capable pin and used a combination of the timer's PWM feature and one-shot. For the PWM, I configured the profile to produce 10us of low followed by 1us of high output and configured the one-shot feature to automatically stop the timer enable after one pulse. Maybe it's called one pulse, rather than one shot. In my zero latency interrupt, I set the direction output by register-stuffing its GPIO, then I enable the delayed step output by register-stuffing the timer enable. Then my zero latency interrupt returns and allows normal code to run and hardware would do the rest. Be aware that not all STM32 timers support the one-shot/one-pulse, and even within the same part, some may while others may not, so be extra careful when designing this part of your circuit. You could also accomplish the above purely in software via zero latency interrupts and a state machine. Hopefully something in this post is useful... Cheers Nathan