msperl
Posts: 325
Joined: Thu Sep 20, 2012 3:40 pm

Re: SPI driver latency and a possible solution

Tue Apr 14, 2015 12:07 pm

well - this driver does not offer that many improvements to the kernel any longer.
Also it is not maintained for 3.18 any longer.

But on the other hand there are several improvements that possibly will go into the 4.1kernel version, which the foundation might want to back-port to 3.18 at some point.

The big question is: are you running the driver in your own code (using spidev) or do you use a kernel module?

If you use spidev, then you might want to think about using the SPI-device directly from userspace, which avoids the context-switches and interrupt latencies at the cost of CPU utilization. I think there is a library out there that can help you with that.

But I guess with 4.2 there might also be some advances included that will improve spidev - for short transfers it would even be compareable to what the user-space library does...

msperl
Posts: 325
Joined: Thu Sep 20, 2012 3:40 pm

Re: SPI driver latency and a possible solution

Tue Apr 14, 2015 2:59 pm

here the updates that are now scheduled to get added to 4.1:
spi: bcm2835: fix all checkpath --strict messages
spi: bcm2835: fill/drain SPI-fifo as much as possible during interrupt
spi: bcm2835: clock divider can be a multiple of 2
spi: bcm2835: enable support of 3-wire mode
spi: bcm2835: move to the transfer_one driver model
spi: bcm2835: fix code formatting issue
spi: bcm2835: fill FIFO before enabling interrupts to reduce interrupts/message
spi: bcm2835: transform native-cs to gpio-cs on first spi_setup
spi: bcm2835: enabling polling mode for transfers shorter than 30us

Note that there is an issue that impacts the timeout of the "polling mode", which also implements a timeout, but can get rescheduled by the OS, which brings it way above the computed timeout value resulting in a TIMEDOUT error.
This is to get resolved.

So these are candidates to get also merged into the foundation kernel (at least at some point in time).

mbmahan39
Posts: 5
Joined: Tue Apr 14, 2015 12:18 am

Re: SPI driver latency and a possible solution

Wed Apr 15, 2015 6:28 am

"msperl", thank you verymuch for the info! I'm currently just using the wiringpi which I believe is using spidev? When is this kernel coming out(4.1)?
If you use spidev, then you might want to think about using the SPI-device directly from userspace, which avoids the context-switches and interrupt latencies at the cost of CPU utilization. I think there is a library out there that can help you with that.
Could you elaborate more please? I'm just starting to learn these stuff :) I have been more of a hardware person lately and Im just trying to catch on the software. :oops: How can I use it directly from the user space? :mrgreen:

msperl
Posts: 325
Joined: Thu Sep 20, 2012 3:40 pm

Re: SPI driver latency and a possible solution

Wed Apr 15, 2015 7:29 am

for user-space SPI (requireing root) see: http://abyz.co.uk/rpi/pigpio/index.html
that might help you as well. Still note that in user-space you may also experience scheduling issues, where the process gets interrupted for 10ms or more...

Future changes to the kernel driver will improve further - especially for longer transfers, so that might be better in the long-run and you do not have to rearrange your code.

When will the 4.1 kernel come out? in the next 50-90 days I would say the release should be official! The merge window is over.
When will the foundation provide a 4.1 kernel? No idea - the foundation is known to skip a few kernel versions (but definitely _after_ 4.1 has been officially released).

But we can ask them to backport ( = copy+ remove one line) the driver in the meantime - the changes were merged into the main trunk 3 days ago - but we need to wait for the fix to the one "issue" I found got merged...

Ingfu
Posts: 1
Joined: Tue May 05, 2015 9:22 am

Re: SPI driver latency and a possible solution

Tue May 05, 2015 9:31 am

Hallo everybody,

I have read all the thread but got a little confused as the situation changed over time.
My question is: what is the best method for high-speed data acqusition from an ADC via SPI?
I have no problem dedicating a core to a polling loop, but want the programm to be run in userland. AlsoI don't want to write my own driver.

Shall I use the bcm 2835 library from Mike McCauley or any other lib/approach suggested?

Cheers

msperl
Posts: 325
Joined: Thu Sep 20, 2012 3:40 pm

Re: SPI driver latency and a possible solution

Tue May 05, 2015 1:15 pm

