Discussion:
Writing socketCAN module for my own hardware
Florian Feldbauer
2014-08-12 07:51:16 UTC
Permalink
Hey all,

I have developed a CAN interface for the Raspberry Pi computer using th=
e=20
SJA1000 directly connected to the GPIOs of the CPU.
So far this interface is used as chardev and works fine.
But I'm also developing a user-space program using this CAN interface.=20
This program should also be compatible with other CAN interfaces like=20
the ones from PEAK or Kvazer. So I thought using socketCAN would be a=20
good idea.

Is there any documentation on how to write a socketCAN compatible kerne=
l=20
module for my own hardware?
I tried writing something similar to the sja1000_isa driver...
So far my modified kernel compiles and I can change bitrate and bring=20
the interface up.
But as soon as I try to send a CAN frame I get the error:
Error 105: No buffer space available

Any help appreciated!

Best regards,
=46lorian

--=20
----------------------------------------
| Dr. Florian Feldbauer |
| |
| Helmholtz-Institut Mainz / |
| Johannes Gutenberg-Universit=E4t Mainz |
| Johann-Joachim-Becher-Weg 36 |
| D-55128 Mainz |
| |
| Office: SB1 / 00-213 |
| Phone: (+49)6131 / 39-29605 |
----------------------------------------

--
To unsubscribe from this list: send the line "unsubscribe linux-can" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Marc Kleine-Budde
2014-08-12 08:24:07 UTC
Permalink
I have developed a CAN interface for the Raspberry Pi computer using the
SJA1000 directly connected to the GPIOs of the CPU.
This sounds very slow :)
So far this interface is used as chardev and works fine.
But I'm also developing a user-space program using this CAN interface.
This program should also be compatible with other CAN interfaces like
the ones from PEAK or Kvazer. So I thought using socketCAN would be a
good idea.
Yes.
Is there any documentation on how to write a socketCAN compatible kernel
module for my own hardware?
I tried writing something similar to the sja1000_isa driver...
IMHO sja1000_platform.c is a better blueprint, as it uses the device
tree to describe the hardware and does not rely on module parameters.
So far my modified kernel compiles and I can change bitrate and bring
the interface up.
Error 105: No buffer space available
You are sending CAN frames faster than the driver is able to send them,
you have to wait a bit, before sending new CAN frames.

Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
Florian Feldbauer
2014-08-12 08:57:23 UTC
Permalink
Hey,

Thanks for the quick answer.
Post by Marc Kleine-Budde
I have developed a CAN interface for the Raspberry Pi computer using=
the
Post by Marc Kleine-Budde
SJA1000 directly connected to the GPIOs of the CPU.
This sounds very slow :)
Actually no. At least with the chardev driver it was faster than the=20
PEAK USB-CAN-PRO
connected to my laptop.
But I'm using direct memory manipulation to set/clear the GPIOs.
This is much faster than using the designated GPIO functions from the=20
kernel...
Post by Marc Kleine-Budde
So far this interface is used as chardev and works fine.
But I'm also developing a user-space program using this CAN interfac=
e.
Post by Marc Kleine-Budde
This program should also be compatible with other CAN interfaces lik=
e
Post by Marc Kleine-Budde
the ones from PEAK or Kvazer. So I thought using socketCAN would be =
a
Post by Marc Kleine-Budde
good idea.
Yes.
Is there any documentation on how to write a socketCAN compatible ke=
rnel
Post by Marc Kleine-Budde
module for my own hardware?
I tried writing something similar to the sja1000_isa driver...
IMHO sja1000_platform.c is a better blueprint, as it uses the device
tree to describe the hardware and does not rely on module parameters.
Ok. I will have a look at it.
Post by Marc Kleine-Budde
So far my modified kernel compiles and I can change bitrate and brin=
g
Post by Marc Kleine-Budde
the interface up.
Error 105: No buffer space available
You are sending CAN frames faster than the driver is able to send the=
m,
Post by Marc Kleine-Budde
you have to wait a bit, before sending new CAN frames.
I'm using
int nbytes =3D write( fd, pframe, sizeof(can_frame_t) );
to send a message. I thought this function blocks until the write is=20
finished?

My old chardev module was based on the kernel module from PEAK systems =
and
thus had a FIFO buffer for sending and receiving messages.
From the above error, I assume, socketCAN has no internal buffer?
What happens if there are many messages received on a small timescale?

Florian
Post by Marc Kleine-Budde
Marc
--=20
----------------------------------------
| Dr. Florian Feldbauer |
| |
| Helmholtz-Institut Mainz / |
| Johannes Gutenberg-Universit=C3=A4t Mainz |
| Johann-Joachim-Becher-Weg 36 |
| D-55128 Mainz |
| |
| Office: SB1 / 00-213 |
| Phone: (+49)6131 / 39-29605 |
----------------------------------------

