0

I have a raspberry pi 4B running Gentoo, with the 5.15.44 raspi kernel & realtime patches applied to it. The kernel is configured for CONFIG_PREEMPT_RT (big surprise), as well as CONFIG_HZ_PERIODIC, CPU_FREQ_DEFAULT_GOV_PERFORMANCE, (some other options I fail to remember off the top of my head) and the raspi itself is running at 1,800 GHz clock speed.

The problem I'm intending to solve is as follows:

I have attached an external device to the GPIO pins of the raspi. The device uses 1 pin as both input & output. For both input & output, communication is done in such a way that every 4 us (microseconds), 1 bit is transferred. A low bit (0) is classified by a low signal for 3us, followed by a high signal for 1us. A high bit (1) is classified by a low signal for 1us, followed by a high signal for 3us.

The external device will periodically send the sequence of 000000001 (this takes around 36us) to the raspi, after which it will expect a response of 64 bit to be returned. To read the data of the external device, I've written a small program in C++ to read the current pin state, as well as print out the time in microseconds since the start of the program.

Here is an example in which the program reads a bit of value 0 being transmitted:

Pin State: 0 | Time Dif: 7365.79 Pin State: 0 | Time Dif: 7365.92 Pin State: 0 | Time Dif: 7366.05 Pin State: 0 | Time Dif: 7366.36 Pin State: 0 | Time Dif: 7366.49 Pin State: 0 | Time Dif: 7366.62 Pin State: 0 | Time Dif: 7366.75 Pin State: 0 | Time Dif: 7366.88 Pin State: 0 | Time Dif: 7367.01 Pin State: 0 | Time Dif: 7367.14 Pin State: 0 | Time Dif: 7367.27 Pin State: 0 | Time Dif: 7367.4 Pin State: 0 | Time Dif: 7367.55 Pin State: 0 | Time Dif: 7367.68 Pin State: 0 | Time Dif: 7367.81 Pin State: 0 | Time Dif: 7367.94 Pin State: 0 | Time Dif: 7368.07 Pin State: 0 | Time Dif: 7368.2 Pin State: 0 | Time Dif: 7368.33 Pin State: 0 | Time Dif: 7368.46 Pin State: 0 | Time Dif: 7368.61 Pin State: 0 | Time Dif: 7368.74 Pin State: 0 | Time Dif: 7368.86 Pin State: 0 | Time Dif: 7368.99 Pin State: 0 | Time Dif: 7369.12 Pin State: 0 | Time Dif: 7369.25 Pin State: 0 | Time Dif: 7369.38 Pin State: 0 | Time Dif: 7369.51 Pin State: 0 | Time Dif: 7369.66 Pin State: 0 | Time Dif: 7369.79 Pin State: 1 | Time Dif: 7369.92 Pin State: 1 | Time Dif: 7370.05 Pin State: 1 | Time Dif: 7370.18 Pin State: 1 | Time Dif: 7370.31 Pin State: 1 | Time Dif: 7370.44 

(I should note at this point that this is being printed after the program has finished executing, not during the reading of these values)

So far so good. However, there is one small problem I haven't been able to figure out. Every now and then, the program will skip a few microseconds. This is quite a problem in this use case, since it means that multiple bits of information will get lost:

Pin State: 0 | Time Dif: 7384.2 Pin State: 0 | Time Dif: 7384.33 Pin State: 1 | Time Dif: 7390.4 Pin State: 1 | Time Dif: 7390.53 

As you can see here, it jumped almost 6 entire microseconds, which is 1.5 bits of information lost. This isn't a huge deal if it's just about getting the polling request from the device, but when it comes to sending information to it, I'm afraid everything will arrive jumbled (the device does not perform any sort of error correction).

Now my question is, how do I prevent this from happening? Is there some kernel config I can set, or running the process under a certain priority? I've tried chrt -rr 99 <program> but to no avail. Any help would be greatly appreciated.

1 Answer 1

0

You did right when choosing to schedule your program SCHED_RR.

Having the RT patch, I expect the IRQs to be threaded (and SCHED_RR as well), increase the priority of the IRQ thread associated with your GPIO.

Ultimately, you should pin your "program" to one core, the GPIO IRQ thread on another one and let the other cores do the housekeeping.

Because it takes time waiting, you can forget printing out the values. Record them in some tmpfs file instead for later use.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.