At least with a 4.1 kernel you should be able to use spi-dev directly with now minimal overhead (when using spi-bcm2835) and get (most) of the benefits as the userland driver (for short transfers).

There is also a version in the pipeline that does DMA for longer transfers, but that is not a necessity for ADCs...

User avatar
mntmst
Posts: 57
Joined: Thu Sep 27, 2012 11:26 pm
Location: Fairview, Oregon

Re: SPI driver latency and a possible solution

Thu Jun 11, 2015 11:21 pm

Small issue with spi-2835 driver.
Edit: Scratch the problem with delay and cs, the driver implements transfer_one so the spi.c code handles those functions for it. Still have a problem formatting large transfers that I need to track down the true cause for.

Now that I look at it the problem might be because that timing on the spi-2835 driver is about 10us slower (in software overhead) than spi-2708 for a three byte transfer causing a glitch somewhere in the chain external to the driver. The timing stability is absolutely great. Thanks for the great work. :D
Bravo Zulu
https://youtu.be/G25rX8B9tlo

Image

Top to bottom (MCP3202/channel 0 then 1) with delay_usecs working great: data in(trigger), chip select, clock (1mhz), data out
Image

Image

Image

Top to bottom (MCP3202/channel 0 then 1) with delay_usecs: data in, chip select(trigger), clock (1mhz), data out
Image

User avatar
mntmst
Posts: 57
Joined: Thu Sep 27, 2012 11:26 pm
Location: Fairview, Oregon

Re: SPI driver latency and a possible solution

Sat Jun 13, 2015 8:05 am

Found the answer to my glitch problem with many transfers in one SPI message. With cs_change set the spi-bcm2708 driver would delay_usecs then set cs to false after every transfer (back to true on the next transfer) and at the last transfer. The spi.c framework does delay_usecs then toggles cs (true->false->true) after every transfer but the last transfer of the spi message(correctly according to the spi docs). I needed to turn cs_change off on the last transfer in the message so the next message would toggle cs back to true for the MCP3202 chip. The spi.c code also inserts an extra 10us delay for each cs toggle when cs_change is set.

Code: Select all

From spi.c
if (xfer->delay_usecs)
			udelay(xfer->delay_usecs);

if (xfer->cs_change) {
			if (list_is_last(&xfer->transfer_list,
					 &msg->transfers)) {
				keep_cs = true;
			} else {
				spi_set_cs(msg->spi, false);
				udelay(10);
				spi_set_cs(msg->spi, true);
			}
		}
This seems to be an excessive amount of fixed delay (the docs say 'briefly go inactive' and the required time for the MCP3202 is 310ns) but it won't hurt my application as I needed delays >10us anyway.
https://git.kernel.org/cgit/linux/kerne ... 92a26e1d50
Use a delay of 10us between deassert and reassert simply from pulling numbers out of a hat.
Image

User avatar
mntmst
Posts: 57
Joined: Thu Sep 27, 2012 11:26 pm
Location: Fairview, Oregon

Re: SPI driver latency and a possible solution

Sun Jun 14, 2015 1:39 am

It's a slow weekend :D so I patched my local kernel branch to have a cs_change_usecs variable in the spi_transfer structure so the toggle time could be set to 1us (or more) instead of the fixed 10us with the default cs_change_usecs value of 0.

