maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Thu Feb 21, 2013 7:49 am

Hello Zeta,
yes, I did the test without IRQF_ONE_SHOT.
Yesterday evening I had a look, where the gpio catchall handler is defined.
It's in the mach-bcm2708 folder, the file bcm2708_gpio.c

From what I understood, it is an interrupt service routine, that reads out the
gpio interrupt registers and triggers a "generic interrupt" for each gpio with
an activ interrupt.

Code: Select all

static irqreturn_t bcm2708_gpio_interrupt(int irq, void *dev_id)
{
	unsigned long edsr;
	unsigned bank;
	int i;
	unsigned gpio;
	for (bank = 0; bank <= 1; bank++) {
		edsr = readl(__io_address(GPIO_BASE) + GPIOEDS(bank));
		for_each_set_bit(i, &edsr, 32) {
			gpio = i + bank * 32;
			generic_handle_irq(gpio_to_irq(gpio));
		}
		writel(0xffffffff, __io_address(GPIO_BASE) + GPIOEDS(bank));
	}
	return IRQ_HANDLED;
}

static struct irqaction bcm2708_gpio_irq = {
	.name = "BCM2708 GPIO catchall handler",
	.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
	.handler = bcm2708_gpio_interrupt,
};

static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb)
{
	unsigned irq;

	ucb->gc.to_irq = bcm2708_gpio_to_irq;

	for (irq = GPIO_IRQ_START; irq < (GPIO_IRQ_START + GPIO_IRQS); irq++) {
		irq_set_chip_data(irq, ucb);
		irq_set_chip(irq, &bcm2708_irqchip);
		set_irq_flags(irq, IRQF_VALID);
	}
	setup_irq(IRQ_GPIO3, &bcm2708_gpio_irq);
}

maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Wed Feb 27, 2013 8:31 pm

Hello,
I decided to continue the GPIO interrupt topic in a new post

http://www.raspberrypi.org/phpBB3/viewt ... 44&t=35371

Greetings maddin

maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Sat Mar 02, 2013 7:53 pm

Hello,
I found a thing in the mcp2515-driver, that could explain, why I don't see a difference, when I set
IRQF_TRIGGER_LOW in the boarddefinition file.

In the mcp2515_open, IRQF_TRIGGER_FALLING is used as a constant value.

Code: Select all

static int mcp2515_open(struct net_device *dev)
...
...
    err = request_irq(spi->irq, mcp2515_interrupt,
			          IRQF_TRIGGER_FALLING, dev->name, dev);

rudiratlos
Posts: 216
Joined: Tue May 01, 2012 8:47 am
Location: Germany (old europe)

Re: CAN controller

Mon Mar 04, 2013 6:06 pm

Hi,

just want to inform the followers on this CAN thread, that the NEW piggy back board with pcb revison 2 has a SPI connector, on which you can directly hook up the MCP 2515 based MINI-CAN Board from ETS.

More infos are here: http://shop.basis.biz/shop/Raspberry-PI ... ack-board/
and here: http://shop.basis.biz/shop/images/manuf ... n_Rev2.pdf

maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Tue Mar 05, 2013 8:26 pm

Hello,
I did some more tests with two mcp2515.
It looks like the mcp2515 module stops clearing the intf register.

I put some printk for one of the can channels to the code and this is the result:

Code: Select all

...
[  531.998806] mcp2515_clear_canintf mcp2515 priv->transmit
[  531.999050] mcp2515_rts_txb0 mcp2515_rts_txb0
[  531.999139] mcp2515_rts_txb0_complete mcp2515_rts_txb0_complete
[  531.999232] mcp2515 priv->busy mcp2515_rts_txb0
[  531.999982] mcp2515_rts_txb0_complete mcp2515_clear_canintf
[  532.000205] mcp2515 priv->transmit mcp2515_rts_txb0
[  532.000298] mcp2515_rts_txb0_completemcp 2515 priv->busy
[  532.000525] mcp2515_rts_txb0 mcp2515_rts_txb0_complete
[  532.001277] mcp2515_clear_canintf mcp2515 priv->transmit
[  532.001596] mcp2515_rts_txb0 mcp2515_rts_txb0
[  532.001678] mcp2515_rts_txb0_complete mcp2515_rts_txb0_complete
[  532.001743] mcp2515 priv->busy mcp2515_clear_canintf
[  532.002860] mcp2515 priv->transmit mcp2515_rts_txb0
[  532.002979] mcp2515_rts_txb0 mcp2515_rts_txb0_complete
[  532.003034] mcp2515_rts_txb0_complete mcp2515 priv->busy
[  532.004198] mcp2515_rts_txb0 mcp2515_rts_txb0_complete
[  532.005220] mcp2515_rts_txb0 mcp2515_rts_txb0_complete
[  532.006394] mcp2515_rts_txb0 mcp2515_rts_txb0_complete
[  532.007019] mcp2515_rts_txb0 mcp2515_rts_txb0_complete
[  532.008136] mcp2515_rts_txb0 mcp2515_rts_txb0_complete
...

