0

I want to run a small piece of code on Linux running on a iMX6 dual core system, which toggles some GPIOS every 1ms, with as little jitter as possible. There may be other low priority tasks running on the system.

So I gather I have these options available:

  • CPU shielding: Make my task to use the whole cpu 1, while leaving cpu 0 for everything else. Wasting cpu 1 time is not a problem in my case.
  • Re-compiling the kernel with PREEMPT_RT, and adjust my task priority to guarantee it will wake up every ms.

So some questions in my head...:

1- What are the pros and cons of each case?

2- In the CPU shielding case, would I build a normal user-space program? Or should I write a module with a kthread?

3- CPU shielding case again: What is the status of cpusets vs isolcpus kernel option? That is, for kernels > 4.x, which way is the most effective?

Community
  • 1
  • 1
Luis de Arquer
  • 377
  • 2
  • 8

1 Answers1

-1

FWIW, sounds like the relatively new deadline scheduler best fits your use case. I believe you can use it in vanilla Linux without PREEMPT_RT patchset.

http://retis.sssup.it/~jlelli/talks/rts-like14/SCHED_DEADLINE.pdf

Erik Alapää
  • 2,585
  • 1
  • 14
  • 25
  • But isn't the deadline scheduler a block device scheduler? AFAIK, it just imposes a time limit to grouping block i/o requests, but GPIOs are not block class. Also, I don't really want a maximum latency, I aim GPIO toggling at a fixed point in time (not later, not before) – Luis de Arquer Jan 17 '17 at 15:14
  • @LuisdeArquer I am no expert on Linux kernel scheduling, but as far as I understand it, SCHEAD_DEADLINE can be used for general scheduling, for example to wake up a process to send stuff on a network interface or toggle a bit in a device register. And it is the only scheduler in Linux that approximates hard realtime behavior. – Erik Alapää Jan 17 '17 at 15:16
  • Sorry, I completely misunderstood you. I thought you were talking about [this](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Performance_Tuning_Guide/ch06s04s02.html). I wasn't aware there was a CPU deadline scheduler, I'll have a look. Thanks! – Luis de Arquer Jan 17 '17 at 16:53
  • OK, I think it should fit your needs. If you want, you can accept the answer. – Erik Alapää Jan 17 '17 at 17:11
  • For a single realtime task, SCHED_DEADLINE won't provide guarantees better than SCHED_FIFO and SCHED_RR. If you need hard realtime (missing cycles is unacceptable), you still need PREEMPT_RT. – crosstalk Jan 18 '17 at 03:03
  • @crosstalk To my understanding, even with PREEMPT_RT, Linux can not be considered true hard realtime - for that you need something like OSE or another small, pure hard RTOS. – Erik Alapää Jan 18 '17 at 08:21
  • It sounds definitely useful for several tasks coexisting in the same CPU. But in this case I only have one task (and I can isolate the CPU for that task). The question is more about the advantages of PREEMPT_RT vs (or added to) CPU isolation for a single task, where I want to toggle a GPIO at a point in time as accurately as possible. E.g. produce a 1ms period square signal on a GPIO pin with minimum jitter. – Luis de Arquer Jan 18 '17 at 10:59
  • @LuisdeArquer I think you could use both in your case. From a presentation by J. Lelli: "common question: does it work with PREEMPT_RT ? it's orthogonal to it PREEMPT_RT reduces latencies, SCHED_DEADLINE implements a scheduling algorithm (can benefit from the former) they should work together without any problem :-)" But of course, generating a square wave this way is not optimal... – Erik Alapää Jan 18 '17 at 11:36
  • @ErikAlapää PREEMPT_RT's purpose is to make Linux hard realtime, and it does so (with the caveat that you need to be more careful about driver selection than you do with a purpose-built RTOS). – crosstalk Jan 18 '17 at 14:36
  • @crosstalk At least, it seems some parts of the kernel cannot be used if you need 100% predictable latencies. For example, some allocators. OTOH, it may be possible to allocate all necessary RAM at application start. Also, it seems for some applications, going with a more radical solution like Xenomai is necessary to get hard real-time: slideshare.net/jserv/realtime-linux?next_slideshow=1 – Erik Alapää Jan 18 '17 at 15:29
  • @ErikAlapää That is true. You have to be careful about which modules you load (for example, don't load nvidia, nouveau, or the intel graphics driver) and manually bump the priority of IRQ handlers for devices that you need. Since Linux isn't normally a realtime system, drivers and interfaces don't document their realtime guarantees under PREEMPT_RT, so you have to carefully benchmark drivers before developing an realtime Linux application. – crosstalk Jan 18 '17 at 15:59
  • @ErikAlapää PREEMPT_RT doesn't give applications a way to do memory allocation in hard realtime. You need to allocate everything up front (and perhaps use a userspace allocator). In general, memory allocation is problematic for realtime systems. Unless you know a given realtime allocator's algorithm (such as TLSF) very well, it's hard to determine its worst-case performance (average case is trivial, of course). Also, error handling is usually important in realtime systems and handling an allocation failure is probably as difficult as doing the same task without dynamic allocation. – crosstalk Jan 18 '17 at 16:00
  • @ErikAlapää Xenomai's dual kernel approach has a few advantages over PREEMPT_RT. It gives better worst-case latencies, supports RTDM drivers, and better documents the determinism of its APIs. However, PREEMPT_RT has much better hardware support than Xenomai's dual kernel setup. Note that Xenomai 3 supports both a dual kernel approach and PREEMPT_RT as the underlying realtime OS. – crosstalk Jan 18 '17 at 16:05
  • @crosstalk Aha, I was under the impression that you always needed dual-kernel approach with Xenomai. – Erik Alapää Jan 18 '17 at 16:17
  • @crosstalk & ErikAlapää Thanks for the info! I didn't even know about Xenomai, I am having a look and looks promising for larger tasks. In my particular case, I have tried CPU isolation through the isolcpus command line argument, and it works well enough. I've got my GPIOs consistently toggling every ms, with a jitter of +/- 2us in the worst case, which is more than enough for me. Probably in this particuar case, PREEMPT-RT would not be worth it... – Luis de Arquer Jan 18 '17 at 16:31