Reduce microsecond jitter (using realtime kernel)
0
votes
1
answer
725
views
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
but to no avail. Any help would be greatly appreciated.
Asked by xNaXDy
(1 rep)
Jun 16, 2022, 12:46 PM
Last activity: Jul 19, 2022, 04:10 PM
Last activity: Jul 19, 2022, 04:10 PM