0

I have a project running a 32x32 LED grid based on these instructions:

https://learn.adafruit.com/adafruit-rgb-matrix-plus-real-time-clock-hat-for-raspberry-pi/driving-matrices

which relies on these drivers:

https://github.com/adafruit/rpi-rgb-led-matrix/

At the same time, my Rasp Pi 2 is running a full Bitcoin node. A python script interacts both with the bitcoind server via JSON-RPC, and the LED matrix.

I found that when the Adafruit driver is running...

from rgbmatrix import Adafruit_RGBmatrix

matrix = Adafruit_RGBmatrix(32, 1)

...many other processes involving Bitcoind and the JSON-RPC interface time-out. Sometimes the calls never return, sometimes it takes up to an hour!

I'm stuck on trouble-shooting this. I don't even know how the LED matrix / GPIO signals are affecting the other systems. Staring at htop I don't see anything strange when it's running. But for sure, when I run my scripts WITHOUT Adafruit_RGBmatrix I have zero problems interacting with bitcoind server.

What kind of resources does Adafruit_RGBmatrix suck up? How can I monitor it? How can I retard the driver for a moment to get my other process through?

Sorry this is a confusing one, throwing a hail mary here...

2 Answers 2

1

Some threads of the rpi-rgb-led-matrix library are running with real time priority. That means that if they have work to do they will preempt all non real time processes.

To stop the library running with real time priority comment out lines 47-51 of rpi-rgb-led-matrix/lib/thread.cc.

i.e. change

void Thread::Start(int priority) {
  assert(!started_);
  pthread_create(&thread_, NULL, &PthreadCallRun, this);

  if (priority > 0) {
    struct sched_param p;
    p.sched_priority = priority;
    pthread_setschedparam(thread_, SCHED_FIFO, &p);
  }

  started_ = true;
}

to

void Thread::Start(int priority) {
  assert(!started_);
  pthread_create(&thread_, NULL, &PthreadCallRun, this);

  /*
  if (priority > 0) {
    struct sched_param p;
    p.sched_priority = priority;
    pthread_setschedparam(thread_, SCHED_FIFO, &p);
  }
  */

  started_ = true;
}

I have no idea what bad effect this will have on the running of your LED display.

3
  • Yes thank you! This works for now, I will test more to see if the lower priority causes any other downstream issues
    – pinhead
    Commented Feb 11, 2016 at 22:07
  • how did you find that so fast?
    – pinhead
    Commented Feb 11, 2016 at 22:13
  • github.com/adafruit/rpi-rgb-led-matrix/tree/master/lib has a comment about priority and I know to look for sched_priority as I have used it myself.
    – joan
    Commented Feb 11, 2016 at 22:41
0

Linux is a multi-user, multi-tasking operating system. This means that it can run multiple processes simultaneously. However, this is an illusion. What is really happening is that only one program runs at a time (assuming we have only 1 CPU ...). The apparent execution of multiple programs at the same time occurs because we perform what is known as a context switch between programs very quickly. If we were to take a photo snapshot at any moment in time, only one program would ever be running in that picture but if we switch between programs quite quickly, we get the illusion that they are all running. So ... what allows us to switch between one program and another. Typically, a program will "relinquish" its use of the CPU when it performs some kind of long term asynchronous I/O operation such as writing to disk, making a network call or waiting for user input. However, if a program performs lots and lots of pure CPU operations, it may never voluntarily give up its CPU time. This is where pre-emption comes into play. The OS tracks how long a given application has the CPU and if it has held that CPU for "too long", the CPU is taken from it and given to another waiting application. There are sophisticated algorithms for choosing which application gets the CPU when a slice of time is used up and this is, in part, governed by an attribute of a process called its priority. At a high level, processes which want the CPU and have a higher priority level than other processes will be given it. What this means is that if a program runs with high priority, it may be given an "unequal" share of the CPU relative to other processes. This can result in the notion of "starvation" of other applications which would like the CPU but have lower priorities.

There are also other reasons that starvation can occur. There are certain tasks that are "non-interruptable" and if called, may not be preempted. An application that registers to use these services may also claim an unequal share of resources.

The starvation of CPU time to some applications does not indicate an error or flaw ... it merely reflects the reality of what the system may actually be doing. When an application is run as root, that application has the highest level of privileges which includes the ability to change its own priority (upwards) as well as register with the hardware timers for interrupt level processing at very short duration intervals.

I did a very quick examination of the code in the projects you referenced and found indications that both of these may be happening in the Adafruit libraries. It may simply be the case that when you are running those Adafruit programs, they actually need dedicated resources to achieve the timliness of the tasks that they are performing and that there is nothing left over to give CPU cycles to the other applications you want to run in parallel.

1
  • Thank you for the spectacular informative answer! So I have to run the LED python script as root, because no other user can access the GPIO pins which drive the matrix. Should I also run bitcoind as root? Or is there an easier way to adjust the priority? The LED python script should be the lowest priority...
    – pinhead
    Commented Feb 11, 2016 at 21:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.