3

I have a similar problem with this. How to program a simple CANopen layer . I read the answers but I have to program a CANopen layer on my own I cannot get a commercial one. So are there any basics of writing a CANopen stack (or layer I'm not certain about the difference)? I don't know even where to start..

If it's required here's some information :

My master device is a beagle bone black with QNX. QNX has a generic CAN library I think but not specific to CANopen. And my slave is a militarized brushless motor controller. I'm writing in C++. I have a documentation about the general requirements of my system. There are 2 RPDOs and 4 TPDOs, transmission is synchronous, there is no stopped mode( so no heart-beat and node guarding) and all message informations are stated (size, format, related node IDs etc.)

İpek
  • 162
  • 1
  • 11
  • 2
    I am pretty sure this question will be regarded as "too broad" or "off-topic". The simple answer is you get the protocol specification documents and you implement it - not much more to say. Its not a programming question so much as a system engineering question. https://www.can-cia.org/standardization/specifications/ – Clifford Sep 07 '17 at 21:02

3 Answers3

22

There are actually at least 4 open source projects that implement CANopen:

  • CanFestival is the oldest and might be the most mature solution. License: LGPLv2.
  • CANopenNode is aimed at micro-controllers. License: GPLv2.
  • Lely CANopen is a library for implementing CANopen masters and slaves. License: Apache version 2.
  • openCANopen is a master that runs on Linux. License: ISC. Note: I am the author of this project.

I would have posted links, but apparently I don't have enough "reputation".

openCANopen also includes some utilities such as a daemon for forwarding traffic over TCP and a program that interprets and dumps CANopen traffic to standard output.

Lely CANopen is actually of pretty decent code quality and I might have used it if it'd been available when I started writing my own implementation. However, I have not tried using it, so I can't really say which implementation is "better". I can only say that they are different and one or the other may suit your needs better.

Now, I doubt that any of those implementations will work straight out of the box on QNX. They will either have to be adapted or you can copy individual parts of the code into your own implementations. At least that should save you some time.

any1
  • 361
  • 1
  • 5
  • CANOpenNode is also available for any generic linux that has SocketCan. It's linux implementation is called CANopenSockets. It's actually very easy to cross-compile and make it work for your SBC. I wonder how it compares though to the various closed source CANOpen libraries: Emtas-CANopen, Port CANopen, PEAK, etc. – Geoffrey VL Sep 05 '19 at 06:29
  • 1
    Embedded office now also have an open source implementation https://github.com/embedded-office/canopen-stack, using Apache 2.0 license – Simon Byholm Aug 13 '20 at 10:16
  • @SimonByholm Do you know if I can find implemented drivers for the embedded office stack anywhere? – Max Oct 23 '20 at 09:44
  • @Max Sorry for the late answer, but that's probably where they make the money, at Embedded Office. They will write the driver for you as a consulting service. What you can do is take the driver from some other free stack and change the API so it fits. – Simon Byholm Apr 28 '21 at 07:19
  • 1
    Note that CANopenNode is Apache 2.0 now, https://github.com/CANopenNode/CANopenNode/blob/master/LICENSE – Chris Morgan Aug 10 '21 at 02:06
12

The quick and dirty work-around is to only implement the bare minimum (just don't market it as CANopen or claim CANopen compliance):

  • Support for those specific RPDOs/TPDOs that the other node will send/expect to receive. Use fixed COBID (CAN identifiers). Forget about PDO mapping and PDO configuration, use fixed settings.
  • Implement a NMT bootup message.
  • Implement NMT state transitions between pre-operational and operational (your node needs to respond to these from the NMT master).
  • Implement some means to set the node id. Easiest might be to hard code it as a program constant.

If you are lucky, this is all that is needed. If you are unlucky, there will be SDO commmunication, meaning you will have to implement the SDO protcol and also the whole Object Dictionary. Otherwise, the above is fairly straight-forward and not that much work.

In case you need the Object Dictionary, then there might be no other way around getting a full-blown protocol stack. You'll also need to apply for a vendor id from CAN-in-Automation, but it's a one-time fee (no royalties).

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 1
    I also agree that such a minimalistic "non-CANopen-compliant" approach can be sometimes the most appropriate solution. – Oliver Heggelbacher May 04 '18 at 09:07
  • I would even argue that "use SDO commmunication only" is the easier approach. For a standard CANopen servo drive, all you require is writing and reading integer values via CANopen ("expedited SDO transfer"). Each read and write is one CAN Bus frame for the request to the drive, and evaluating one CAN Bus frame with the answer. – Oliver Heggelbacher May 04 '18 at 09:15
  • 2
    @OliverHeggelbacher SDO communication should only happen in pre-operational mode though. A control system which allows its outputs to be affected while in pre-operational mode is of questionable design. Also, SDO communication would also require slightly more overhead data traffic, expedited or not. Praxis for designing control systems is not to work on request-to-send basis, nor to send upon data change (asynchronous PDO/DS401 default behavior), but rather with "event timer PDO", sending out their data in operational mode each _n_ milliseconds. – Lundin May 04 '18 at 09:39
  • Of course all of this depends on the system, but a control system like a servo drive would likely be a high integrity system and then I would expect no less but "event-timer" behavior, as that is the only acceptable method in such applications. – Lundin May 04 '18 at 09:40
  • Hello Lundin, you make very valid points about the correct design of a CANopen compliant system for cyclic / time-critical process data exchange. I merely suggest to really look at the actual application: The main controller is maybe not a PLC but a Windows PC custom software that talks to a single drive for a non-dynamic, maybe even semi-manual positioning purpose. Then SDO, staying in "Pre-Operational" and not dealing with NMT and PDO is IMHO a valid solution which is easy to implement, test and debug. – Oliver Heggelbacher May 28 '18 at 09:34
1

I'm from Embedded Office and want to add my penny to your search, even if it's late. First I want to mention, the reason why we didn't put drivers into the canopen-stack repository is the complexity of embedded software development on multiple targets with multiple compilers and my goal to provide running software wherever possible. With just a library is hard to identify problems during usage.

The good news, I setup an environment to get the different targets and compilers managable by a single maintainer (me). So the canopen-stack is developped with LLVM on host machines, and a first demo is provided for STM32F7xx microcontrollers. More is coming, so stay tuned :-)