dplamp
Posts: 21
Joined: Mon Jan 21, 2013 9:23 am
Location: France

Re: CAN controller

Mon Oct 21, 2013 11:39 am

Hi,

Well, we're probably drifting off topic, but I gave it a try, actually :
1/ At the time, I used a MCP2515 and a PIC18F2550. Nowadays, a PIC32 with both USB and CAN capabilities is probably a better option.
2/ I chose Libusb-1.0, which is good, and had to develop on Windows, which is a pain in the xxx when it comes to USB. Libusb-1.0 has an elegant event-driven mode.
3/ I used 64-byte interrupt xfers in full-speed mode, but you can't send faster than at T=1ms. It seems that bulk transfers don't have this limitation.

In my opinion, the good thing is that it would be easily portable to a number of platforms, but the downside is that it takes 1 USB port. Will the USB port be able to power the board ?

Again, the MCP2515 solution leads to a very simple PCB, that fits in the Pi box, without extra firmware, cabling nor power supply !

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

Re: CAN controller

Mon Oct 21, 2013 11:59 am

Well , if you want to make use of the USB, then have a look at the existing USB to can bridge device drivers at: drivers/net/can/usb/...

If you mimic their API you might be even avoiding writing the linux driver itself, but if you want to learn something new, then write the linux-can driver as well...

Martin

Hugo2310
Posts: 4
Joined: Tue Mar 19, 2013 9:20 am

Re: CAN controller

Mon Oct 21, 2013 1:25 pm

Hi,

First of all: msperl, Zeta, maddin1234 and bertr2d2, and everyone else, thank you for sharing your work and teaching us beginners!

i'm watching this topic for a while now, til now every error i got was able to fix by reading further replies. but now i'm on an error i can't fix by using google or the forum :(

I set up my first SD-Card after the guide from maddin1234 » Fri Aug 17, 2012 4:11 pm. After some work i get it run, a month ago, attached to a CAN Simulation (Vector CANoe). I also have the problem, like cadsenthilkumar, that my mouse and keyboard aren't functional under Lxde.
After the comment from bertr2d2 » Sun Oct 06, 2013 7:06 pm i bought a second SD-Card and made the success that my Configuration was working in loopback mode. dmesg says "bit timig not yet defined". So i wanted to take a look at my first SD-Card. Bizarrely now there it says also "bit timing not yet defined".

The only thing i found was shortening the wires, so i made a small board. Working a 16mhz oscillator. but that gives no success. i hope my information is enough for you to work with. and of course my english isn't to bad :)

thanks in advance
Hugo

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

Re: CAN controller

Mon Oct 21, 2013 1:35 pm

If you see "bit timig not yet defined" in the output of dmesg, then - at least at some point in time - you did not have configured the baud-rate for the CAN controller...

This typically shows up as a new line every few seconds until you issue the following:

Code: Select all

/sbin/ip link set can0 type can bitrate 500000 <possibly add other args for loopback,...>
ifconfig can0 up
from then on the can-controller should be up and running fine and the message stops appearing...

Note that - if you set up the system to automatically start can - the message might appear in the window between when the modules/drivers get loaded and when the commands to configure baud get actually executed.

Hope this helps...

Ciao, Martin

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

Re: CAN controller

Mon Oct 21, 2013 10:56 pm

Msperl, Gerd,

I have tried to restart from scratch an install using the new drivers, given the archive Gerd provided, in order to update the wiki.
It is already late in the night here, so I will finish tomorrow. However I have a question you might already have solved, so here it is :

How do you do to load the mcp2515 driver and NOT the mcp251x ?

What I've done is that /etc/modules contains :
spi_bcm2708
spi-config devices=bus=0:cs=0:modalias=mcp2515:speed=10000000:gpioirq=25:pd=20:pds32-0=20000000:pdu32-4=0x2002:force_release
mcp2515
the spi-config module has the modalias set to mcp2515, however it seems it loads the mcp251x driver when loaded manually.

Here is the dmesg output (no mention of mcp2515, only mcp251x):

Code: Select all

[   12.692143] spi_config_register:spi0.0: registering modalias=mcp2515 with max_speed_hz=10000000 mode=0 and gpio/irq=25/195
[   12.726909] spi_config_register:spi0.0:platform data:c9e6db20: 00 2d 31 01 02 20 00 00 00 00 00 00 00 00 00 00  .-1.. ..........
[   12.744642] spi_config_register:spi0.0:platform data:c9e6db30: 00 00 00 00                                      ....
[   12.767685] CAN device driver interface
[   12.818466] mcp251x spi0.0: CANSTAT 0x80 CANCTRL 0x07
[   12.820147] mcp251x spi0.0: probed
[   20.970478] mcp251x spi0.0: CNF: 0x04 0xb5 0x01
the list of modules after a fresh boot (no modprobe command issued manually). Both modules are loaded even if I only requested mcp2515 :