--
To unsubscribe from this list: send the line "unsubscribe linux-can" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Marc Kleine-Budde
2014-08-12 10:01:56 UTC
Permalink
Post by Florian Feldbauer
Post by Marc Kleine-Budde
I have developed a CAN interface for the Raspberry Pi computer using the
SJA1000 directly connected to the GPIOs of the CPU.
This sounds very slow :)
Actually no. At least with the chardev driver it was faster than the
PEAK USB-CAN-PRO
connected to my laptop.
But I'm using direct memory manipulation to set/clear the GPIOs.
This is much faster than using the designated GPIO functions from the
kernel...
Portability comes with a price.
Post by Florian Feldbauer
Post by Marc Kleine-Budde
So far this interface is used as chardev and works fine.
But I'm also developing a user-space program using this CAN interface.
This program should also be compatible with other CAN interfaces like
the ones from PEAK or Kvazer. So I thought using socketCAN would be a
good idea.
Yes.
Is there any documentation on how to write a socketCAN compatible kernel
module for my own hardware?
I tried writing something similar to the sja1000_isa driver...
IMHO sja1000_platform.c is a better blueprint, as it uses the device
tree to describe the hardware and does not rely on module parameters.
Ok. I will have a look at it.
Post by Marc Kleine-Budde
So far my modified kernel compiles and I can change bitrate and bring
the interface up.
Error 105: No buffer space available
You are sending CAN frames faster than the driver is able to send them,
you have to wait a bit, before sending new CAN frames.
I'm using
int nbytes = write( fd, pframe, sizeof(can_frame_t) );
to send a message. I thought this function blocks until the write is
finished?
No. It will return with a errno if the message cannot be queued.
Post by Florian Feldbauer
My old chardev module was based on the kernel module from PEAK systems and
thus had a FIFO buffer for sending and receiving messages.
From the above error, I assume, socketCAN has no internal buffer?
There are buffers for RX and TX.
Post by Florian Feldbauer
What happens if there are many messages received on a small timescale?
If the system can handle the RX load all messages will be queued. Then
there are per socket queues for your userspace applications. If a queue
if full, CAN frames will be dropped. You can get information about
dropped CAN frames with the recvmsg() system call. See candump.c from
the gitorious can-utils for an exmaple.

Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
Florian Feldbauer
2014-10-01 07:26:56 UTC
Permalink
Hey all,

I still have some problems with the socket CAN driver for
my Raspberry Pi CAN interface.
I added a printk statement in the read/write register functions to
see what happens.

Looking into the output of `dmesg` after loading the kernel module
I see in an endless loop appearing the lines

[ 129.210361] sja1000_raspi: Read register 0: 0x21
[ 129.210394] sja1000_raspi: Write register 4: 0x00
[ 129.210423] sja1000_raspi sja1000_raspi.0 can0: bit-timing not yet=20
defined

Is this an expected behavior?

After setting the bitrate using
$> ip link set can0 type can bitrate 250000
The above messages stop.

dmesg output at this point:
[ 172.870195] sja1000_raspi: Read register 15: 0xff
[ 172.870231] sja1000_raspi: Read register 14: 0xff
[ 172.872933] sja1000_raspi sja1000_raspi.0 can0: setting BTR0=3D0x01=20
BTR1=3D0x1c
[ 172.872971] sja1000_raspi: Write register 6: 0x01
[ 172.872987] sja1000_raspi: Write register 7: 0x1c
[ 173.269190] sja1000_raspi: Read register 0: 0x21
[ 173.269221] sja1000_raspi: Write register 4: 0x00
[ 173.269287] sja1000_raspi: Write register 15: 0x00
[ 173.269303] sja1000_raspi: Write register 14: 0x00
[ 173.269319] sja1000_raspi: Read register 12: 0xff
[ 173.269336] sja1000_raspi: Read register 0: 0x21
[ 173.269348] sja1000_raspi: Write register 0: 0x00
[ 173.269369] sja1000_raspi: Read register 0: 0x20
[ 173.269381] sja1000_raspi: Write register 4: 0x7f
[ 173.269446] sja1000_raspi: Read register 15: 0x0c
[ 173.269462] sja1000_raspi: Read register 14: 0x03

The main problem is: If I now try to change the bitrate again
I get a "Device or resource busy" error.
demsg shows in this case simply these to lines:
[ 445.848207] sja1000_raspi: Read register 15: 0x0c
[ 445.848241] sja1000_raspi: Read register 14: 0x03

After bringing the interface up and trying to listen on the CANbus
using candump from the can-utils I get nothing, although a second
node is sending frames and bitrate settings are correct.