And this is the output in a normal operation

Code: Select all

...
[  604.593633] mcp2515 priv->transmit
[  604.593686] mcp2515_rts_txb0
[  604.593807] mcp2515_rts_txb0_complete
[  604.593908] mcp2515 priv->busy
[  604.593995] mcp2515_clear_canintf
[  604.594049] mcp2515 priv->transmit
[  604.594070] mcp2515_rts_txb0
[  604.594105] mcp2515_rts_txb0_complete
[  604.594359] mcp2515 priv->busy
[  604.594460] mcp2515_clear_canintf
[  604.594515] mcp2515 priv->transmit
[  604.594536] mcp2515_rts_txb0
[  604.594571] mcp2515_rts_txb0_complete
[  604.594809] mcp2515 priv->busy
[  604.594980] mcp2515_clear_canintf
...
I'm going to do some more tests and hope I can find out more.

Greeting maddin

maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Thu Mar 07, 2013 7:56 pm

I made some more test and now I don't have an idea anymore.

In the "log" are informations from the bcm2708_gpio module for both interrupt sources and
from the mcp2515 module only for can0 (to keep it readable).

Code: Select all

edsr at beginning of interrupt=0x00020000 
i=17 gpio=17 
CAN0_interrupt 
CAN0_read_flags 			CAN0_spi_async 
edsr after generic_interrupt=0x00000000
								                  CAN0_read_flags_complete Result: intf=04 eflg=00
CAN0_clear_intf 			CAN0_spi_async		CAN0_clear_intf_complete
CAN0_read_flags 			CAN0_spi_async 
CAN0_start_xmit 
								                CAN0_read_flags_complete Result: intf=00 eflg=00
CAN0_load_txb0 				CAN0_spi_async 		CAN0_load_txb0_complete 
edsr at beginning of interrupt=0x80000000 
i=31 gpio=31 
edsr after generic_interrupt=0x00000000
CAN0_send_rts_txb0 			CAN0_spi_async 		CAN0_send_rts_txb0_complete 
CAN0_read_flags 			CAN0_spi_async 		CAN0_read_flags_complete Result: intf=00 eflg=00
C0_clear_busy 
edsr at beginning of interrupt=0x00020000 
i=17 gpio=17 
CAN0_interrupt 
CAN0_read_flags 			CAN0_spi_async 
edsr after generic_interrupt=0x00000000
								                CAN0_read_flags_complete Result: intf=04 eflg=00
CAN0_clear_intf 			CAN0_spi_async 		CAN0_clear_intf_complete 
CAN0_read_flags 			CAN0_spi_async 
edsr at beginning of interrupt=0x80000000 
i=31 gpio=31 
edsr after generic_interrupt=0x00000000
CAN0_start_xmit 
								                CAN0_read_flags_complete Result: intf=00 eflg=00
CAN0_load_txb0 				CAN0_spi_async		CAN0_load_txb0_complete 
CAN0_send_rts_txb0 			CAN0_spi_async 		CAN0_send_rts_txb0_complete 
CAN0_read_flags 			CAN0_spi_async 		CAN0_read_flags_complete Result: intf=00 eflg=00
C0_clear_busy 
edsr at beginning of interrupt=0x80000000 
i=31 gpio=31 
edsr after generic_interrupt=0x00000000 
edsr at beginning of interrupt=0x80000000
For me, it looks like both modules work fine.
The mcp2515 module clears the intf flags and it is read out as 00 then.
The bcm2708_gpio module clears the gpio17 bit and it is read out as 0 then.