Code: Select all

Module                  Size  Used by
can_raw                 6148  0 
can                    23604  1 can_raw
mcp2515                 6109  0 
mcp251x                 9494  0 
can_dev                 9485  2 mcp2515,mcp251x
spi_config              9384  0 
spidev                  5248  0 
spi_bcm2708             7453  0 
snd_bcm2835            16432  0 
snd_pcm                77728  1 snd_bcm2835
snd_page_alloc          5169  1 snd_pcm
snd_seq                53482  0 
snd_seq_device          6462  1 snd_seq
snd_timer              20110  2 snd_pcm,snd_seq
snd                    58744  5 snd_bcm2835,snd_timer,snd_pcm,snd_seq,snd_seq_device
joydev                  9356  0 
evdev                   9450  3 
hid_sunplus             1491  0 
leds_gpio               2243  0 
led_class               3570  1 leds_gpio
The cat /sys/bus/spi/devices/*/modalias output (here the mcp2515 is shown correctly)
spi:mcp2515
spi:spidev
The interrupt list, the interrupt is linked to mcp251x:

Code: Select all

           CPU0       
  3:       4451   ARMCTRL  BCM2708 Timer Tick
 16:          0   ARMCTRL  bcm2708_spi.0
 32:     106154   ARMCTRL  dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1
 52:          2   ARMCTRL  BCM2708 GPIO catchall handler
 65:        225   ARMCTRL  ARM Mailbox IRQ
 66:          1   ARMCTRL  VCHIQ doorbell
 75:          1   ARMCTRL
 77:       5829   ARMCTRL  bcm2708_sdhci (dma)
 80:         30   ARMCTRL  bcm2708_spi.0
 83:         19   ARMCTRL  uart-pl011
 84:       9127   ARMCTRL  mmc0
195:          2      GPIO  mcp251x
FIQ:              usb_fiq
Err:          0
And finally the ip output, mentionning again the mcp251x (don't worry for the error in it, I copied it after trying a cansend command with nothing on the bus, and was not in loopback. Communication with the chip is okay as I see some traffic on the transceiver I/O).

Code: Select all

3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 10
    link/can 
    can state ERROR-PASSIVE restart-ms 0 
    bitrate 125000 sample-point 0.875 
    tq 500 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
    mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
    clock 10000000
    re-started bus-errors arbit-lost error-warn error-pass bus-off
    0          0          0          1          1          0         
    RX: bytes  packets  errors  dropped overrun mcast   
    0          0        0       0       0       0      
    TX: bytes  packets  errors  dropped carrier collsns 
    0          0        0       0       0       0   
I must be missing something (probably only some sleep ;)
How can there be a dependency to the mcp251x driver so that it starts directly even if not requested... ?

I already noticed it when launching things by hand before (I was unloading mcp251x after loading spi and before loading mcp2515).

As soon as I can make this work automatically after reboot without manual intervention and have updated the wiki, then I will dig a bit more the debian package question, to see if I can make one for all this (I am thinking of some debug scripts that would be handy to had in it, so that beginners only have to run it to have details on what may be wrong : module not loaded, interface not started, error on the bus, and could even make an autobaud functionnality by trying each bus frequency and checking if there are errors at theses speed). No sure how long it would take to package it...

Thanks again !

Zeta

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

Re: CAN controller

Tue Oct 22, 2013 6:37 am

you only need to load one of the mcp drivers.

The mcp251x driver can handle a device configured with modinfo as mcp2510 and mcp2515.

While the mcp2515 driver can only handle a mcp2515 (probably mostly because you can not find a mcp2510 in any shop any more so testing with the "older" version was not possible).

When the linux SPI subsystem detects a driver matching pair of driver/device based on the modinfo it will use that and try to initiate that driver. But if there are multiple drivers in memory that can handle the same modinfo, then the first one loaded wins.
So this was your case...

As for the message showing up regularly: I guess that there is a feature in the kernel that tries to configure a CAN device every few seconds if it has not been configured yet. The problem here is that the driver itself just complains that it has not been configured and ads a message to the dmesg buffer. This was possibly a change somewhere in the lower parts of the CAN infrastructure that was changed after the driver got written, and the driver never got updated to remove that fact.

The same with the fact that since kernel 3.6 it has problems with interrupts, where the driver may be stuck in a situation where the interrupt line is still low, but it does not realize that fact... At some point we had level-interrupts instead of edge interrupts, but the kernel started to complain about the fact that it does not support the specific set of interrupt configs (or some additional configs would be required).

All this has not been addressed by modifications to the driver and that is why our recommendation for now is to use the mcp2515 driver, which is out of tree and which is missing some features nice for debugging initial connections (loopback, one-shot,...) But at least it does not "stop" in it tracks where only an unload/reload of the driver helps.

Anyway: both drivers are old and have issues, so as soon as I finish my spi-DMA driver I will start a new mcp2515 driver that tries to be as efficient as possible (making use of all the spi-DMA-driver features) so that we can transfer a message with minimal overhead delay and interrupts. Obviously it ideally would also be able to handle a 1MBit CAN-bus which is saturated with 0 byte length frames (that would be 15385 messages/second), but I might not be able to achive that...

The same with 500k Bus speed (=7692 messages/s) is already possible with the mcp2515 and my (unmaintained) realTime priority enabled spi-bcm2708 driver - note that if you use the forked version of notro, you may need to add the realtime=1 module parameter to get it in realtime mode...

Hope this answers your questions...

Martin

P.s: you can add the mcp251x driver to /etc/modprobe.d/raspi-blacklist.conf so that it does not get automatically loaded and then the mcp2515 might get loaded instead...

mugatu
Posts: 1
Joined: Wed Oct 23, 2013 11:28 am

Re: CAN controller

Wed Oct 23, 2013 11:39 am

Thanks to "maddin1234" for your reply, very very helpful information. I have gotten as far as step 7 and actually skipped it and went straight into step 8 (kernel has been compiling for many hours now, you weren't kidding about it taking a long time).

My question is about step 7: You mention that one needs to "create a new txt-file and name it for example bcm2708.diff copy the text of the posted patchfile from AlexB into that file and save it on an usb-stick." Where is said posted patchfile? Couldn't I just rename the patchfile as "bcm2708.diff" instead of creating a new text file?

Also, I am able to get into the "/usr/src/linux/arch/arm/mach-bcm2708" folder, no problem, however, the "# cp /media/usbstick/bcm2708.diff ." command gives me an error, can I replace the command with "# cp /media/usbstick/bcm2708.diff /usr/src/linux/arch/arm/mach-bcm2708?"

Finally, I am unable to run the "# patch -p0 <mcp2515_patch.diff" at all...where do I get the "mcp2515_patch.diff" file?

Please advise at your earliest convenience. Thanks again for your detailed instructions, folks on this board seem to have fairly advanced linux skills and a step-by-step guide was sorely needed.

# cd /usr/src/linux/arch/arm/mach-bcm2708
# cp /media/usbstick/bcm2708.diff .

Hugo2310
Posts: 4
Joined: Tue Mar 19, 2013 9:20 am

Re: CAN controller

Wed Oct 23, 2013 12:34 pm

i had the same problem i solved it like following.
with diff you check 2 files for differences. shown in the resulting .diff-file.
i get it run, by adding and deleting the shown codelines by foot. using nano. then you replace the original file with your changed one. using "cp /directory/changed_file_with_original_name.c /directory/original_file.c"

i'm sure there is a smarter way. but this worked for me.

later in discussion u find a package to download, where u don't have to recompile the kernel. if u just want to make it run, this is what u prefer, i guess.

zephyr91
Posts: 1
Joined: Wed Oct 23, 2013 1:07 pm

Re: CAN controller

Wed Oct 23, 2013 1:14 pm

Hugo, please let me know where in the discussion I can find " package to download, where u don't have to recompile the kernel." I don't see a link for it anywhere and it could certainly come in handy. Please let us know.


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

Re: CAN controller

Wed Oct 23, 2013 10:23 pm

Gerd,

For the debian package, I have not yet created it, but started to look at the documentation.
What I think is the easier would be to take the actual raspbian kernel package, and simply add some patches to it to include the drivers msperl wrote (and the new one too in a future version). I should also change the kernel version to be able to have both standard and modified kernel install and being able to switch with the bootloader if something goes wrong. Was this the solution you were thinking, or do you have something better in mind ?

Martin,

I spent some time fighting with the new setup, using Gerd archive. Here are some new things I discovered thanks to your pointers. I still have some things to understand a bit more before updating the wiki page...
msperl wrote:When the linux SPI subsystem detects a driver matching pair of driver/device based on the modinfo it will use that and try to initiate that driver. But if there are multiple drivers in memory that can handle the same modinfo, then the first one loaded wins.
So this was your case...
Yes, that was that !
What is strange is that only the mcp251x registers some modinfo, not the mcp2515 :

Code: Select all

# grep mcp251 /lib/modules/3.6.11+/modules.alias
alias spi:mcp2515 mcp251x
alias spi:mcp2510 mcp251x
If I remove the mcp251x.ko file from the drivers/net/can directory, to leave only the mcp2515.ko and run "depmod -a" to refresh, then the "spi:mcp2515" alias is not declared anymore (and not mcp251x either obviously as it doesn't support it). I have not yet open the drivers to see if it is something that is not declared in the mcp2515 driver, so maybe it is normal. It is one of the things I have to do tomorrow.
msperl wrote:As for the message showing up regularly: I guess that there is a feature in the kernel that tries to configure a CAN device every few seconds if it has not been configured yet. The problem here is that the driver itself just complains that it has not been configured and ads a message to the dmesg buffer. This was possibly a change somewhere in the lower parts of the CAN infrastructure that was changed after the driver got written, and the driver never got updated to remove that fact.
That is not much of a problem, as it only fills the dmesg output but doesn't prevent anything to work then. But it would be better to remove it.
msperl wrote:Anyway: both drivers are old and have issues, so as soon as I finish my spi-DMA driver I will start a new mcp2515 driver that tries to be as efficient as possible (making use of all the spi-DMA-driver features) so that we can transfer a message with minimal overhead delay and interrupts. Obviously it ideally would also be able to handle a 1MBit CAN-bus which is saturated with 0 byte length frames (that would be 15385 messages/second), but I might not be able to achive that...
I need to finish to make my setup starting autonomously first, then I will be able to spend some time to help you testing this (probably not on the coding side, as I am far behind you on linux driver concepts...).
msperl wrote:you can add the mcp251x driver to /etc/modprobe.d/raspi-blacklist.conf so that it does not get automatically loaded and then the mcp2515 might get loaded instead...
This works. The other way is to simply remove the mcp251x driver and updating the system with "depmod -a". The blacklist is still better as it allows to activate it later on without having to move back some files.

It should be possible to change the "/lib/modules/3.6.11+/modules.alias" file, to replace the "alias spi:mcp2515 mcp251x" by "alias spi:mcp2515 mcp2515", and in this case the spi-config module should automatically loads the mcp2515 module. But the system seems to use the binary file "/lib/modules/3.6.11+/modules.alias.bin" which is generated by depmod, and don't fallback to the text file if the binary doesn't exist. I have to read again the documentation to see how to do this change manually. Maybe it is better to handle that directly in the driver source code, as the mcp251x does ?


Anyway, I am still blocked about using the mcp2515 driver. I get something strange. I don't remember if it is the normal output or not of this driver :

Code: Select all

4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 10
    link/can 
    can state STOPPED restart-ms 0 
    bitrate 125000 sample-point 0.875 
    tq 500 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
    mcp2515: tseg1 2..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
    clock 10000000
    re-started bus-errors arbit-lost error-warn error-pass bus-off
    0          0          0          0          0          0         
    RX: bytes  packets  errors  dropped overrun mcast   
    0          0        0       0       0       0      
    TX: bytes  packets  errors  dropped carrier collsns 
    0          0        0       0       0       0  
It shouldn't be "UNKNOWN" and "STOPPED" ? I have not succeed in getting frames sent or received with this one, but seems ok with the mcp251x.

I am not sure if there is something to change in the spi-config call between the two drivers:

Code: Select all

spi-config devices=bus=0:cs=0:modalias=mcp2515:speed=10000000:gpioirq=25:pd=20:pds32-0=20000000:pdu32-4=0x2002:force_release
In particular I didn't take time to check what the pd, pds and pdu parameters were, and if they make sense to the mcp2515 driver.

I'll continue tomorrow, hopefully with a bit more success !

Thanks !
Zeta

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

Re: CAN controller

Thu Oct 24, 2013 9:50 pm

Ok, I found out the trick about the modinfo.

I took a look at both the mcp251x and mcp2515 source code.

What is missing in the mcp2515 is the following snippet:

Code: Select all

// Enumeration of all devices supported by this driver.
// There is only one device for the mcp2515, but I kept the principle of the enum to be easier to make it evolve
enum mcp2515_model {
        CAN_MCP2515 // Could be assigning a value using "= xxx"  if needed, but zero value is enough
};

// Construct the table containing the modinfo text, and the corresponding value
// This value is used by the driver to know which device it has been loaded for,
// in case several are supported
static const struct spi_device_id mcp2515_id_table[] = {
        { "mcp2515",    CAN_MCP2515 },
        { },
};

// Register the modinfo structure to the kernel
// As it is related to "spi", the name will appear as "spi:mcp2515" in the modules.alias file
MODULE_DEVICE_TABLE(spi, mcp2515_id_table);
It is then the depmod command that builds the modules.* files from these structures and macros.

Then, if needed by the driver to make some difference in behavior depending on the device, which is obviously not the case here where only one device is supported by the driver, but makes sense for the original mcp251x drivers which handled both mcp2515 and mcp2510, the current device id from the table (so it is one of the enum) can be retrieved by :

Code: Select all

// With "spi" of type "struct spi_device *spi"
switch(spi_get_device_id(spi)->driver_data)
{
    case CAN_MCP2515:
    // Some device specific code
    // ...
}
That should (not tried yet) make it to be loaded automatically using modinfo, from the spi-config call.

Martin, can you add this to your new CAN driver ?

I will give it a try using the current mcp2515 driver after setting up the .deb package by patching it.

Still a lot of points opened, looking at the next one !

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

Re: CAN controller

Fri Oct 25, 2013 6:27 am

Sorry, I forgot to respond yesterday, but seems as if you have found out yourself...

Anyway: the module construct needs to be there explicitly if you got a driver that has a different name - which is the case for my new driver right now (which is called mcp2515a for now).

This driver as of now is already configuring the mcp2515 - the receive/transmit code is still missing.
But it is also supporting all the other options for can:
Loop back,
One-shot,
Listen only,
That sampling argument (can't remember what it is called right now)

Flow diagrams for messages and callbacks have also been created, so that I will not forget anything...

Still I try to minimize the callbacks, as they directly map to interrupts and this is obviously a limiting resource...
My guess is that I should be able to make it work with only 2-3 interrupts per can message (assuming am handling each one separately).

Martin

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

Re: CAN controller

Sun Oct 27, 2013 9:03 am

While I am writing a newer driver for the mcp2515 chip, which tries to work VERY efficiently with the spi-bcm2835dma driver,
I am now having a question to all (potential) users:

What about absolute sequencing of messages?

Do we need to send out CAN-messages in correct sequence under any circumstances?
The question why I ask is because it should normally work "fine" if you send up to 3 CAN messages in a row, but as soon as you exceed that you may run into reordering issues due to the way that the HW works.
If this is a hard requirement, then the driver would need to sacrifice potential thru-put for this (under some circumstances).

A similar situation applies to receiving, but there I am not sure yet if I can achieve this under ALL circumstances - there might be some tricky race-conditions between HW and SW to make it work - especially if the linux side is very busy and the system comes closer to "loosing packets" due to long delays in scheduling. But then in such a situation we would come already close to loosing some packet, which would be even worth...

From my current plans for the driver, it should be possible to handle:
  • up to 2 receives of a CAN message
  • up to 3 transmits of a CAN message
  • all error handling (missed packets, BUS-error conditions,...)
with just 1 IRQ plus 2 SPI-callbacks.

In the case of the spi-bcm2835dma driver - when optimized with DMA pipelining - these Callbacks should map to a total of 2 interrupts for the whole handling, so we would handle all the above in a total of 3 interrupts. Obviously it is not very likley to get into such a situation because the CAN bus would not be able to handle this - we essentially would stall for 3 CAN-Messages on the bus...

Please give me your feedback on such requirements that you would like to have fulfilled with the new driver.

Thanks,
Martin

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

Re: CAN controller

Sun Oct 27, 2013 4:47 pm

msperl wrote:Do we need to send out CAN-messages in correct sequence under any circumstances?
The question why I ask is because it should normally work "fine" if you send up to 3 CAN messages in a row, but as soon as you exceed that you may run into reordering issues due to the way that the HW works.
If this is a hard requirement, then the driver would need to sacrifice potential thru-put for this (under some circumstances).

A similar situation applies to receiving, but there I am not sure yet if I can achieve this under ALL circumstances - there might be some tricky race-conditions between HW and SW to make it work - especially if the linux side is very busy and the system comes closer to "loosing packets" due to long delays in scheduling. But then in such a situation we would come already close to loosing some packet, which would be even worth...
I think for me it would still be okay. Of course keeping the absolute sequencing would be better, but if this is the only trade-off to be able to do it...

I took a look at the CANOpen spec to be sure. The main point where it could have been a problem was for SDO block transfers where a bunch of frames are sent without acknowledge in between. But as the frames are numbered, it is possible to buffer them on the receiving side and put them back in order.

This depends on the protocol used of course, and some other may not be possible to use with the order mixed...

msperl wrote:From my current plans for the driver, it should be possible to handle:
  • up to 2 receives of a CAN message
  • up to 3 transmits of a CAN message
  • all error handling (missed packets, BUS-error conditions,...)
with just 1 IRQ plus 2 SPI-callbacks.
Great ! Well done !

On my side, I am reading a lot of things about debian packages, and I am trying to build a kernel package (compiling on the rpi for several hours already...).
It is a bit messy, but I hope this first test will help me to understand how to do it correctly then. At this time I will add all the specific drivers (SPI and MCP2515) we are talking here.

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

Re: CAN controller

Sun Oct 27, 2013 11:02 pm

Hi!

Just a bit of progress on the SPI/mcp2515 driver combo:

The spi-bcm2835dma driver seems to work quite well - at least with the new mcp2515 driver

The mcp2515a driver is now able to receive packets and show them via candump.

A simple test-case that has:
  • the mcp2515 in listen only mode with 4MHz SPI-bus-speed
  • a single client on the can bus transmitting an extended 8-byte message at 500khz bus speed
  • as there is no other device on the CAN bus acknowledging packets it will try to send the frame repeatedly...
  • this results in the bus being 100% saturated with a frame sent every 0.000308seconds
  • this equals to 3246 packets/second
The statistics on the interface after a "few" packets:

Code: Select all

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:1237913 errors:2 dropped:0 overruns:0 frame:2
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10 
          RX bytes:9877777 (9.4 MiB)  TX bytes:0 (0.0 B)
So I have had 2 buffer-overrun while processing 1.2M packets - so about 0.00016% packet-loss...

vmstat shows:

Code: Select all

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 0  0      0 324412  23468  91832    0    0     0     0 17031 22978  3 69 28  0
 0  0      0 324380  23468  91832    0    0     0     0 16597 22959  3 65 32  0
 0  0      0 324316  23468  91832    0    0     0     0 16812 23350  0 69 31  0
 0  0      0 324220  23468  91832    0    0     0     0 16712 22787  0 71 29  0
 0  0      0 324220  23468  91832    0    0     0     0 17030 23033  1 69 30  0
 1  0      0 324284  23468  91832    0    0     0     0 16698 22918  0 71 29  0
 0  0      0 324348  23468  91832    0    0     0     0 16813 23416  1 70 28  0
 0  0      0 324316  23468  91832    0    0     0     0 16587 23014  1 68 31  0
 0  0      0 324284  23468  91832    0    0     0     0 16805 23330  1 68 31  0
 0  0      0 324284  23468  91832    0    0     0     0 16599 22966  1 68 31  0
 0  0      0 324284  23468  91832    0    0     0     0 17025 23063  1 73 26  0
So we run at around 16k interrupts/s and use about 70% of CPU with the full network stack.
If I disable the network-stack, then I get down to 62% CPU utilization.

Still, the number of interrupts are still quite high - the spi-bcm2835dma driver is not yet fully pipeline, so we get additional interrupts and CPU utilization is higher. Also two SPI-messages that are scheduled asyncroniously one after the other are spaced quite a bit apart due to the use of the transfer_one_message inteface still used.

Here what it looks like:
Screen Shot 2013-10-27 at 23.31.47a.png
Screenshot of a single transfer
Screen Shot 2013-10-27 at 23.31.47a.png (41.92 KiB) Viewed 6026 times
So there is still some overhead that can get reduced...
Screen Shot 2013-10-27 at 23.41.47.png
The bigger picture
Screen Shot 2013-10-27 at 23.41.47.png (24.89 KiB) Viewed 6026 times
Still it looks as if the RPI is heavily taxed with such a message load and I wonder how much "load" the driver pair can handle with smaller data sizes (or 1MBit traffic) - we might get close to reaching 100% CPU.

On the other hand - the driver is still just reading from the primary message buffer most of the time (not flowing over to the second buffer of the MCP2515). While this means obviously more traffic, the additional transfer would be much smaller than the scheduling "gaps" between the SPI transfers.

For most parts the driver is actually able to run with 500khz SPI Bus speed as well, but then we are loosing quite a few packets and we get heavy overruns (so big, that the counters for the overruns can not get relied upon, because they can only say, that it has happened, but not how often...)

There is still "space" for improvements on both sides of the drivers...

Ciao, Martin

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

Re: CAN controller

Mon Oct 28, 2013 11:48 pm

Martin, Gerd,

A quick update about my tinkering with debian kernel packages : It works !
I have not made anything special yet, only took the kernel source from the raspberry pi github and built it as a debian package, then installed it on the pi using the package manager, and rebooted to it.

I gave it another name, so that both the original and the modified kernel (and modules) can co-exist, and if something wrong happens, changing the config.txt file on the sd-card from another computer allows to boot back with the original kernel.

Code: Select all

pi@raspberrypi ~ $ uname -a
Linux raspberrypi 3.6.11-can-1+ #1 PREEMPT Sun Oct 27 15:39:51 UTC 2013 armv6l GNU/Linux
I intend to number the following updates -can-2, -can-3, etc...

So, now that I see how to do it (probably not correctly yet...), what should I include in this package ?
For the DMA support in the SPI driver, Gerd, you said that it needed a recompiled kernel, and not only the modules. Can you provide more details on this, to not forget something ?
Martin, is your mcp2515a driver ready for being included there yet (as experimental), or do you think I should stick to the "standard" mcp2515 for now ?
Same question goes for the SPI driver.
I will probably open a new thread for some questions about kernel packaging, to make it better. But It will not be before next week as I will not be available in the coming days.

Thanks !

Zeta

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

Re: CAN controller

Tue Oct 29, 2013 7:05 am

Sorry, both drivers still need some improvements to get into working order... (I just found that there is a race-condition that I can trigger when running with a slower spi bus on the spi driver).

Also there is the fact, that the mcp2515a driver right now can not send packets yet.

And the dma-spi driver is still not fully pipelined. But there the fact is that putting it into pipelined mode will mean that the depreciated message will show up. Why this is the case I have asked on the spi-devel list, but I did not get feedback on that...

I need to set priorities, but you can include the spi-bcm2835 (with my patches - see the pull request). The spi-bcm2835dma I would include only as a technology preview to give people the possibility to test.

Maybe you should also include the other /boot files in your packages. And -from what I have seen - there is a new mechanism for the kernel packages via raspberrypi-bootloader you may want to check that out.

For overall improvements please talk to popcornmix about those packages of yours, maybe they can go into raspbien themselves...

Martin

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

Re: CAN controller

Tue Oct 29, 2013 2:55 pm

Hi,
msperl wrote: What about absolute sequencing of messages?
Do we need to send out CAN-messages in correct sequence under any circumstances?
I would definitly say yes to this question. I do have an application which could run into trouble if
the sequence is out of order.

Martin, your efforts are really promising :-)

@Zeta,

I didn't expected, that you would like to compile the kernel. I just thought, that you take the tar archive and
make a binary debian package of this. Did you took the exact kernel source as the Raspbian distribution ?
For reference take this one "How to build LPICP kernel modules for raspbian on the R-PI"
http://hg.kewl.org/pub/k8048/file/e9127 ... ADME.lpicp

I patched the kernel with this patch:

Code: Select all

@@ -584,6 +584,9 @@ struct platform_device bcm2708_powerman_device = {
   .id = 0,
   .num_resources = ARRAY_SIZE(bcm2708_spi_resources),
   .resource = bcm2708_spi_resources,
+  .dev = {
+    .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
+  },
 };

 #ifdef CONFIG_SPI
Regards,

Gerd

P.S.: The last days I've done some experiments with a PIC18F26K80. This is a PIC
controller with CAN (ECAN) on board. This MCU costs only 1 Euro more than a
MCP2515 can do SPI-Slave (at 16MHz). The legacy CAN mode is nothing else
than a MCP2515. This might be an option, if we need a deeper FIFO (which I don't
like at all - huge buffers tend to be an alibi for moved programming problems) or could
offer an optimzed resgister set - eg. read CANINTF + EFLG and RXBn all in one request
which should minimize SPI sequences. Also you don't need to distinguisch between RXBn
and RXBn+1, just read the buffer. Create your perfect MCP2515 yourself :mrgreen:
The changes for the mcp251x/mcp2515a module should be very small.

The MCU could be programmed directly from RPi: http://dev.kewl.org/k8048/Doc/
Easy to build CAN-Bus interface:
http://lnxpps.de/rpie

danjperron
Posts: 3502
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: CAN controller

Tue Oct 29, 2013 4:27 pm

Hi Bertr2d2,

you don't even need that board to program the PIC18F26K80. The Rpi alone will do.

Check this post http://www.raspberrypi.org/phpBB3/viewt ... 43#p430643

I Know I'm a little bit off track but does anybody have knowledge about libcanopen from
https://github.com/rscada/libcanopen. I'm trying to figure out how to send raw TPDO in python 2.7.

SDO works fine but I don't have a clue on how to use the library TPDO method.

B.T.W. looks like that I won't need to do a driver since the mcp2515 driver I got from here works like a charm.

This is my current project http://www.raspberrypi.org/phpBB3/viewt ... 38#p444938


Thanks for the driver!

Daniel

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

Re: CAN controller

Tue Oct 29, 2013 4:35 pm

Hi Gert!

well - if you want to write the PIC firmware to emulate the mcp2515, but with more registers (or more hidden buffers - to use the default drivers), then feel free - you could also provide an SPI bootloader to get the thing programmed via SPIDEV or similar...

If you would want to improve on the "communication" pattern, there is the possibility to improve things a bit, but I believe we can manage with a set of 3 transfers:
  • get basic values for RX/TX
  • getting extra values - reading RX0 blindly to avoid further delay reading it later...
  • Scheduling additional Reads/Acks of RX packet.
As for my personal progress with the drivers:
  • the MCP2515a driver seems to be working stable for RX - it already contains a bit of error handling - to get improved and tested. But it needs to get the TX queues handled correctly as well (especially avoiding reordering)
  • the spi-bcm2835dma driver has some strange hiccups with DMA...
Overall the two together can handle arround 700k-1M on a saturated 500KHz CAN messages with 3-7 lost packets for the whole time and that with 2MHz SPI bus speed without triggering the DMA hiccup.

Still need to figure out WHY this really happens, because the DMA-Chain produced is essentially the same each time we run it.
My guess is that we have some concurrency issues on DMA transfers that can trigger such stalls...
Essentially both DMA queues are stalling without sending an interrupt to wake us up about the fact until it is too late...

The problem is somehow related to the fact that RX/TX DMAs are scheduling each other and some times this does not happen.
That I might have solved by moving away from the 2D DMA mode and configuring each register separately.

I was trying to be smart and was using 2D-Mode for DMA: 2x4byte transfers, increasing source by 4, decreasing destination by 4 to write 2 adjacent registers with a single DMA transfer in reverse order - first I need to write the address of the control-block @base+4 before starting the DMA by writing a bit pattern to @base+0.

But there is also the situation where a transfer gets aborted somehow early missing some bits - but only under some strange circumstances...

The devil lies in the details...

Martin

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

Re: CAN controller

Tue Oct 29, 2013 4:52 pm

Hi Daniel,
danjperron wrote:Hi Bertr2d2,

you don't even need that board to program the PIC18F26K80. The Rpi alone will do.

Check this post http://www.raspberrypi.org/phpBB3/viewt ... 43#p430643

I Know I'm a little bit off track but does anybody have knowledge about libcanopen from
https://github.com/rscada/libcanopen. I'm trying to figure out how to send raw TPDO in python 2.7.

SDO works fine but I don't have a clue on how to use the library TPDO method.

B.T.W. looks like that I won't need to do a driver since the mcp2515 driver I got from here works like a charm.
The driver works fine - if you only have low traffic. This is probably the reason why you haven't seen any problem yet.
This is my current project http://www.raspberrypi.org/phpBB3/viewt ... 38#p444938

Thanks for the driver!

Daniel
The mcp2515 code is from Andre B. Oliveira, with some SocketCAN team cleaning ...

Interesting project and python script :)

Just to be clear: The programmer mentioned above don't need any special board, it's done directly
from the RPi GPIOs like your Python script. The k8048 programmer code is able to programm
all LVP able 14/16 bit PICs (PIC10/12/14/16/18) IMHO and is awesome fast btw ...

Is the PIC-CAN code public ?

Regards

Gerd
Easy to build CAN-Bus interface:
http://lnxpps.de/rpie

danjperron
Posts: 3502
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: CAN controller

Tue Oct 29, 2013 5:02 pm

Hi Gert,

yes , just download it from the github. I specify M.I.T. license.

And yes! directly from the gpio at 3.3V. It won't be as fast but it will do the job.

Daniel

danjperron
Posts: 3502
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: CAN controller

Tue Oct 29, 2013 5:13 pm

Hi Gert,
I did try 1mbs full CANOpen TPDO transfer. It is possible that I lost packet but if I compare it to the stock driver, it didn't hang.

For me this is a big improvement!

Daniel

danjperron
Posts: 3502
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: CAN controller

Tue Oct 29, 2013 5:20 pm

Hi Gert,
are you talking about the pic18f26k80 for the led post.

I will put it on my github if any interest.

the base code is from canopennode v1 .10 from source forge.

Daniel

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