I'm working with the raspberry pi kernel=20
(https://github.com/raspberrypi/linux)
version 3.12.y commit c256eb9968c8997dce47350d2075e42f1b3991d3

Source of my own kernel module is also on github
https://github.com/ffeldbauer/epics_RPi_can/blob/ver3.0.0/CAN_interface=
/driver/sja1000_raspi.c

As written before, I could not find a documentation of socketCAN and=20
simply tried
to "copy" the sja1000_isa.c driver...naybe I did something completely=20
wrong or missed
something?

Any help is very much appreciated!

Best regards,
=46lorian
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
I have developed a CAN interface for the Raspberry Pi computer usi=
ng the
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
SJA1000 directly connected to the GPIOs of the CPU.
This sounds very slow :)
Actually no. At least with the chardev driver it was faster than the
PEAK USB-CAN-PRO
connected to my laptop.
But I'm using direct memory manipulation to set/clear the GPIOs.
This is much faster than using the designated GPIO functions from th=
e
Post by Marc Kleine-Budde
Post by Florian Feldbauer
kernel...
Portability comes with a price.
Post by Florian Feldbauer
Post by Marc Kleine-Budde
So far this interface is used as chardev and works fine.
But I'm also developing a user-space program using this CAN interf=
ace.
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
This program should also be compatible with other CAN interfaces l=
ike
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
the ones from PEAK or Kvazer. So I thought using socketCAN would b=
e a
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
good idea.
Yes.
Is there any documentation on how to write a socketCAN compatible =
kernel
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
module for my own hardware?
I tried writing something similar to the sja1000_isa driver...
IMHO sja1000_platform.c is a better blueprint, as it uses the devic=
e
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
tree to describe the hardware and does not rely on module parameter=
s.
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Ok. I will have a look at it.
Post by Marc Kleine-Budde
So far my modified kernel compiles and I can change bitrate and br=
ing
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
the interface up.
Error 105: No buffer space available
You are sending CAN frames faster than the driver is able to send t=
hem,
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
you have to wait a bit, before sending new CAN frames.
I'm using
int nbytes =3D write( fd, pframe, sizeof(can_frame_t) );
to send a message. I thought this function blocks until the write is
finished?
No. It will return with a errno if the message cannot be queued.
Post by Florian Feldbauer
My old chardev module was based on the kernel module from PEAK syste=
ms and
Post by Marc Kleine-Budde
Post by Florian Feldbauer
thus had a FIFO buffer for sending and receiving messages.
From the above error, I assume, socketCAN has no internal buffer?
There are buffers for RX and TX.
Post by Florian Feldbauer
What happens if there are many messages received on a small timescal=
e?
Post by Marc Kleine-Budde
If the system can handle the RX load all messages will be queued. The=
n
Post by Marc Kleine-Budde
there are per socket queues for your userspace applications. If a que=
ue
Post by Marc Kleine-Budde
if full, CAN frames will be dropped. You can get information about
dropped CAN frames with the recvmsg() system call. See candump.c from
the gitorious can-utils for an exmaple.
Marc
--=20
----------------------------------------
| Dr. Florian Feldbauer |
| |
| Helmholtz-Institut Mainz / |
| Johannes Gutenberg-Universit=C3=A4t Mainz |
| Johann-Joachim-Becher-Weg 36 |
| D-55128 Mainz |
| |
| Office: SB1 / 00-213 |
| Phone: (+49)6131 / 39-29605 |
----------------------------------------