From this time it stays 0, I can see it, because the gpio 31 interrupt is still working.
When gpio17 interrupt would have been recognized, edsr should be 0x80020000.

So the only possibility I see is, that the falling edge has not been recognized.

Maybe it is possible to find out something more with a logic-analyser, but I don't have one.

I will also post this in the other post and will try to ask "broadcom" for help.


greetings maddin

Zeta
Posts: 72
Joined: Wed Dec 12, 2012 9:51 pm

Re: CAN controller

Thu Mar 07, 2013 8:17 pm

Hello maddin,

Sorry for not be able to help you more currently. It seems you already have tested a lot of things.

About your conclusion :
maddin1234 wrote:So the only possibility I see is, that the falling edge has not been recognized.
You wrote some time ago:
maddin1234 wrote:Hello,
I found a thing in the mcp2515-driver, that could explain, why I don't see a difference, when I set
IRQF_TRIGGER_LOW in the boarddefinition file.

In the mcp2515_open, IRQF_TRIGGER_FALLING is used as a constant value.
The last thing you can try - if you did not already tried it - is to set by hand the interrupt to TRIGGER_LOW mode in the driver (or better, let it use the value given in the board configuration, and configure to low from there).

That way if the problem is a falling edge not detected, using level interrupt should allow to detect the low state at the end of the interrupt handler.
For this to work and avoid triggering several times for the same interrupt, the mcp2515 should have had time to clear the interrupt through SPI before the interrupt handler returns, if I understand it well enough.

Hope this works.

Zeta

maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Fri Mar 08, 2013 11:56 am

Hello,
I tried to set IRQF_TRIGGER_LOW directly in the mcp2515_open function, but then the request_irq failed. I have to find out why.

I also found that the mcp2515 driver uses spin_lock_irqsave(&priv->lock, flags);

Does anyone know what this does exactly?
Does it disable the execution of a new interrupt in the operation system, or does it disable the recognition of an interrupt in the GPIO-registers?

maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Sun Mar 10, 2013 9:07 pm

Hello,
while searching for information about spin_lock_irqsave I found a patch
Raspberry SDHCI driver low latency patch
https://gist.github.com/ddv2005/3454406

It looks like the only thing they do is to replace spin_lock_irqsave with a
"local locking function":

Code: Select all

- spin_lock_irqsave(&host->lock, flags);
+ sdhci_spin_lock(host);
Maybe this can also work for our drivers. spi-bcm2708.c and mcp2515.c both
contain spin_lock_irqsave.

And maybe we should also spend some time thinking about whether we need
spin_lock_irqsave at all. Some drivers for other can controllers do not have spin_lock_irqsave
in their code.

Greetings maddin

Zeta
Posts: 72
Joined: Wed Dec 12, 2012 9:51 pm

Re: CAN controller

Sun Mar 10, 2013 11:17 pm

Hello maddin,

I don't know yet this part of the kernel you are fighting with... here are some comments though.
maddin1234 wrote:It looks like the only thing they do is to replace spin_lock_irqsave with a
"local locking function":
Looking at this patch, we can see that they replace
the call to : spin_lock_irqsave(&host->lock, flags);
by a call (hidden in the local function) to : spin_lock(&host->lock);

Will trying to see what the difference between them was, I discovered a book that may explains all:
http://www.makelinux.net/ldd3/

Especially the chapter 5 : "Concurrency and race conditions" where a desciption of spinlocks functions is given: http://www.makelinux.net/ldd3/chp-5-sect-5

extracts:
Unlike semaphores, spinlocks may be used in code that cannot sleep, such as interrupt handlers. When properly used, spinlocks offer higher performance than semaphores in general. They do, however, bring a different set of constraints on their use.
spin_lock_irqsave disables interrupts (on the local processor only) before taking the spinlock; the previous interrupt state is stored in flags. If you are absolutely sure nothing else might have already disabled interrupts on your processor (or, in other words, you are sure that you should enable interrupts when you release your spinlock), you can use spin_lock_irq instead and not have to keep track of the flags. Finally, spin_lock_bh disables software interrupts before taking the lock, but leaves hardware interrupts enabled.
So in this patch, they don't get rid of the irq in the call to the spinlock function.

If they use the "low latency mode" (the enable_llm variable here), they call manually the disable_irq_nosync(host->irq) and local_irq_enable() function (and their opposite to restore them).

