Hello eyeryone,
I’m actually porting a bare-metal-realtime-application to linux.
That application needs to exchange 256 bytes of data with slave processors via spi every 500us.
On an oscilloscope I see that the actual transfer (the clock-signal) takes about 308us while the ioctl()-call takes about 435us.
Because of that I do the ioctl() in a separate realtime-thread of high priority.
To see the begin and end of the ioctl()-call my thread switches a gpio-pin immediately before and after the ioctl():
In the oscillogram the blue signal is the clock of the spi while the pink one is the gpio indicating the start and end of the ioctl().
Most of the time everything works fine, but in one of a thousand times the ioctl() takes more than 500us breaking my realtime.
I found a 2 1/2 years old thread about a similar issue. Like described in the post by Garyio I turned the “message pump” into a realtime thread.
diff -c spi-imx.c.orig spi-imx.c
*** spi-imx.c.orig 2018-07-10 11:52:06.579519394 +0200
--- spi-imx.c 2018-10-16 15:47:30.807011186 +0200
***************
*** 1192,1197 ****
--- 1192,1198 ----
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
master->bus_num = np ? -1 : pdev->id;
+ master->rt = 1; // DM 16.10.2018
spi_imx = spi_master_get_devdata(master);
spi_imx->bitbang.master = master;
After this with top I can see the “message pump” running as realtime thread:
top - 17:14:27 up 1:14, 2 users, load average: 1.06, 1.04, 1.00
Tasks: 119 total, 1 running, 118 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.6 us, 6.4 sy, 0.0 ni, 93.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 251580 total, 187476 free, 17904 used, 46200 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 227320 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
614 root 20 0 29156 1456 1288 S 32.1 0.6 13:59.36 asx-linux
76 root -51 0 0 0 0 S 6.5 0.0 3:05.27 irq/64-sdma
265 root rt 0 0 0 0 S 4.5 0.0 2:05.07 spi0
612 root 20 0 4428 2072 1716 R 1.3 0.8 0:34.66 top
It now looks somewhat better but still in 0.4% of the cases it takes more than 450us giving me too little time to handle the received data and to initiate the next transfer.
Is there something like a realtime-patch for the spi-driver or any way to shorten the time-gap (90us in best cases) between the end of the actual transfer (clock-signal) and the return of the ioctl()-call?
Thanks,
Grimme