send_periodic not working on RPI Linux 6.1.21-v8+
Describe the bug
Receiving the following error when calling send_periodic() on RPI (Linux 6.1.21-v8+) using socketcan bus: can.exceptions.CanOperationError: Couldn't send CAN BCM frame due to OS Error: Invalid argument You are probably referring to a non-existing frame. [Error Code 22]
Full trace:
python3.9 send_periodic_test.py
Traceback (most recent call last):
File "/home/pi/.local/lib/python3.9/site-packages/can/interfaces/socketcan/socketcan.py", line 275, in send_bcm
return bcm_socket.send(data)
OSError: [Errno 22] Invalid argument
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/pi/send_periodic_test.py", line 9, in <module>
interface.send_periodic(can.Message(arbitration_id=0x18FFFF00, data=[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), period=0.1, duration=1.0)
File "/home/pi/.local/lib/python3.9/site-packages/can/bus.py", line 241, in send_periodic
self._send_periodic_internal(msgs, period, duration),
File "/home/pi/.local/lib/python3.9/site-packages/can/interfaces/socketcan/socketcan.py", line 843, in _send_periodic_internal
task = CyclicSendTask(bcm_socket, task_id, msgs, period, duration)
File "/home/pi/.local/lib/python3.9/site-packages/can/interfaces/socketcan/socketcan.py", line 345, in __init__
self._tx_setup(self.messages)
File "/home/pi/.local/lib/python3.9/site-packages/can/interfaces/socketcan/socketcan.py", line 372, in _tx_setup
send_bcm(self.bcm_socket, header + body)
File "/home/pi/.local/lib/python3.9/site-packages/can/interfaces/socketcan/socketcan.py", line 288, in send_bcm
raise can.CanOperationError(base + specific_message, error.errno) from error
can.exceptions.CanOperationError: Couldn't send CAN BCM frame due to OS Error: Invalid argument You are probably referring to a non-existing frame. [Error Code 22]
SocketcanBus was not properly shut down
Python script:
import can
interface = can.interface.Bus(
channel='can0',
interface='socketcan',
bitrate=250000
)
interface.send(can.Message(arbitration_id=0x18FFFF00, data=[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]))
interface.send_periodic(can.Message(arbitration_id=0x18FFFF00, data=[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), period=0.1, duration=1.0)
interface.shutdown()
I set up RPI using latest Raspbian version, which is running Linux kernel version 6.1.21-v8+ (using python 3.9) . I am using seeed studio CAN hat with their overlay enabled. I have another RPI running Linux kernel version 5.10.11-v7l+ (using python 3.7) that has been working fine for some time now.
To Reproduce
Steps I did for a completely fresh install:
- Install latest Raspbian image or update existing image to Linux 6.1.21-v8+
- Enable SPI via raspi-config
-
sudo apt update -
sudo apt upgrade -
sudo apt install can-utils git python3-pip exfat-fuse exfat-utils -
python3 -m pip install python-can RPi.GPIO pigpio pandas numpy - Modify
/etc/network/interfaceswith:
auto can0
iface can0 inet manual
pre-up /sbin/ip link set $IFACE up type can bitrate 250000 sample-point 0.8 dbitrate 2000000 dsample-point 0.8 fd on
up /sbin/ifconfig $IFACE up
down /sbin/ifconfig $IFACE down
auto can1
iface can1 inet manual
pre-up /sbin/ip link set $IFACE up type can bitrate 250000 sample-point 0.8 dbitrate 2000000 dsample-point 0.8 fd on
up /sbin/ifconfig $IFACE up
down /sbin/ifconfig $IFACE down
-
Add
dtoverlay=seeed-can-fd-hat-v1(using older seeed studio hat without RTC) to/boot/config.txt -
Modify
/etc/rc.local
sudo ifconfig can0 txqueuelen 65535
sudo ifconfig can1 txqueuelen 65535
-
sudo reboot -
touch send_periodic_test.py - Add
import can
interface = can.interface.Bus(
channel='can0',
interface='socketcan',
bitrate=250000
)
interface.send(can.Message(arbitration_id=0x18FFFF00, data=[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]))
interface.send_periodic(can.Message(arbitration_id=0x18FFFF00, data=[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), period=0.1, duration=1.0)
interface.shutdown()
-
python3 send_periodic_test.py
Expected behavior
send_periodic should work as expected on latest Linux kernel.
Additional context
OS and version: Linux 6.1.21-v8+ Python version: Python 3.9.2 python-can version: 4.2.2 python-can interface/s (if applicable): socketcan
Traceback and logs
def func():
return "hello, world!"
I just did another fresh install but made sure to not update linux to v6 and the script runs fine.
5.10.92-v7l+ #1514 SMP Mon Jan 17 17:38:03 GMT 2022 armv7l GNU/Linux
@willem445 Did you test both kernel versions with the same python-can version? @hartkopp You would probably know if anything changed between 5.10.92 and 6.1.21... any idea what the problem might be?
Sorry should have mentioned that, yes I did. Summary:
works
pi@raspberrypi:~ $ uname -a
Linux raspberrypi 5.10.92-v7l+ #1514 SMP Mon Jan 17 17:38:03 GMT 2022 armv7l GNU/Linux
pi@raspberrypi:~ $ python3 -m pip freeze | grep python-can
python-can==4.2.2
pi@raspberrypi:~ $ python3
Python 3.9.2 (default, Mar 12 2021, 04:06:34)
[GCC 10.2.1 20210110] on linux
pi@raspberrypi:~ $ python3 send_periodic_test.py
does not work
pi@pitester1:~ $ uname -a
Linux pitester1 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux
pi@pitester1:~ $ python3 -m pip freeze | grep python-can
python-can==4.2.2
pi@pitester1:~ $ python3
Python 3.9.2 (default, Mar 12 2021, 04:06:34)
[GCC 10.2.1 20210110] on linux
pi@pitester1:~ $ python3 send_periodic_test.py
Traceback (most recent call last):
File "/home/pi/.local/lib/python3.9/site-packages/can/interfaces/socketcan/socketcan.py", line 275, in send_bcm
return bcm_socket.send(data)
OSError: [Errno 22] Invalid argument
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/pi/send_periodic_test.py", line 9, in <module>
interface.send_periodic(can.Message(arbitration_id=0x18FFFF00, data=[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), period=0.1, duration=1.0)
File "/home/pi/.local/lib/python3.9/site-packages/can/bus.py", line 241, in send_periodic
self._send_periodic_internal(msgs, period, duration),
File "/home/pi/.local/lib/python3.9/site-packages/can/interfaces/socketcan/socketcan.py", line 843, in _send_periodic_internal
task = CyclicSendTask(bcm_socket, task_id, msgs, period, duration)
File "/home/pi/.local/lib/python3.9/site-packages/can/interfaces/socketcan/socketcan.py", line 345, in __init__
self._tx_setup(self.messages)
File "/home/pi/.local/lib/python3.9/site-packages/can/interfaces/socketcan/socketcan.py", line 372, in _tx_setup
send_bcm(self.bcm_socket, header + body)
File "/home/pi/.local/lib/python3.9/site-packages/can/interfaces/socketcan/socketcan.py", line 288, in send_bcm
raise can.CanOperationError(base + specific_message, error.errno) from error
can.exceptions.CanOperationError: Couldn't send CAN BCM frame due to OS Error: Invalid argument You are probably referring to a non-existing frame. [Error Code 22]
SocketcanBus was not properly shut down
I did try reverting to python-can v3.3.3 (which is what my original PI had on it at first) on the Linux v6 PI but I had the same issue.
I did just notice that the older kernel is armv71 and the newer kernel is aarch64. Perhaps that is the issue?
@zariiii9003 That ended up being it. Upon googling, apparently new Raspbian on PI4s will prefer 64bit to 32bit kernel. I added arm_64bit=0 to boot/config.txt based on this and rebooted and now the script works:
pi@raspberrypi:~ $ uname -a
Linux raspberrypi 6.1.21-v7l+ #1642 SMP Mon Apr 3 17:22:30 BST 2023 armv7l GNU/Linux
pi@raspberrypi:~ $ python3 send_periodic_test.py
So I've found a fix for my immediate problem but I'm wondering if this is still a defect with python-can that needs to be resolved to work in the Linux 64bit environment?
Hi @willem445 ,
there is indeed a problem when mixing 32/64 bit kernels and user space (the integer values have different sizes in struct bcm_head).
When both are identical 32 bit OR 64 bit it works fine.
I remember some suggestion from @marckleinebudde to fix this issue for the CAN_BCM. I have to check the status of that attempt.
Btw. adding arm_64bit=0 in config.txt is a good find!