It didn't get it yet why they deactivate the hardware irq and activate the "local" one, and when releasing the lock deactivate the local one and reactivate the hardware one. I don't get the point of the local here.

Finally there is also something about a second interrupt that is memorized, linked to DMA it seems.

The book cited previously also has details about interrupts : http://www.makelinux.net/ldd3/chp-10-sect-3

At least I found a next book to read (already bought, waiting for it to be delivered)...

Zeta
Posts: 72
Joined: Wed Dec 12, 2012 9:51 pm

Re: CAN controller

Sun Mar 10, 2013 11:31 pm

One thing I forgot:
Finally, spin_lock_bh disables software interrupts before taking the lock, but leaves hardware interrupts enabled.
This one may be interesting to look at for the GPIO part (probably not for the SPI), as individual input interrupts are handled as software interrupts, and the complete port as a hardware interrupts.

This function may allow to keep the hardware interrupt running to avoid missing them, and delay (or throw ?) the software interrupts.

maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Mon Mar 11, 2013 9:07 pm

Hello,
I also read and thought a lot.

1.) spin_lock is just setting a lock-bit (very fast)
spin_lock_irq sets the lock-bit and disables the interrupts (more code to execute)
pin_lock_irqsave sets the lockbit, reads out the irq-state, saves it and disables interrupts (a lot of code)
and similar for the unlock functions
That might be the reason for the lower latency in the mmc patch.

2.) spin_lock_irqsave is needed in the "normal" code, when the interrupt handler uses a spin_lock.
This is to avoid a deadlock. When the normal code sets the spin_lock and then an interrupt arrives, the normal code would be interrupted, the interrupt handler starts and goes to busy sleep, because he will not get the spin. So spin_lock_irqsave is used to be sure an interrupt can not interrupt in this code sequence.

Idea 2.: The interrupt handler just sets a spin_lock around modifying priv->busy or priv->interrupt.
So maybe for priv->transmit a spin_lock_irqsave is not necessary, a spin_lock might be enough.

3.) I didn't find a reason for what we need the spin_lock
For example the spin_lock_irqsave area from the function mcp2515_start_xmit:

Code: Select all

...
	spin_lock_irqsave(&priv->lock, flags);
	if (priv->busy) {
		priv->transmit = 1;
		spin_unlock_irqrestore(&priv->lock, flags);
		return NETDEV_TX_OK;
	}
	priv->busy = 1;
	spin_unlock_irqrestore(&priv->lock, flags);
...
The code sets a spin_lock_irqsave and checks the state of priv->busy
3.1) If priv->busy is set, the driver sets priv->transmit, releases the spin_lock and returns.
(When the driver is doing something else, then remember that there is a message to transmit)

Idea 3.1: The function mcp2515_start_xmit stoped the queue (netif_stop_queue(dev)) earlier, and it is released not until the CANINTF_TXOIF bit signals, that the transmission is completed.
So I do not see the need for this spin_lock, because no new message can arrive, before this one is transmitted.

3.2) If priv_busy is not set, it is set and the spin_lock is released.
The only thing that can happen here is, that the interrupt handler starts and sets the busy-bit before the mcp2515_start_xmit sets it.

Idea 3.2: I can't see a problem in this.

I think I will try to remove all the spin_locks from the mcp2515 driver and test it.

Greetings maddin

maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Tue Mar 12, 2013 6:11 pm

Hello,
I did some more tests.

Code: Select all

cangen can0 -g 0 -i -I 400 -L 8 &
results in 61.9% busload at 500kBit.

When I remove all spin_locks from the mcp2515.c module, there is a little speed improvement to 62.3%.
Only sending and only receiving seems to work find, but when sending and receiving at the same time, the driver fails after some time.

When removing all the spin_locks from the spi.c module, the busload improves from 61.9 to 62.7%
but the driver fails after some time.

Removing the spin_locks from spi-bcm2708.c module results in failing to probe the mcp2515 devices.