--
To unsubscribe from this list: send the line "unsubscribe linux-can" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Marc Kleine-Budde
2014-10-01 07:49:47 UTC
Permalink
Post by Florian Feldbauer
I still have some problems with the socket CAN driver for
my Raspberry Pi CAN interface.
I added a printk statement in the read/write register functions to
see what happens.
Looking into the output of `dmesg` after loading the kernel module
I see in an endless loop appearing the lines
[ 129.210361] sja1000_raspi: Read register 0: 0x21
[ 129.210394] sja1000_raspi: Write register 4: 0x00
[ 129.210423] sja1000_raspi sja1000_raspi.0 can0: bit-timing not yet
defined
Is this an expected behavior?
Do you have network manager or a similar program running that is trying
to handle the CAN interface?
Post by Florian Feldbauer
After setting the bitrate using
$> ip link set can0 type can bitrate 250000
The above messages stop.
[ 172.870195] sja1000_raspi: Read register 15: 0xff
[ 172.870231] sja1000_raspi: Read register 14: 0xff
[ 172.872933] sja1000_raspi sja1000_raspi.0 can0: setting BTR0=0x01
BTR1=0x1c
[ 172.872971] sja1000_raspi: Write register 6: 0x01
[ 172.872987] sja1000_raspi: Write register 7: 0x1c
[ 173.269190] sja1000_raspi: Read register 0: 0x21
[ 173.269221] sja1000_raspi: Write register 4: 0x00
[ 173.269287] sja1000_raspi: Write register 15: 0x00
[ 173.269303] sja1000_raspi: Write register 14: 0x00
[ 173.269319] sja1000_raspi: Read register 12: 0xff
[ 173.269336] sja1000_raspi: Read register 0: 0x21
[ 173.269348] sja1000_raspi: Write register 0: 0x00
[ 173.269369] sja1000_raspi: Read register 0: 0x20
[ 173.269381] sja1000_raspi: Write register 4: 0x7f
[ 173.269446] sja1000_raspi: Read register 15: 0x0c
[ 173.269462] sja1000_raspi: Read register 14: 0x03
The main problem is: If I now try to change the bitrate again
I get a "Device or resource busy" error.
You'll get this busy error if the device is still "up", so there is
someone who automatically does something similar to "ifconfig can0 up".
Post by Florian Feldbauer
[ 445.848207] sja1000_raspi: Read register 15: 0x0c
[ 445.848241] sja1000_raspi: Read register 14: 0x03
After bringing the interface up and trying to listen on the CANbus
using candump from the can-utils I get nothing, although a second
node is sending frames and bitrate settings are correct.
Do you get any interrupts?
Post by Florian Feldbauer
I'm working with the raspberry pi kernel
(https://github.com/raspberrypi/linux)
version 3.12.y commit c256eb9968c8997dce47350d2075e42f1b3991d3
Source of my own kernel module is also on github
https://github.com/ffeldbauer/epics_RPi_can/blob/ver3.0.0/CAN_interface/driver/sja1000_raspi.c
As written before, I could not find a documentation of socketCAN and
simply tried
to "copy" the sja1000_isa.c driver...naybe I did something completely
wrong or missed
something?
Yes, making a copy of the driver is probably not the right thing....
BTW: where's are the original copyright notes?
Post by Florian Feldbauer
Any help is very much appreciated!
regards,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
Florian Feldbauer
2014-10-01 12:32:22 UTC
Permalink
Post by Florian Feldbauer
I still have some problems with the socket CAN driver for
my Raspberry Pi CAN interface.
I added a printk statement in the read/write register functions to
see what happens.
Looking into the output of `dmesg` after loading the kernel module
I see in an endless loop appearing the lines
[ 129.210361] sja1000_raspi: Read register 0: 0x21
[ 129.210394] sja1000_raspi: Write register 4: 0x00
[ 129.210423] sja1000_raspi sja1000_raspi.0 can0: bit-timing not ye=
t
Post by Florian Feldbauer
defined
Is this an expected behavior?
Do you have network manager or a similar program running that is tryi=
ng
to handle the CAN interface?
network-manager is not installed and looking at the active services and=
=20
processes
I don't see anything which looks like a network manager...
Post by Florian Feldbauer
After setting the bitrate using
$> ip link set can0 type can bitrate 250000
The above messages stop.
[ 172.870195] sja1000_raspi: Read register 15: 0xff
[ 172.870231] sja1000_raspi: Read register 14: 0xff
[ 172.872933] sja1000_raspi sja1000_raspi.0 can0: setting BTR0=3D0x=
01
Post by Florian Feldbauer
BTR1=3D0x1c
[ 172.872971] sja1000_raspi: Write register 6: 0x01
[ 172.872987] sja1000_raspi: Write register 7: 0x1c
[ 173.269190] sja1000_raspi: Read register 0: 0x21
[ 173.269221] sja1000_raspi: Write register 4: 0x00
[ 173.269287] sja1000_raspi: Write register 15: 0x00
[ 173.269303] sja1000_raspi: Write register 14: 0x00
[ 173.269319] sja1000_raspi: Read register 12: 0xff
[ 173.269336] sja1000_raspi: Read register 0: 0x21
[ 173.269348] sja1000_raspi: Write register 0: 0x00
[ 173.269369] sja1000_raspi: Read register 0: 0x20
[ 173.269381] sja1000_raspi: Write register 4: 0x7f
[ 173.269446] sja1000_raspi: Read register 15: 0x0c
[ 173.269462] sja1000_raspi: Read register 14: 0x03
The main problem is: If I now try to change the bitrate again
I get a "Device or resource busy" error.
You'll get this busy error if the device is still "up", so there is
someone who automatically does something similar to "ifconfig can0 up=
".
hmm....I just noticed that, the interface is always brought up=20
automatically.
Even if I run `if config can0 down` the interface is brought up again..=
=2E.
Post by Florian Feldbauer
[ 445.848207] sja1000_raspi: Read register 15: 0x0c
[ 445.848241] sja1000_raspi: Read register 14: 0x03
After bringing the interface up and trying to listen on the CANbus
using candump from the can-utils I get nothing, although a second
node is sending frames and bitrate settings are correct.
Do you get any interrupts?
Seems not the case
Sending doesn't work either...
From a very quick look, it seems the GPIOs are not set...But to be sur=
e
I have to build a small adapter in order to properly connect our digita=
l=20
scope to it...
Post by Florian Feldbauer
I'm working with the raspberry pi kernel
(https://github.com/raspberrypi/linux)
version 3.12.y commit c256eb9968c8997dce47350d2075e42f1b3991d3
Source of my own kernel module is also on github
https://github.com/ffeldbauer/epics_RPi_can/blob/ver3.0.0/CAN_interf=
ace/driver/sja1000_raspi.c
Post by Florian Feldbauer
As written before, I could not find a documentation of socketCAN and
simply tried
to "copy" the sja1000_isa.c driver...naybe I did something completel=
y
Post by Florian Feldbauer
wrong or missed
something?
Yes, making a copy of the driver is probably not the right thing....
BTW: where's are the original copyright notes?
"Copy" in this case means: I looked into=20
sja1000_isa.c/sja1000_platform.c to see what function have
to be implemented and what parameters do they use.
I copied the corresponding functions from my chardev driver and modifie=
d=20
them
accordingly....
Post by Florian Feldbauer
Any help is very much appreciated!
regards,
Marc
--=20
----------------------------------------
| Dr. Florian Feldbauer |
| |
| Helmholtz-Institut Mainz / |
| Johannes Gutenberg-Universit=C3=A4t Mainz |
| Johann-Joachim-Becher-Weg 36 |
| D-55128 Mainz |
| |
| Office: SB1 / 00-213 |
| Phone: (+49)6131 / 39-29605 |
----------------------------------------

--
To unsubscribe from this list: send the line "unsubscribe linux-can" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Marc Kleine-Budde
2014-10-01 12:41:43 UTC
Permalink
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Do you get any interrupts?
Seems not the case
Sending doesn't work either...
From a very quick look, it seems the GPIOs are not set...But to be sure
I have to build a small adapter in order to properly connect our digital
scope to it...
Let's see if there is actual output on the GPIO lines...

BTW: what's the use-case of the rpi, better buy a beagle bone black.
IIRC you need to attach the CAN phy, and you're ready to go. It comes
with two internal CAN cores, the first one is quite easy to setup, the
second one uses the same pins as one the the I2C busses, which has to be
disabled then... And you can use a proper mainline kernel.
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Post by Florian Feldbauer
I'm working with the raspberry pi kernel
(https://github.com/raspberrypi/linux)
version 3.12.y commit c256eb9968c8997dce47350d2075e42f1b3991d3
Source of my own kernel module is also on github
https://github.com/ffeldbauer/epics_RPi_can/blob/ver3.0.0/CAN_interface/driver/sja1000_raspi.c
As written before, I could not find a documentation of socketCAN and
simply tried
to "copy" the sja1000_isa.c driver...naybe I did something completely
wrong or missed
something?
Yes, making a copy of the driver is probably not the right thing....
BTW: where's are the original copyright notes?
"Copy" in this case means: I looked into
sja1000_isa.c/sja1000_platform.c to see what function have
to be implemented and what parameters do they use.
I copied the corresponding functions from my chardev driver and modified
them
accordingly....
IANAL, but it's best practice to state which parts of your driver is
based on the work of others.

Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
Florian Feldbauer
2014-10-01 12:56:29 UTC
Permalink
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Do you get any interrupts?
Seems not the case
Sending doesn't work either...
From a very quick look, it seems the GPIOs are not set...But to be =
sure
Post by Marc Kleine-Budde
Post by Florian Feldbauer
I have to build a small adapter in order to properly connect our dig=
ital
Post by Marc Kleine-Budde
Post by Florian Feldbauer
scope to it...
Let's see if there is actual output on the GPIO lines...
BTW: what's the use-case of the rpi, better buy a beagle bone black.
IIRC you need to attach the CAN phy, and you're ready to go. It comes
with two internal CAN cores, the first one is quite easy to setup, th=
e
Post by Marc Kleine-Budde
second one uses the same pins as one the the I2C busses, which has to=
be
Post by Marc Kleine-Budde
disabled then... And you can use a proper mainline kernel.
I'm working at the university for experimental hadron physik. And for
our experiment we need a low budget, high performance CANbus interface
running under Linux.
We came up with the idea of the Rpi, since it's small, it has ethernet,=
=20
and it is
cheap (~30 euro). And with the sja1000 connected to the GPIOs you can=20
achieve
the high data throughput (up to 6666 extended data frames with 8 byte=20
length @1Mbit/s)

Actually I don't know if any other embedded linux board like the beagle=
=20
bone
was considered...
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Post by Florian Feldbauer
I'm working with the raspberry pi kernel
(https://github.com/raspberrypi/linux)
version 3.12.y commit c256eb9968c8997dce47350d2075e42f1b3991d3
Source of my own kernel module is also on github
https://github.com/ffeldbauer/epics_RPi_can/blob/ver3.0.0/CAN_inte=
rface/driver/sja1000_raspi.c
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Post by Florian Feldbauer
As written before, I could not find a documentation of socketCAN a=
nd
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Post by Florian Feldbauer
simply tried
to "copy" the sja1000_isa.c driver...naybe I did something complet=
ely
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Post by Florian Feldbauer
wrong or missed
something?
Yes, making a copy of the driver is probably not the right thing...=
=2E
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
BTW: where's are the original copyright notes?
"Copy" in this case means: I looked into
sja1000_isa.c/sja1000_platform.c to see what function have
to be implemented and what parameters do they use.
I copied the corresponding functions from my chardev driver and modi=
fied
Post by Marc Kleine-Budde
Post by Florian Feldbauer
them
accordingly....
IANAL, but it's best practice to state which parts of your driver is
based on the work of others.
Yes, you're right! It will be added in the next commit...
(The current branch ver3.0.0 of my repo is currently still a developmen=
t=20
branch...)

Florian
Post by Marc Kleine-Budde
Marc
--=20
----------------------------------------
| Dr. Florian Feldbauer |
| |
| Helmholtz-Institut Mainz / |
| Johannes Gutenberg-Universit=C3=A4t Mainz |
| Johann-Joachim-Becher-Weg 36 |
| D-55128 Mainz |
| |
| Office: SB1 / 00-213 |
| Phone: (+49)6131 / 39-29605 |
----------------------------------------

--
To unsubscribe from this list: send the line "unsubscribe linux-can" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Marc Kleine-Budde
2014-10-01 13:11:56 UTC
Permalink
Post by Florian Feldbauer
Post by Marc Kleine-Budde
BTW: what's the use-case of the rpi, better buy a beagle bone black.
IIRC you need to attach the CAN phy, and you're ready to go. It comes
with two internal CAN cores, the first one is quite easy to setup, the
second one uses the same pins as one the the I2C busses, which has to be
disabled then... And you can use a proper mainline kernel.
I'm working at the university for experimental hadron physik. And for
our experiment we need a low budget, high performance CANbus interface
running under Linux.
High performance and bit banging in one sentence (or SoC) is a bit
contradictory :)
Post by Florian Feldbauer
We came up with the idea of the Rpi, since it's small, it has ethernet,
and it is
cheap (~30 euro). And with the sja1000 connected to the GPIOs you can
achieve
the high data throughput (up to 6666 extended data frames with 8 byte
Beagle Bone is about ~60€ in single quantities.
Post by Florian Feldbauer
Actually I don't know if any other embedded linux board like the beagle
bone
was considered...
:(

Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
Florian Feldbauer
2014-10-09 15:06:42 UTC
Permalink
Hey all,

I now checked everything with a mixed signal scope and
one thing came to my eye:

After loading the module, I get the error:
[ 16.806860] sja1000_raspi sja1000_raspi.0: registering sja1000_raspi=
=20
device (reg_base=3D0xf2200000, irq=3D174)
[ 16.836560] sja1000_raspi sja1000_raspi.0 (unregistered net_device):=
=20
setting SJA1000 into reset mode failed!
[ 16.871684] sja1000_raspi sja1000_raspi.0: sja1000_raspi device=20
registered (reg_base=3D0xf2200000, irq=3D174)

Although I can see at the scope, that reading register 0 of the SJA1000=
=20
returns the value 1 as it should be.
Also, it seems that there is some kind of endless loop reading this=20
register.

Now, what I don't understand at all:
Removing the module and loading it again works.
I don't get the error that setting the SJA1000 into reset mode failed,
the register is only read once after loading the module,
and sending/reading CAN frames from the bus after setting a proper=20
bitrate works too....

Any Ideas why the first initialization of the kernel module doesn't wor=
k?
When is the probe function of the module actually called?

A completely other question: I wanted to use libsocketcan to check the=20
state of the interface,
bringing it up in case it's down, within my C/C++ Program.
Is there a way to use this lib as a normal user? Maybe some group the=20
user has to be in?

Regards,
=46lorian
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Do you get any interrupts?
Seems not the case
Sending doesn't work either...
From a very quick look, it seems the GPIOs are not set...But to be =
sure
Post by Marc Kleine-Budde
Post by Florian Feldbauer
I have to build a small adapter in order to properly connect our dig=
ital
Post by Marc Kleine-Budde
Post by Florian Feldbauer
scope to it...
Let's see if there is actual output on the GPIO lines...
BTW: what's the use-case of the rpi, better buy a beagle bone black.
IIRC you need to attach the CAN phy, and you're ready to go. It comes
with two internal CAN cores, the first one is quite easy to setup, th=
e
Post by Marc Kleine-Budde
second one uses the same pins as one the the I2C busses, which has to=
be
Post by Marc Kleine-Budde
disabled then... And you can use a proper mainline kernel.
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Post by Florian Feldbauer
I'm working with the raspberry pi kernel
(https://github.com/raspberrypi/linux)
version 3.12.y commit c256eb9968c8997dce47350d2075e42f1b3991d3
Source of my own kernel module is also on github
https://github.com/ffeldbauer/epics_RPi_can/blob/ver3.0.0/CAN_inte=
rface/driver/sja1000_raspi.c
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Post by Florian Feldbauer
As written before, I could not find a documentation of socketCAN a=
nd
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Post by Florian Feldbauer
simply tried
to "copy" the sja1000_isa.c driver...naybe I did something complet=
ely
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Post by Florian Feldbauer
wrong or missed
something?
Yes, making a copy of the driver is probably not the right thing...=
=2E
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
BTW: where's are the original copyright notes?
"Copy" in this case means: I looked into
sja1000_isa.c/sja1000_platform.c to see what function have
to be implemented and what parameters do they use.
I copied the corresponding functions from my chardev driver and modi=
fied
Post by Marc Kleine-Budde
Post by Florian Feldbauer
them
accordingly....
IANAL, but it's best practice to state which parts of your driver is
based on the work of others.
Marc
--=20
----------------------------------------
| Dr. Florian Feldbauer |
| |
| Helmholtz-Institut Mainz / |
| Johannes Gutenberg-Universit=C3=A4t Mainz |
| Johann-Joachim-Becher-Weg 36 |
| D-55128 Mainz |
| |
| Office: SB1 / 00-213 |
| Phone: (+49)6131 / 39-29605 |
----------------------------------------

--
To unsubscribe from this list: send the line "unsubscribe linux-can" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Marc Kleine-Budde
2014-10-09 16:13:55 UTC
Permalink
Hello Florian,

please don't top-post.
Post by Florian Feldbauer
I now checked everything with a mixed signal scope and
[ 16.806860] sja1000_raspi sja1000_raspi.0: registering sja1000_raspi
device (reg_base=0xf2200000, irq=174)
setting SJA1000 into reset mode failed!
[ 16.871684] sja1000_raspi sja1000_raspi.0: sja1000_raspi device
registered (reg_base=0xf2200000, irq=174)
Although I can see at the scope, that reading register 0 of the SJA1000
returns the value 1 as it should be.
Also, it seems that there is some kind of endless loop reading this
register.
No, just a loop of up to 100 :)
Post by Florian Feldbauer
static void set_reset_mode(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
unsigned char status = priv->read_reg(priv, SJA1000_MOD);
int i;
/* disable interrupts */
priv->write_reg(priv, SJA1000_IER, IRQ_OFF);
for (i = 0; i < 100; i++) {
/* check reset bit */
if (status & MOD_RM) {
priv->can.state = CAN_STATE_STOPPED;
return;
}
/* reset chip */
priv->write_reg(priv, SJA1000_MOD, MOD_RM);
udelay(10);
status = priv->read_reg(priv, SJA1000_MOD);
}
netdev_err(dev, "setting SJA1000 into reset mode failed!\n");
}
Instrument this code to see what's going on.
Post by Florian Feldbauer
Removing the module and loading it again works.
I don't get the error that setting the SJA1000 into reset mode failed,
the register is only read once after loading the module,
and sending/reading CAN frames from the bus after setting a proper
bitrate works too....
Maybe the delay is to small for your big banging io interface.
Post by Florian Feldbauer
Any Ideas why the first initialization of the kernel module doesn't work?
When is the probe function of the module actually called?
As soon as there is a matching driver//device combination on a bus.
Looking at your driver, it's racy. You should not do any hardware setup
in the init function.
Post by Florian Feldbauer
A completely other question: I wanted to use libsocketcan to check the
state of the interface,
bringing it up in case it's down, within my C/C++ Program.
Is there a way to use this lib as a normal user? Maybe some group the
user has to be in?
IIRC your process needs NET_ADMIN capabilities (CAP_NET_ADMIN). I
personally never used capabilities, but there are libcap and libcap-ng
(https://people.redhat.com/sgrubb/libcap-ng/), which might help.

Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
Florian Feldbauer
2014-10-10 07:43:49 UTC
Permalink
Hey,
Post by Marc Kleine-Budde
Hello Florian,
please don't top-post.
Post by Florian Feldbauer
I now checked everything with a mixed signal scope and
[ 16.806860] sja1000_raspi sja1000_raspi.0: registering sja1000_ra=
spi
Post by Marc Kleine-Budde
Post by Florian Feldbauer
device (reg_base=3D0xf2200000, irq=3D174)
[ 16.836560] sja1000_raspi sja1000_raspi.0 (unregistered net_devic=
setting SJA1000 into reset mode failed!
[ 16.871684] sja1000_raspi sja1000_raspi.0: sja1000_raspi device
registered (reg_base=3D0xf2200000, irq=3D174)
Although I can see at the scope, that reading register 0 of the SJA1=
000
Post by Marc Kleine-Budde
Post by Florian Feldbauer
returns the value 1 as it should be.
Also, it seems that there is some kind of endless loop reading this
register.
No, just a loop of up to 100 :)
Maybe it's correlated with the issue that the message
[ 129.210423] sja1000_raspi sja1000_raspi.0 can0: bit-timing not yet
appears over and over again in dmesg, but register 0 is definitely
read more than 100 times...
Post by Marc Kleine-Budde
Post by Florian Feldbauer
static void set_reset_mode(struct net_device *dev)
{
struct sja1000_priv *priv =3D netdev_priv(dev);
unsigned char status =3D priv->read_reg(priv, SJA1000_MOD);
int i;
=
=20
Post by Marc Kleine-Budde
Post by Florian Feldbauer
/* disable interrupts */
priv->write_reg(priv, SJA1000_IER, IRQ_OFF);
=
=20
Post by Marc Kleine-Budde
Post by Florian Feldbauer
for (i =3D 0; i < 100; i++) {
/* check reset bit */
if (status & MOD_RM) {
priv->can.state =3D CAN_STATE_STOPPED;
return;
}
=
=20
Post by Marc Kleine-Budde
Post by Florian Feldbauer
/* reset chip */
priv->write_reg(priv, SJA1000_MOD, MOD_RM);
udelay(10);
status =3D priv->read_reg(priv, SJA1000_MOD);
}
=
=20
Post by Marc Kleine-Budde
Post by Florian Feldbauer
netdev_err(dev, "setting SJA1000 into reset mode failed!\n"=
);
Post by Marc Kleine-Budde
Post by Florian Feldbauer
}
Instrument this code to see what's going on.
Post by Florian Feldbauer
Removing the module and loading it again works.
I don't get the error that setting the SJA1000 into reset mode faile=
d,
Post by Marc Kleine-Budde
Post by Florian Feldbauer
the register is only read once after loading the module,
and sending/reading CAN frames from the bus after setting a proper
bitrate works too....
Maybe the delay is to small for your big banging io interface.
Post by Florian Feldbauer
Any Ideas why the first initialization of the kernel module doesn't =
work?
Post by Marc Kleine-Budde
Post by Florian Feldbauer
When is the probe function of the module actually called?
As soon as there is a matching driver//device combination on a bus.
Looking at your driver, it's racy. You should not do any hardware set=
up
Post by Marc Kleine-Budde
in the init function.
Ok...I moved the whole configuration of the GPIOs into the probe=20
function (instead of the init)
and now it works! Thanks!

Now I only have to solve the problem, that bringing the interface down=20
is not possible....
Always need to reboot just to change bitrate is no fun.
Maybe I should consult the Raspberry community, if there is some kind o=
f=20
network manager...

Again, many thanks for your help!!
Regards,
=46lorian
Post by Marc Kleine-Budde
Post by Florian Feldbauer
A completely other question: I wanted to use libsocketcan to check t=
he
Post by Marc Kleine-Budde
Post by Florian Feldbauer
state of the interface,
bringing it up in case it's down, within my C/C++ Program.
Is there a way to use this lib as a normal user? Maybe some group th=
e
Post by Marc Kleine-Budde
Post by Florian Feldbauer
user has to be in?
IIRC your process needs NET_ADMIN capabilities (CAP_NET_ADMIN). I
personally never used capabilities, but there are libcap and libcap-n=
g
Post by Marc Kleine-Budde
(https://people.redhat.com/sgrubb/libcap-ng/), which might help.
Marc
--=20
----------------------------------------
| Dr. Florian Feldbauer |
| |
| Helmholtz-Institut Mainz / |
| Johannes Gutenberg-Universit=C3=A4t Mainz |
| Johann-Joachim-Becher-Weg 36 |
| D-55128 Mainz |
| |
| Office: SB1 / 00-213 |
| Phone: (+49)6131 / 39-29605 |
----------------------------------------

--
To unsubscribe from this list: send the line "unsubscribe linux-can" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Marc Kleine-Budde
2014-10-10 08:06:33 UTC
Permalink
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Although I can see at the scope, that reading register 0 of the SJA1000
returns the value 1 as it should be.
Also, it seems that there is some kind of endless loop reading this
register.
No, just a loop of up to 100 :)
Maybe it's correlated with the issue that the message
[ 129.210423] sja1000_raspi sja1000_raspi.0 can0: bit-timing not yet
appears over and over again in dmesg, but register 0 is definitely
read more than 100 times...
As mentioned earlier, you have probably a mechanism running on your
system, that tries to enable the CAN interface. Bringing up the
interface without a set bit-rate is not allowed.

[...]
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Any Ideas why the first initialization of the kernel module doesn't work?
When is the probe function of the module actually called?
As soon as there is a matching driver//device combination on a bus.
Looking at your driver, it's racy. You should not do any hardware setup
in the init function.
Ok...I moved the whole configuration of the GPIOs into the probe
function (instead of the init)
and now it works! Thanks!
Now I only have to solve the problem, that bringing the interface down
is not possible....
Always need to reboot just to change bitrate is no fun.
Maybe I should consult the Raspberry community, if there is some kind of
network manager...
What kind of distribution are you using?

Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
Florian Feldbauer
2014-10-10 08:09:22 UTC
Permalink
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Although I can see at the scope, that reading register 0 of the SJ=
A1000
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
returns the value 1 as it should be.
Also, it seems that there is some kind of endless loop reading thi=
s
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
register.
No, just a loop of up to 100 :)
Maybe it's correlated with the issue that the message
[ 129.210423] sja1000_raspi sja1000_raspi.0 can0: bit-timing not ye=
t
Post by Marc Kleine-Budde
Post by Florian Feldbauer
appears over and over again in dmesg, but register 0 is definitely
read more than 100 times...
As mentioned earlier, you have probably a mechanism running on your
system, that tries to enable the CAN interface. Bringing up the
interface without a set bit-rate is not allowed.
[...]
Post by Florian Feldbauer
Post by Marc Kleine-Budde
Any Ideas why the first initialization of the kernel module doesn'=
t
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
work?
When is the probe function of the module actually called?
As soon as there is a matching driver//device combination on a bus.
Looking at your driver, it's racy. You should not do any hardware s=
etup
Post by Marc Kleine-Budde
Post by Florian Feldbauer
Post by Marc Kleine-Budde
in the init function.
Ok...I moved the whole configuration of the GPIOs into the probe
function (instead of the init)
and now it works! Thanks!
Now I only have to solve the problem, that bringing the interface do=
wn
Post by Marc Kleine-Budde
Post by Florian Feldbauer
is not possible....
Always need to reboot just to change bitrate is no fun.
Maybe I should consult the Raspberry community, if there is some kin=
d of
Post by Marc Kleine-Budde
Post by Florian Feldbauer
network manager...
What kind of distribution are you using?
raspbian wheezy, version from 2014-09-09
Post by Marc Kleine-Budde
Marc
--=20
----------------------------------------
| Dr. Florian Feldbauer |
| |
| Helmholtz-Institut Mainz / |
| Johannes Gutenberg-Universit=C3=A4t Mainz |
| Johann-Joachim-Becher-Weg 36 |
| D-55128 Mainz |
| |
| Office: SB1 / 00-213 |
| Phone: (+49)6131 / 39-29605 |
----------------------------------------

--
To unsubscribe from this list: send the line "unsubscribe linux-can" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Loading...