The bus locks up because pins 96 and 97 never leave UART1 mode: on Debian 9.4 IoT the real-time kernel build ignores the CAN overlay, and the old cape_enable line loads nothing. Boot the stock kernel, set uboot_overlay_addr4=/lib/firmware/BB-CAN1-00A0.dtbo in /boot/uEnv.txt, and confirm pinmux_dcan1_pins in pinmux-pins before starting CODESYS.
A CAN bus that locks every node wired to it, on a BeagleBone Black running CODESYS, is an image problem before it is a wiring problem. On the Debian 9.4 IoT image the two pins that carry DCAN1, pins 96 and 97, stay in UART1 mode unless a U-Boot overlay switches them to mode 2. The real-time kernel build leaves that overlay unapplied. The CANopen manager still reports Running, because the runtime started; nothing reaches the wire. Two decisions fix it: boot the stock kernel, and load BB-CAN1-00A0.dtbo through uboot_overlay_addr4 in /boot/uEnv.txt. Confirm the pin state in pinmux-pins before you open CODESYS again.
Why does the CAN bus lock up every device you wire to it?
The pins never left UART1. On this image the overlay that switches pins 96 and 97 to DCAN1 is applied by U-Boot, and the real-time kernel build leaves them untouched. The controller drives nothing onto the header. Every node then looks dead to CODESYS, and a scan inside the CANopen device dialog can freeze the development environment while it waits on a controller that owns no pins.
The symptoms collected on the bench already point at the image layer:
- Manager reports Running, the device scan freezes. The runtime is up with no working controller under it. Look at hops 2 to 4 below.
- Two boards, two CAN capes and two transceivers behave identically. The fault follows the software image, not the wire.
- A decoding scope shows the transducer running at 500 kbps on its own. Bit rate and node ID are right; the failure sits above the wire.
pinmux-pinslists pins 96 and 97 under UART1. The overlay never applied, so DCAN1 drives nothing onto the header./boot/uEnv.txtstill carriescape_enable=bone_capemgr.enable_partno=BB-CAN1. That mechanism is gone on this image, and the line loads no overlay.
What does Running on the CANopen manager actually tell you?
Running covers one hop only: it says the manager task started inside the CODESYS runtime. The Linux layer underneath, where this fault sits, can be fully down while the status stays green. Trace one request down the stack and test each hop on its own:
| Hop | Layer | What proves it |
|---|---|---|
| 1 | CANopen manager in the CODESYS runtime | PLC logger messages |
| 2 | SocketCAN interface in Linux | ip link shows the interface up at the bus rate |
| 3 | DCAN1 controller and its pinmux | pinmux-pins shows pinmux_dcan1_pins on pins 96 and 97 |
| 4 | Header pins to the transceiver | Pin crossing on P9-24 and P9-26, 3.3 V logic, common ground |
| 5 | Bus wiring, termination, nodes | Scope with CAN decode at 500 kbps |
Hop 5 was ruled out first: the scope decoded the transducer at 500 kbps with the known node ID. That leaves hops 1 to 4, checked from the bottom up in the rest of this page. Once frames flow again, node-level behaviour such as heartbeats and guarding is a manager question, covered in CODESYS CANopen node status and guard timer.
How do you check which function owns pins 96 and 97?
Read the live pin state with one command, cat /sys/kernel/debug/pinctrl/44e10800.pinmux/pinmux-pins. A working DCAN1 setup shows pin 96 (44e10980.0) and pin 97 (44e10984.0) claimed by 481d0000.can with function pinmux_dcan1_pins on both lines. The working output looks like this:
pin 96 (44e10980.0): 481d0000.can (GPIO UNCLAIMED) function pinmux_dcan1_pins group pinmux_dcan1_pinspin 97 (44e10984.0): 481d0000.can (GPIO UNCLAIMED) function pinmux_dcan1_pins group pinmux_dcan1_pins
Interpretation:
- Both pins show
pinmux_dcan1_pins: the overlay applied and DCAN1 owns the pins. Go test SocketCAN. - Either pin shows UART1 or no CAN function: the mux stayed put and the controller drives nothing onto the header. Fix the overlay method and the kernel below.
While you are at the header: DCAN1 TX lands on P9-24, the pin labelled UART1 RX, and DCAN1 RX lands on P9-26, the pin labelled UART1 TX. The crossing is how mode 2 assigns the pair, so wiring by the silkscreen label swaps TX and RX. Both orientations were tried during this fault with no change, which is another pointer at the mux. Keep the transceiver on 3.3 V logic, termination at both ends of the bus, and one common ground.
Does cape_enable=bone_capemgr.enable_partno still load overlays on Debian Stretch?
No. Debian 9.4 IoT loads overlays in U-Boot, the bone_capemgr slots file behind cape_enable is gone, and that line loads nothing. One uboot_overlay_addr line in /boot/uEnv.txt replaces it. U-Boot has applied device tree overlays since v2017.01, so the boot loader, not a runtime slots file, puts the CAN cape into the tree.
The line that works:
uboot_overlay_addr4=/lib/firmware/BB-CAN1-00A0.dtbo
Add it to /boot/uEnv.txt and reboot. If another overlay already occupies addr4, take the next free uboot_overlay_addr number. The cape_enable line loads nothing on this image, which the configuration table below shows directly.
Why does the real-time kernel kill the CAN overlay?
The BoneRT kernel build leaves DCAN1 unclaimed. With it installed, pins 96 and 97 stay in UART1 mode regardless of the overlay line. The stock kernel with the same line brings CAN up and boots in about 14 seconds. Three configurations were run on this image, across two boards:
| Configuration | Result |
|---|---|
Fresh image, BoneRT kernel from ./update_kernel.sh --bone-rt-kernel --stable, cape_enable line |
No CAN; the slots mechanism is gone on this image |
BoneRT kernel plus the uboot_overlay_addr4 line |
Pins 96 and 97 never leave UART1 |
Stock kernel plus the uboot_overlay_addr4 line only |
CAN works, boot stays at about 14 seconds |
The same RT install stretched boot from about 14 seconds to about 2 minutes. systemd-analyze blame and systemd-analyze critical-chain name the blocking units, and disabling the web server service recovered none of the time; the stock kernel boots fast again. Why that kernel build ignores the overlay is not documented in any citable source, so treat the pin state as the gate, not the kernel name.
Recommendation: run the stock kernel with uboot_overlay_addr4=/lib/firmware/BB-CAN1-00A0.dtbo in /boot/uEnv.txt for CAN work on Debian 9.4 IoT. Return to the real-time kernel only after pinmux-pins shows pinmux_dcan1_pins on pins 96 and 97 on a boot of that kernel.
How do you test SocketCAN before touching CODESYS again?
Bring the interface up at the bus rate with sudo ip link set <iface> up type can bitrate 500000, then watch candump <iface>: frames from a powered node mean Linux owns the controller and the pins. The CODESYS runtime drives CAN through SocketCAN, so a working Linux interface is the prerequisite. Work it in this order:
- Run
ip linkand note the interface name. The name depends on which controllers the kernel enabled, and the first one can appear ascan0even though you configured DCAN1. - Bring it up:
sudo ip link set <iface> up type can bitrate 500000. The number matches the 500 kbps the scope decoded. - Run
candump <iface>with the transducer powered. Frames should scroll, and the scope decode shows the same traffic. - With the CODESYS runtime stopped, send one frame with
cansend <iface> <id>#<data>and watch it on the scope. A frame that never appears on the wire means the mux or transceiver path is still broken.
Then align the runtime side. The runtime keeps its interface name and bit rate in rts_set_baud.sh; open it and set both to the interface you just tested, and read the PLC logger for CAN initialisation messages before you restart the manager. Transfer-level faults after that, such as a block transfer that stalls, live one layer up in CANopen SDO block transfer support and troubleshooting.
What does a complete fix look like in one example?
From a fresh Debian 9.4 IoT image on a BeagleBone Black Rev C: keep the stock kernel, add uboot_overlay_addr4=/lib/firmware/BB-CAN1-00A0.dtbo to /boot/uEnv.txt, reboot, and check that pins 96 and 97 report pinmux_dcan1_pins before CODESYS starts. The full sequence, with the numbers carried through:
- Flash Debian 9.4 IoT, the 2018-06-17 image, and leave the stock kernel in place. Skip
update_kernel.sh. - Add the one line to
/boot/uEnv.txtand reboot. cat /sys/kernel/debug/pinctrl/44e10800.pinmux/pinmux-pinsnow shows pins 96 and 97 owned by 481d0000.can underpinmux_dcan1_pins.ip linklistscan0. Bring it up at 500000, which is the 500 kbps the scope decoded on the bench.candump can0shows the transducer frames, and the scope shows the same traffic, so hop 2 and hop 5 agree.- Edit
rts_set_baud.shtocan0at the same 500 kbps, start the CODESYS V3.5 SP12 Patch 4 runtime, and read a clean PLC logger. - The CANopen manager goes to Running with the EDS-loaded transducer answering, and the device scan no longer freezes.
The rate check is the arithmetic that catches this class of fault: 500 kbps on the scope, 500000 in ip link, 500 kbps in rts_set_baud.sh, one value in three places. Boot time lands back at about 14 seconds. Once the pressure value flows, where to show it, on the controller screen or a separate line display, is a layout question of its own: see live factory data display: signage or dashboard.
Questions
Can you run candump while the CODESYS runtime is running?
Yes. A read-only candump attaches its own raw socket and receives the same frames the runtime sees, so watching traffic with the manager active is safe. Do not run cansend while the manager is running: injected frames disturb the node state machines and can push nodes into error states that look like a bus fault.
Does CAN Network 1 in the CODESYS device tree always mean the Linux interface can1?
No, the mapping follows what the kernel enabled, not the number in the tree. The first enabled controller can appear as can0 even when you configured DCAN1. Read the PLC logger at startup, match the network number to the interface ip link shows, and point rts_set_baud.sh at that same name and rate.
Does a smart cape with I2C recognition need different setup from a bare transceiver?
No. The overlay does the same job either way: it claims pins 96 and 97 for DCAN1. Recognition changes what U-Boot may load on its own, so with a bare transceiver you always write the uboot_overlay_addr line yourself. Once pinmux-pins shows pinmux_dcan1_pins, the two setups are identical from the wire inward.
Why does the CODESYS network scan miss the BeagleBone but find other boards?
Treat that as a discovery nuisance, not a CAN fault. Discovery broadcasts are unreliable on this image, and entering the board IP address by hand connects the development system to the runtime. The bus lockup is unrelated to discovery and sits in the pinmux layer either way.
Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.