No good results from today :(

maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Wed Mar 13, 2013 8:45 pm

Hi again,
I tried to use IRQF_TRIGGER_LOW for the mcp2515 driver today.

To make the mcp2515-driver use the settings from the bcm2708.c file was quite easy.
in the function
static int mcp2515_open(struct net_device *dev)

Code: Select all

add::        struct mcp251x_platform_data *pdata = spi->dev.platform_data;

replace                        IRQF_TRIGGER_FALLING, dev->name, dev);
by                                pdata->irq_flags, dev->name, dev); 
But the rest was more work than I expected.
In the bcm2708_gpio driver I had to add the configurations for level-interrupts, it was just
made to handle egde-interrupts before.
The interrupt handler clears the GPIOEDS register now only when edge-detection is configured,
otherwise the mcp2515-module has to clear the GPIOEDS.
I think this is necessary because we use the asynchronous spi interface. The mcp2515 interrupt
handler has finished, before the asyncronous spi-transfer has finished and the mcp2515 canintf register is cleared.

To make this possible, I added two public functions to the bcm2708_gpio.c file and created a
bcm2708_gpio.h file. (In the folder arch/arm/mach-bcm2708/include/mach/ )

I can compile the kernel with
make
but then
make modules
fails with the message, that the functions from bcm2708_gpio.c can not be found,
when building the mcp2515.ko.

I didn't find out, how to tell make where the functions are. Perhaps anyone has an idea.

I attached the three files that I changed. I also tried to add a comment beginning
with "// maddin1234: " everywhere I made changes.
Greeting maddin
Attachments
changed_for_lowlevel_interrupt.zip
(8.73 KiB) Downloaded 224 times

e8micke
Posts: 2
Joined: Sat Mar 23, 2013 9:38 am

Re: CAN controller

Sat Mar 23, 2013 10:03 am

My knowledge of Linux IRQ handling in general, and rasperry HW in particlar is very small.
But I have attached some picture for the phenomena, maybee it can help the bug searching.

IRQ always end up low when there are a stop in reception.
Sending and transmitting simultaneously seems to make things worse.
Playing USB audio (=lots of IRQ) also seems to make things worse.
I might be wrong, but it seems like the CS (CE of MCP2515) is always low when IRQ are falling, and after CS/CE is rised, the new IRQ are never serviced.
I think is due to a "interrupt-in-the-interrupt" which causes the MCP handling to pause, and because of the large handling time there is another IRQ during the IRQ handling.
rasp_mcp2515_1.jpg
Timing IRQ , ID348 is received ID3C8 sent
rasp_mcp2515_1.jpg (56.22 KiB) Viewed 7025 times
rasp_mcp2515_2.jpg
Crash #3, only RX
rasp_mcp2515_2.jpg (47.28 KiB) Viewed 7025 times
rasp_mcp2515_3.jpg
Crash #3
rasp_mcp2515_3.jpg (53.5 KiB) Viewed 7025 times

maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Sat Mar 23, 2013 5:32 pm

Hi, thanks for the graphics.
Crash #3, only RX looks suspicious.

The first falling edge of the mcp2515-interrupt leads to a correct reaction.
The mcp2515-driver reads the canintf register, sees that a rx-buffer is full,
reads data from this buffer and clears rx-interrupt (see posts on page 5 for this),
reads the canintf register again and terminates, because there is nothing more to do.

When the second falling edge comes, it starts the same, cantinf register is read,
rx-buffer is read and rx-interrupt is cleared, then it reads the canintf again and now something
must have happend. The chip-select for the spi is not released.

The third falling edge of the mcp2515 interrupt is not handled anymore, maybe the spi-driver
"thinks" it is still busy from the last read of canintf.


Can you give some more information of your test setup?
What is your bitrate? About 2,5ms for a message is very slow. At 500k an 8 bit message uses
something about 280us.
Are you using 1 or two can channels?

greeting maddin

e8micke
Posts: 2
Joined: Sat Mar 23, 2013 9:38 am

Re: CAN controller

Sat Mar 23, 2013 8:00 pm

Test setup is a small test program that "load" the bus from a PC just to force this error, takes about 60-90 seconds on average to make the RX crash in my case.

Code: Select all

while (i<60000):
    ii=0
    while (ii<10):
        cansend(0x348,"1102FF1900000000")
        ii=ii+1
        time.sleep(0.003)
    time.sleep(0.1)
Bitrate is 47619 bits per second (this is a for SAAB car, CD changer emulator).
It's slow compared to most other things.

Rasperry (MCP2515) also sends CAN, but only two messages each second (10ms separated).
The raspberry also plays USB audio (CM108 chip device on full, not high speed USB).
I still think (without any knowledge of the code), that the IRQ is cleared at the end of the interrupt, so any IRQ happing during the IRQ is lost.

