2 unstable releases

0.2.0 Jan 17, 2024
0.1.0 Jan 17, 2024

#223 in Embedded development

30 downloads per month

MIT license

52KB
1.5K SLoC

canopeners

Incomplete, but easy to use implementation of the CANOpen standard in Rust.

Examples

All examples are blocking. Set timeouts with conn.set_{read_write}_timeout.

Send a single message:

Conn::new("vcan0").map(|conn| {
    let nmt = Nmt::new(canopeners::NmtFunction::StartRemoteNode, 10);
    conn.send(&Message::Nmt(nmt)).unwrap();
})

Write bytes to object dictionary on a remote node:

Conn::new("vcan0").map(|mut conn| {
    conn.sdo_write(
    /* remote node id */ 0x10, 
    /* index */ 0x1000,
    /* sub index */ 1,
    /* data, can be any length */ &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    .unwrap();
})

Read bytes from object dictionary on a remote node:

Conn::new("vcan0").map(|mut conn| {
    let res = conn.sdo_read(
    /* remote node id */ 0x10, 
    /* index */ 0x1000,
    /* sub index */ 1)
    .unwrap();
    dbg!(res);
})

Building

nix develop
cargo build

if you'd rather use your system cargo, just cargo build will work too

Testing

setup_vcan.sh sets up a virtual CAN bus. tests/ rely on this

TODO

  • enum for all message types (can't use impl trait as function return type)
  • send/receive SDO
  • stateless example over vcan
  • segmented SDO
  • porcelain wrappers for easy send/receive over SDO
  • finish replacing manual bit manipulation with binrw
  • package.nix
  • convert simple.rs example into tests
  • fix cargo warns
  • fix clippy lints
  • add send_acked for all message types
  • Node impl sending TPDOs based on SYNC msgs
  • extended ID support

Dependencies

~3.5MB
~72K SLoC