Code: Select all

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 57a1950..3f784df 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -836,7 +836,7 @@ static int spi_transfer_one_message(struct spi_master *master,
                                keep_cs = true;
                        } else {
                                spi_set_cs(msg->spi, false);
-                               udelay(10);
+                               udelay(xfer->cs_change_usecs ? xfer->cs_change_usecs : 10);
                                spi_set_cs(msg->spi, true);
                        }
                }
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 856d34d..131f145 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -622,6 +622,7 @@ struct spi_transfer {
 #define        SPI_NBITS_DUAL          0x02 /* 2bits transfer */
 #define        SPI_NBITS_QUAD          0x04 /* 4bits transfer */
        u8              bits_per_word;
+       u8              cs_change_usecs;
        u16             delay_usecs;
        u32             speed_hz;

msperl
Posts: 325
Joined: Thu Sep 20, 2012 3:40 pm

Re: SPI driver latency and a possible solution

Thu Jun 18, 2015 1:11 pm

mntmst wrote:I patched my local kernel branch to have a cs_change_usecs variable in the spi_transfer structure so the toggle time could be set to 1us (or more) instead of the fixed 10us with the default cs_change_usecs value of 0.
If you want to have that then please consider up-streaming this to the linux kernel by sending a patch to [email protected]
following "normal" procedures - as soon as it goes into the kernel mainained by linus (maybe 4.2) you can request the foundation to cherry-pick the patch into their version...

User avatar
mntmst
Posts: 57
Joined: Thu Sep 27, 2012 11:26 pm
Location: Fairview, Oregon

Re: SPI driver latency and a possible solution

Thu Jun 18, 2015 8:39 pm

msperl wrote: If you want to have that then please consider up-streaming this to the linux kernel by sending a patch to [email protected]
following "normal" procedures - as soon as it goes into the kernel mainained by linus (maybe 4.2) you can request the foundation to cherry-pick the patch into their version...
I will do that when I get back to work next week but think they might be reluctant to change the transfer structure unless some other important modification is also needed, cheers...

cs_change_usecs set to 1us
Image

msperl
Posts: 325
Joined: Thu Sep 20, 2012 3:40 pm

Re: SPI driver latency and a possible solution

Tue Jun 23, 2015 10:54 am

Note that the dma-patch for the driver is now a candidate for 4.2 - as soon as it gets included in the branch of 4.2 I will ask the foundation to cherrry-pick the patch and move it into their 4.0 branch...

User avatar
bomba5
Posts: 10
Joined: Thu Jul 09, 2015 1:58 pm
Location: Catania, IT

Re: SPI driver latency and a possible solution

Thu Jul 09, 2015 2:06 pm

Hello,

I'm stuck in SPI guys:

Code: Select all

[email protected] ~ $ uname -a
Linux pi1 3.12.28+ #709 PREEMPT Mon Sep 8 15:28:00 BST 2014 armv6l GNU/Linux

[email protected] ~ $ lsmod
Module                  Size  Used by
can_bcm                11827  0 
can_raw                 6295  1 
can                    23718  2 can_bcm,can_raw
mcp251x                 9411  0 
can_dev                 9915  1 mcp251x
spi_config              9379  0 
spi_bcm2708             8027  0 
snd_bcm2835            19584  0 
snd_soc_bcm2708_i2s     6202  0 
regmap_mmio             2818  1 snd_soc_bcm2708_i2s
snd_soc_core          127841  1 snd_soc_bcm2708_i2s
snd_compress            8259  1 snd_soc_core
regmap_i2c              1661  1 snd_soc_core
snd_pcm_dmaengine       5505  1 snd_soc_core
regmap_spi              1913  1 snd_soc_core
snd_pcm                83845  3 snd_bcm2835,snd_soc_core,snd_pcm_dmaengine
snd_page_alloc          5132  1 snd_pcm
snd_seq                55484  0 
snd_seq_device          6469  1 snd_seq
snd_timer              20998  2 snd_pcm,snd_seq
leds_gpio               2079  0 
led_class               4118  1 leds_gpio
snd                    62252  7 snd_bcm2835,snd_soc_core,snd_timer,snd_pcm,snd_seq,snd_seq_device,snd_compress

[email protected] ~ $ modinfo spi_bcm2708
filename:       /lib/modules/3.12.28+/kernel/drivers/spi/spi-bcm2708.ko
alias:          platform:bcm2708_spi
license:        GPL v2
author:         Chris Boot <[email protected]>, Martin Sperl
description:    SPI controller driver for Broadcom BCM2708
srcversion:     AA32BEBA832149A11535B88
alias:          of:N*T*Cbrcm,bcm2708-spi*
depends:        
vermagic:       3.12.28+cancan-pi1 preempt mod_unload modversions ARMv6 
parm:           mode:Processing mode: 0=polling, 1=interrupt driven, 2=dma (default) (short)
parm:           realtime:Run the driver with realtime priority (bool)
parm:           debug:Turn on debug output (uint)

[email protected] ~ $ ifconfig can0
can0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          UP RUNNING NOARP  MTU:16  Metric:1
          RX packets:17965 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10 
          RX bytes:143720 (140.3 KiB)  TX bytes:0 (0.0 B)
dmesg at boot:

Code: Select all

[   13.417646] bcm2708_spi bcm2708_spi.0: DMA channel 4 at address 0xf2007400 with irq 20
[   13.441009] bcm2708_spi bcm2708_spi.0: DMA channel 5 at address 0xf2007500 with irq 21
[   13.469733] bcm2708_spi bcm2708_spi.0: SPI Controller at 0x20204000 (irq 80)
[   13.484920] bcm2708_spi bcm2708_spi.0: SPI Controller running in interrupt-driven mode
[   13.642660] spi_config_register: device description: bus=0:cs=0:modalias=mcp2515:speed=10000000:gpioirq=22:pd=20:pds32-0=16000000:pdu32-4=0x2002:force_release
[   13.660182]  spi_config_match_cs: SPI0: check CS=0 to be 0
[   13.667395]  spi_config_match_cs: SPI0.0: Found a device with modinfo spidev
[   13.676159] spi_config_register:spi0.0:mcp2515: found already registered device
[   13.685175]  spi_config_register:spi0.0:mcp2515: forcefully-releasing already registered device taints kernel
[   13.701373] spi_config_register:spi0.0: registering modalias=mcp2515 with max_speed_hz=10000000 mode=0 and gpio/irq=22/192
[   13.734027] spi_config_register:spi0.0:platform data:da2709e0: 00 24 f4 00 02 20 00 00 00 00 00 00 00 00 00 00  .$... ..........
[   13.750681] spi_config_register:spi0.0:platform data:da2709f0: 00 00 00 00                                      ....
[   13.848897] CAN device driver interface
[   13.875964] mcp251x spi0.0: probed
[   19.483076] FAT-fs (mmcblk0p1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
[   21.873849] smsc95xx 1-1.1:1.0 eth0: hardware isn't capable of remote wakeup
[   22.411370] mcp251x spi0.0 can0: bit-timing not yet defined
[   22.411404] mcp251x spi0.0: unable to set initial baudrate!
[   22.411885] mcp251x spi0.0 can0: bit-timing not yet defined
[   22.411914] mcp251x spi0.0: unable to set initial baudrate!
[   22.411966] mcp251x spi0.0 can0: bit-timing not yet defined
[   22.411985] mcp251x spi0.0: unable to set initial baudrate!
[   22.412030] mcp251x spi0.0 can0: bit-timing not yet defined
[   22.412049] mcp251x spi0.0: unable to set initial baudrate!
[   22.412093] mcp251x spi0.0 can0: bit-timing not yet defined
[   22.412110] mcp251x spi0.0: unable to set initial baudrate!
[   23.514162] mcp251x spi0.0 can0: bit-timing not yet defined
[   23.514198] mcp251x spi0.0: unable to set initial baudrate!
[   23.526027] smsc95xx 1-1.1:1.0 eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
[   24.515408] mcp251x spi0.0 can0: bit-timing not yet defined
[   24.515444] mcp251x spi0.0: unable to set initial baudrate!
[   24.520360] bcm2835-cpufreq: switching to governor ondemand
[   24.520413] bcm2835-cpufreq: switching to governor ondemand
[   25.516646] mcp251x spi0.0 can0: bit-timing not yet defined
[   25.516682] mcp251x spi0.0: unable to set initial baudrate!
[   26.517908] mcp251x spi0.0 can0: bit-timing not yet defined
[   26.517946] mcp251x spi0.0: unable to set initial baudrate!
[   27.519166] mcp251x spi0.0 can0: bit-timing not yet defined
[   27.519206] mcp251x spi0.0: unable to set initial baudrate!
[   28.418835] Adding 102396k swap on /var/swap.  Priority:-1 extents:1 across:102396k SSFS
[   28.520412] mcp251x spi0.0 can0: bit-timing not yet defined
[   28.520452] mcp251x spi0.0: unable to set initial baudrate!
[   29.455998] can: controller area network core (rev 20120528 abi 9)
[   29.456185] NET: Registered protocol family 29
[   29.488010] can: raw protocol (rev 20120528)
[   29.521021] mcp251x spi0.0 can0: bit-timing not yet defined
[   29.521059] mcp251x spi0.0: unable to set initial baudrate!
[   29.521171] can: broadcast manager protocol (rev 20120528 t)
[   29.574934] mcp251x spi0.0: CNF: 0x00 0x91 0x01
I manage to get CAN up and working but when it gets messages in delta shorter than 0.5ms, it hangs and I've got to rmmod/modprobe to get the interface up again.
I guess this is a very well known issue but googling around did not help this time.

J
---
bomba

User avatar
bomba5
Posts: 10
Joined: Thu Jul 09, 2015 1:58 pm
Location: Catania, IT

Re: SPI driver latency and a possible solution

Mon Jul 13, 2015 4:59 pm

For everybody struggling with SPI latency issues on Raspberri PI module B+ and MCP2515 based CAN interfaces:

on your computer, download the latest Raspbian release from http://downloads.raspberrypi.org/raspbian_latest
and place it on a SD card as described in https://www.raspberrypi.org/documentati ... s/linux.md

Place the SD inside your module and power it on. This will be the first time you boot into your new Raspbian so
raspi-config will show up automagically - if not, type:

Code: Select all

cd /usr/bin 
sudo ./raspi-config
Select "Advanced options"
Image
Select "SPI"
Image
Confirm you want the SPI interface enabled. Confirm you want the SPI kernel module to be loaded by default, then exit.
Update your system

Code: Select all

sudo apt-get update 
sudo apt-get upgrade 
sudo reboot
Update your kernel

Code: Select all

sudo rpi-update
Add the device tree overlays in /boot/config.txt/

Code: Select all

sudo vi /boot/config.txt
by adding the following lines at the very bottom of the file (oscillator freq and interrupt number may vary)

Code: Select all

dtparam=spi=on 
dtoverlay=mcp2515-can0-overlay,oscillator=16000000,interrupt=22 
dtoverlay=spi-bcm2835-overlay
dtoverlay=spi-dma-overlay
Reboot your system, after that you would be able to bring up your can interface by typing

Code: Select all

sudo /sbin/ip link set can0 up type can bitrate 500000
Adjust the bitrate to match your needings.

Install can-utils

Code: Select all

git clone https://github.com/linux-can/can-utils.git
cd can-utils
./autogen.sh
./configure
make
sudo make install
Done! Refer to can-utils documentation to test your hardware.
https://en.wikipedia.org/wiki/SocketCAN
* based on http://skpang.co.uk/blog/archives/1165
---
bomba

draco
Posts: 18
Joined: Fri Aug 15, 2014 6:42 am
Location: Melbourne, Australia

Re: SPI driver latency and a possible solution

Tue Aug 25, 2015 6:08 am

Hi,

I'm trying to push as much data as possible through my CAN bus. I've been following this thread, but not sure what is the most efficient combination of drivers that gives me the highest throughput.
Here's my setup:
- MCP2515 CAN controller
- Raspbian, kernel 4.1.6
- Running spi_bcm2835 driver with DMA enabled from stock Raspbian 4.1.6 kernel.
- Running mcp251x driver from stock Raspbian 4.1.6 kernel.

From the earlier posts, there is mention of this mcp2515 driver that is more efficient than the mcp251x. I'm also not sure how many of the SPI enhancements from msperl got merged into mainline kernel.

Can anyone in the know shed some light on this please?

Thank you.

Altah
Posts: 5
Joined: Wed Jan 11, 2017 8:38 am

Re: SPI driver latency and a possible solution

Wed Jan 25, 2017 2:35 pm

Hi,

i am also interested in the actual state.
I am using the newest raspbian jessie (4.4.?).
I have problems with a mcp2515 on spi2.
After running a while, the can interface stops receiving frames.

Is the "spi latency patch" allready implemented?
How to use the mcp2515 module with the newest kernel?

Mase89
Posts: 1
Joined: Wed Jan 25, 2017 2:12 am

Re: SPI driver latency and a possible solution

Fri Feb 17, 2017 4:27 am

zia_7575 wrote:Hey Martin,

I am using raspberry pi with ADS1298 chip .. I have applied your spi_low_latency patch. Interrupt works fine for me.. but whenever I try to use dma, I do not receive data.. plus there is no timeouts. Please help me to find the data and how can I trace it ?

Regards,
Zia
Hey Zia,

is it possible to get your code for getting started with the ADS 1298 on the Raspberry - i want to use this device for some low current measurements and don't know how to start with it by now since its my first time setting a thing like this up...

Regards,
Mase

Return to “Interfacing (DSI, CSI, I2C, etc.)”

Who is online

Users browsing this forum: No registered users and 10 guests