Zoom into crash #3.
rasp_mcp2515_3_magn.jpg
Crash #3 magnified
rasp_mcp2515_3_magn.jpg (51.95 KiB) Viewed 7013 times
There is a 5.5µs time after CS is rising (X1) till IRQ is falling (forever, X2).

Regarding the CS in the "Crash #3, only RX" (should be "Crash #2, only RX") picture,
the CS signal does rise, but out of picture.
IRQ however, is never rised.

Please let me know if you need more pictures, or other details.

Edit:
This issue is with the mcp251x driver (3.6.11-ARCH+), the mcp2515 driver seens to be stable in the same conditions!
/Mikael

maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Sun Mar 24, 2013 11:35 am

Hi,
when you are using the mcp251x driver, I think I know what is happening.
I didn't have a deep look into the mcp251x driver, but one of the advantages
of the mcp2515 driver is that it uses asynchronous spi transfer.
That means, that the interrupt handler returns IRQ_HANDLED before all
the work is done.
I could imagine that the mcp251x returns IRQ_HANDLED at the end of all operations.

The GPIO Interrupt is handled in the bcm2708_gpio module and this module in the
original version clears the EventDetectionRegister (EDR) after the interrupt handler has returned.

In your picture, you can see, that mcp251x reads the rx-buffer. This clears the canintf flag
and the interrupt line goes up. The mcp251x goes on to read the canintf-register again.
When the register was read as 0x00 from spi-module (no interrupt active) and the next
message was received before the driver really finished, this interrupt will not be recognized
by mcp251x because it finishes when read 0x00 and it will not be recognized by the bcm2708_gpio
module, because the EDR wasn't cleared from the previous interrupt but will be cleared after
mcp251x returns.

Have a look at my preivious posts, I think it will help here to clear the EDR before executing
the generic_irq.
Or maybe change the prioity of your tasks. It looks like your system is quite busy with playing
the audio files and cannot handle the interrupts as fast necessary.
I wouldn't have expected, that the raspy has problems with such a low bitrate.

greeting maddin

maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Sat Mar 30, 2013 8:13 am

Hello,
I just want to point out, what I was working at the last days.

I found out, that using polling-mode in the SPI driver increases the busload
for roundabout 10% compared to interrupt driven mode.

That lead me to another idea:
Keeping IRQF_TRIGGER_FALLING but get rid of the spin_lock_IRQsave.

I tried to programm a spinlock-free version of the mcp2515 driver, first tests look good,
when using only one can. When I did some more tests I will publish it here.

But when using two can's, I still have the same problem.
So the next step I will try is, to put "if (polling)" to the SPI driver and then to decide
whether do make a spin_lock or a spin_lock_IRQsave.

greetings maddin

nexulm
Posts: 8
Joined: Tue Apr 02, 2013 8:42 am

Re: CAN controller

Wed Apr 03, 2013 7:06 am

Hello maddin1234,

as I'm see the same problem on my setup 2x CAN interfaces with MCP2515/PCA82C250, 12MHz and GPIO-Interrupts on GPIO25 (CAN0) / GPIO24 (CAN1) with Kernel 3.6.11. I've read a lot across the forum.
I was using cangw from the can-utils to make a CAN-Gateway with the Raspi as I've seen that one of my CAN-interfaces stuck. If I use only one CAN-Interface each of them is working fine up to 1MBit/s and >= 60% busload.
I'm also using the "MCP2515 Asynchronous Driver" and the "SPI low latency patch" which are mentioned here: http://elinux.org/RPi_CANBus

How is your progress on using both CAN-interfaces with or without spin_lock_IRQsave?
Did you use/try also another Kernel 3.2.27/3.8.4?

I'm not sure if this fault occurs also on these Kernels!?!
I'm very interested in solving this issue to get my CAN-Gateway running. If you or someone else need more details (i.e. Oscilloscope screenshots) for debugging I like to support the community.

Regards
Mike

maddin1234
Posts: 68
Joined: Sat Aug 04, 2012 8:33 pm

Re: CAN controller

Fri Apr 05, 2013 6:15 pm

Hello nexulm,
no, I'm sorry but I didn't have a real result yet.
I also had this problem with a 3.2 kernel, didn't check it with a 3.8 but
don't think that it will make a difference.

What I think about the problem now is:

mcp2515- and spi-driver both use spin_lock_IRQsave.
I didn't find a lot about IRQsave, so all what comes now is a "guess".

When we are using just one can, both drivers disable the interrupts for short times,
but this is no problem for the can, because all the SPI transfers happen while the
Interrupt line is still low (until "canintf" is cleared). Exception is the last "read_flags" but
there doesn't seem to be a timing problem.

When we are using two cans, there are 4 "modules" disabling the interrupts.
mcp2515 for can0, spi for can0,
mcp2515 for can1 and spi for can1.
And between can0 and can1 there is no timing correlation.
So I think for example the can0 falling edge appears just at the moment when
spi for can1 has disabled the interrupts.

That 's why I tried to get rid of the spin_lock_IRQsave commands.

I attached my mcp2515 driver without spinlocks.
I put a lot of comments to the code to explain the changes.
In my test it worked well until now with one can but it didn't solve the problem.

So next step will be to look into the spi-driver.

greetings maddin
Attachments
mcp2515.zip
(5.95 KiB) Downloaded 225 times

bertr2d2
Posts: 98
Joined: Wed Aug 08, 2012 10:12 pm

Re: CAN controller

Fri Apr 12, 2013 9:49 am

Hi,

I was following this thread since beginning and I must admit, that CAN&RPi has some limitations. The MCP2515 with it's SPI interface is a challenge. Great affords were made with the the new SPI driver (thx to msperl), but IMHO the RPi isn't the best platform for using CAN.
I'm quite happily using the RPI with 250Kb (500kb seems also to be OK), but beyond this or even use 2 MCP2515 is to much for the RPi.

I've made some baseline tests using virtual CAN interfaces. A packet is send to the VCAN interface, received on the other, incremented and send back (code attached):

Code: Select all

CAN Bounce Test

Platform        CPU             Clock [MHZ]     Bogomips        p/sec [1000]    Mbit
RaspberryPI     ARMv6           700             700             21.36           1.69
Beaglebone      ARMv7           720             720             44.29           3.50
Laptop          PentiumM        1500            1500            168.06          13.27
Workstation     AMD64           3000            6000            449.34          35.50
For you refrence the test setup:

Code: Select all

modprobe can
modprobe can-raw
modprobe can-gw
modprobe vcan

ip link add type vcan
ifconfig vcan0 up
ip link add type vcan
ifconfig vcan1 up

cangw -A -s vcan0 -d vcan1 -e
cangw -A -s vcan1 -d vcan0 -e
SocketCAN needs some CPU power. On top the SPI/MCP2515 generates lots of interrupts ( 2-6 fold per packet), which will decrease the performance.
IMO a 2 CAN interface will only work with bandwidth below 125 kb.

Today I'm using a Beaglebone. The AM3358 does have more horse power, 2 integrated CAN interfaces and a bunch of other peripherals. If you need plenty of interfaces have a look at it.
BTW: The Beaglebone is beeing updated in the next month with more memory, more power and lower price.

Regards,

Gerd
bounce.zip
CAN Bounce Test
(1.42 KiB) Downloaded 228 times
Easy to build CAN-Bus interface:
http://lnxpps.de/rpie

nexulm
Posts: 8
Joined: Tue Apr 02, 2013 8:42 am

Re: CAN controller

Sat Apr 13, 2013 12:32 pm

Hello,

two day ago I've measured the Interrupt and SPI behaviour on my 2x MCP2515 CAN-Interface setup.
I'm using raspbian with Kernel 3.6.y, the spi-latency patch and the newer MCP2515 driver. The MCP2515 interrupts are routed to GPIO25 (CAN0) and GPIO24 (CAN1).
The problem that one of the CAN interfaces (sometimes CAN0, sometimes CAN1 and the number of received frames on each CAN-Interaces differs also after each driver restart) stops sending and stays in Interrupt Low state can also be seen. For me that's not a problem of the "horse power" of BCM2835. Maybe it's more a general linux driver structure and interrupt priority questions, or? But I don't know th linux driver achitecture good enough so far. Furthermore IMO it doesn't depend directly on one-shot-irq because I've seen the same problem with Kernel 3.2.27 with Level-triggerd interrupt.
Two question from my side regarding the measurments are:
1. Why is there a delay of round about 30us between Interrupt Low of MCP2515 and SPI-Chip Enable?
2. Why is there a secand SPI read command after the MCP2515 is already on high level again?

Maybe someone has a explanation or some hints on this!

Due to limitations of attachments on this forum (max. per post) I've splittet them to two posts.
In general the file name explains the dependencies between Oscillosope channel and signal.
Attachments
MCP2515_Ch1_SCLK_Ch2_MOSI_Ch3_SPI_CE0_Ch4_INT0_CAN0_Start (Mobile).png
SPI read command (Start)
MCP2515_Ch1_SCLK_Ch2_MOSI_Ch3_SPI_CE0_Ch4_INT0_CAN0_Start (Mobile).png (55.21 KiB) Viewed 6659 times
MCP2515_Ch1_SPI_CE0_Ch2_INT0_Ch3_SPI_CE1_Ch4_INT1_CAN0_OK_CAN1_NOK (Mobile).png
CAN1 stops sending (INT stays low)
MCP2515_Ch1_SPI_CE0_Ch2_INT0_Ch3_SPI_CE1_Ch4_INT1_CAN0_OK_CAN1_NOK (Mobile).png (39.57 KiB) Viewed 6659 times
MCP2515_Ch1_SPI_CE0_Ch2_INT0_Ch3_SPI_CE1_Ch4_INT1_CAN0_CAN1 (Mobile).png
CAN0 and CAN1 are working fine
MCP2515_Ch1_SPI_CE0_Ch2_INT0_Ch3_SPI_CE1_Ch4_INT1_CAN0_CAN1 (Mobile).png (44.12 KiB) Viewed 6659 times
Last edited by nexulm on Sat Apr 13, 2013 12:38 pm, edited 2 times in total.

nexulm
Posts: 8
Joined: Tue Apr 02, 2013 8:42 am

Re: CAN controller

Sat Apr 13, 2013 12:35 pm

...and the missing measurements. ;-)

Mike
Attachments
MCP2515_Ch1_SCLK_Ch2_MOSI_Ch3_SPI_CE0_Ch4_INT0_CAN0_NOK (Mobile).png
SPI if CAN0 stops sending
MCP2515_Ch1_SCLK_Ch2_MOSI_Ch3_SPI_CE0_Ch4_INT0_CAN0_NOK (Mobile).png (59.33 KiB) Viewed 6659 times
MCP2515_Ch1_SCLK_Ch2_MOSI_Ch3_SPI_CE0_Ch4_INT0_CAN0_End (Mobile).png
SPI read command (end)
MCP2515_Ch1_SCLK_Ch2_MOSI_Ch3_SPI_CE0_Ch4_INT0_CAN0_End (Mobile).png (56.52 KiB) Viewed 6659 times

Zeta
Posts: 72
Joined: Wed Dec 12, 2012 9:51 pm

Re: CAN controller

Sat Apr 13, 2013 2:04 pm

nexulm wrote:For me that's not a problem of the "horse power" of BCM2835. Maybe it's more a general linux driver structure and interrupt priority questions, or? But I don't know th linux driver achitecture good enough so far. Furthermore IMO it doesn't depend directly on one-shot-irq because I've seen the same problem with Kernel 3.2.27 with Level-triggerd interrupt.
I agree the processing power is not the only problem here. Even if we miss some frames, which would be directly related to some "horse power" and architecture (our choice of using MCP2515 with only 2 buffers, and using 2 of them on the same SPI bus) limitations, it shouldn't simply stop working.
nexulm wrote:1. Why is there a delay of round about 30us between Interrupt Low of MCP2515 and SPI-Chip Enable?
It is the time taken by the gpio catchall interrupt handler to be called, to generate software irq, to pass the soft irq to the mcp2515 driver, which will request a spi read, that the spi driver will then handle... The "SPI low-latency" patch made by msperl already reduced this time.
Check this post for example : http://www.raspberrypi.org/phpBB3/viewt ... 19#p162719
nexulm wrote:2. Why is there a secand SPI read command after the MCP2515 is already on high level again?
It was answered too in this thread some time ago, see http://www.raspberrypi.org/phpBB3/viewt ... 24#p165924 and following messages:
bertr2d2 wrote:Reading the RX0 or RX1 automatically clears the interrupt. There is a third sequence
which reads the CANINTF+EFLG again.

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