Coder Social home page Coder Social logo

canopennode / canopennode Goto Github PK

View Code? Open in Web Editor NEW
1.3K 1.3K 621.0 2.52 MB

CANopen protocol stack

Home Page: https://canopennode.github.io/CANopenNode/index.html

License: Apache License 2.0

C 99.90% Makefile 0.10%
canopen canopennode embedded iot stack

canopennode's Introduction

CANopenNode

CANopenNode is free and open source CANopen protocol stack.

CANopen is the internationally standardized (EN 50325-4) (CiA301) higher-layer protocol for embedded control system built on top of CAN. For more information on CANopen see http://www.can-cia.org/

CANopenNode is written in ANSI C in object-oriented way. It runs on different microcontrollers, as standalone application or with RTOS.

Variables (communication, device, custom) are collected in CANopen Object Dictionary and are accessible from both: C code and from CANopen network.

CANopenNode homepage is https://github.com/CANopenNode/CANopenNode

This is version 4 of CANopenNode with new Object Dictionary implementation. For older versions git checkout branches v1.3-master or v2.0-master.

Characteristics

CANopen

  • Object Dictionary offers clear and flexible organisation of any variables. Variables can be accessed directly or via read/write functions.
  • NMT slave to start, stop, reset device. Simple NMT master.
  • Heartbeat producer/consumer error control for monitoring of CANopen devices. An older alternative, 'node guarding', is also available.
  • PDO for broadcasting process data with high priority and no protocol overhead. Variables from Object Dictionary can be dynamically mapped to the TPDO, which is then transmitted according to communication rules and received as RPDO by another device.
  • SDO server enables expedited, segmented and block transfer access to all Object Dictionary variables inside CANopen device.
  • SDO client can access any Object Dictionary variable on any CANopen device inside the network.
  • Emergency message producer/consumer.
  • Sync producer/consumer enables network synchronized transmission of the PDO objects, etc.
  • Time-stamp producer/consumer enables date and time synchronization in millisecond resolution.
  • LSS CANopen node-id and bitrate setup, master and slave, LSS fastscan.
  • CANopen gateway, CiA309-3 Ascii command interface for NMT master, LSS master and SDO client.
  • CANopen Safety, EN 50325-5, CiA304, "PDO like" communication in safety-relevant networks
  • CANopen Conformance Test Tool passed.

Other

Related projects

  • CANopenNode (this project): CANopen protocol stack, base for CANopen device. It contains no device specific code (drivers), which must be added separately for each target system. An example shows the basic principles, compiles on any system, but does not connect to any CAN hardware.
  • CANopenDemo: Demo device with CANopenNode and different target systems, tutorial and testing tools.
  • CANopenNode.github.io: Html documentation, compiled by doxygen, for CANopenDemo, CANopenNode and other devices, available also online: https://canopennode.github.io
  • CANopenEditor: Object Dictionary editor, external GUI tool for editing CANopen Object Dictionary for custom device. It generates C source code, electronic data sheet and documentation for the device. It is a fork from libedssharp.
  • CANopenLinux: CANopenNode on Linux devices. It can be a basic CANopen device or more advanced with commander functionalities.
  • CANopenSTM32: CANopenNode on STM32 microcontrollers.
  • Analog Devices Inc.: CANopenNode on Analog Devices Inc. MAX32xx microcontrollers.
  • CANopenPIC: CANopenNode on PIC microcontrollers from Microchip. Works with 16-bit and 32 bit devices. Includes example for Arduino style Max32 board.
  • doc/deviceSupport.md: List of other implementations of CANopenNode on different devices.

Documentation, support and contributions

All code is documented in the source header files. Some additional documents are in doc directory.

To generate complete html documentation, run doxygen in the project base directory: sudo apt install doxygen graphviz pdf2svg; doxygen > /dev/null

Complete generated documentation is also available online: https://canopennode.github.io

Tutorial, demo device and tests are available in CANopenDemo repository.

Report issues on https://github.com/CANopenNode/CANopenNode/issues

Older discussion group is on Sourceforge: http://sourceforge.net/p/canopennode/discussion/387151/

Contributions are welcome. Best way to contribute your code is to fork a project, modify it and then send a pull request. Please follow the Recommended C style and coding rules, like indentation of 4 spaces, etc. There is also a codingStyle file with example.

CANopenNode flowchart

Flowchart of a typical CANopenNode implementation:

                            -----------------------
                           |     Program start     |
                            -----------------------
                                       |
                            -----------------------
                           |     CANopen init      |
                            -----------------------
                                       |
                            -----------------------
                           |     Start threads     |
                            -----------------------
                                 |     |     |
             --------------------      |      --------------------
            |                          |                          |
 ----------------------    ------------------------    -----------------------
| CAN receive thread   |  | Timer interval thread  |  | Mainline thread       |
|                      |  |                        |  |                       |
| - Fast response.     |  | - Realtime thread with |  | - Processing of time  |
| - Detect CAN ID.     |  |   constant interval,   |  |   consuming tasks     |
| - Partially process  |  |   typically 1ms.       |  |   in CANopen objects: |
|   messages and copy  |  | - Network synchronized |  |    - SDO server,      |
|   data to target     |  | - Copy inputs (RPDOs,  |  |    - Emergency,       |
|   CANopen objects.   |  |   HW) to Object Dict.  |  |    - Network state,   |
|                      |  | - May call application |  |    - Heartbeat.       |
|                      |  |   for some processing. |  |    - LSS slave        |
|                      |  | - Copy variables from  |  | - Gateway (optional): |
|                      |  |   Object Dictionary to |  |    - NMT master       |
|                      |  |   outputs (TPDOs, HW). |  |    - SDO client       |
|                      |  |                        |  |    - LSS master       |
|                      |  |                        |  | - May cyclically call |
|                      |  |                        |  |   application code.   |
 ----------------------    ------------------------    -----------------------

All code of the CANopenNode is non-blocking. Code in source files is collected into objects. Parts of the code can be enabled/disabled, so only files and parts of code can be used, which are required for the project. See stack configuration in 301/CO_config.h file.

For most efficiency code can run in different thread as seen in above flowchart. This is suitable for microcontrollers. It is also possible to run everything from single thread, as available on Linux devices. Code includes mechanisms, which triggers processing of OD objects when necessary.

In CANopen initialization section all CANopen objects are initialized. In run time CANopen objects are processed cyclically.

Files CANopen.h and CANopen.c is a joint of all CANopen objects. It may seems complex, but offers some flexibility and is suitable for most common configurations of the CANopen objects. CANopen objects can be defined in global space or can be dynamically allocated. Object dictionary can be used default (OD.h/.c files), but configuration with multiple object dictionaries is also possible by using the #CO_config_t structure. CANopen.h and CANopen.c files can also be only a reference for more customized implementation of CANopenNode based device.

Object Dictionary is a collection of all network accessible variables and offers most flexible usage. OD variables can be initialized by object dictionary or application can specify own read/write access functions for specific OD variables. Groups of OD variables are also able to be stored to non-volatile memory, either on command or automatically.

File structure

  • 301/ - CANopen application layer and communication profile.
    • CO_config.h - Configuration macros for CANopenNode.
    • CO_driver.h - Interface between CAN hardware and CANopenNode.
    • CO_ODinterface.h/.c - CANopen Object Dictionary interface.
    • CO_Emergency.h/.c - CANopen Emergency protocol.
    • CO_HBconsumer.h/.c - CANopen Heartbeat consumer protocol.
    • CO_NMT_Heartbeat.h/.c - CANopen Network management and Heartbeat producer protocol.
    • CO_PDO.h/.c - CANopen Process Data Object protocol.
    • CO_SDOclient.h/.c - CANopen Service Data Object - client protocol (master functionality).
    • CO_SDOserver.h/.c - CANopen Service Data Object - server protocol.
    • CO_SYNC.h/.c - CANopen Synchronisation protocol (producer and consumer).
    • CO_TIME.h/.c - CANopen Time-stamp protocol.
    • CO_fifo.h/.c - Fifo buffer for SDO and gateway data transfer.
    • crc16-ccitt.h/.c - Calculation of CRC 16 CCITT polynomial.
  • 303/ - CANopen Recommendation
    • CO_LEDs.h/.c - CANopen LED Indicators
  • 304/ - CANopen Safety (Implemented only in v1.3, not updated for the latest version).
    • CO_SRDO.h/.c - CANopen Safety-relevant Data Object protocol.
    • CO_GFC.h/.c - CANopen Global Failsafe Command (producer and consumer).
  • 305/ - CANopen layer setting services (LSS) and protocols.
    • CO_LSS.h - CANopen Layer Setting Services protocol (common).
    • CO_LSSmaster.h/.c - CANopen Layer Setting Service - master protocol.
    • CO_LSSslave.h/.c - CANopen Layer Setting Service - slave protocol.
  • 309/ - CANopen access from other networks.
    • CO_gateway_ascii.h/.c - Ascii mapping: NMT master, LSS master, SDO client.
  • storage/
    • CO_storage.h/.c - CANopen data storage base object.
    • CO_storageEeprom.h/.c - CANopen data storage object for storing data into block device (eeprom).
    • CO_eeprom.h - Eeprom interface for use with CO_storageEeprom, functions are target system specific.
  • extra/
    • CO_trace.h/.c - CANopen trace object for recording variables over time.
  • example/ - Directory with basic example, should compile on any system.
    • CO_driver_target.h - Example hardware definitions for CANopenNode.
    • CO_driver_blank.c - Example blank interface for CANopenNode.
    • main_blank.c - Mainline and other threads - example template.
    • CO_storageBlank.h/.c - Example blank demonstration for data storage to non-volatile memory.
    • Makefile - Makefile for example.
    • DS301_profile.xpd - CANopen device description file for DS301. It includes also CANopenNode specific properties. This file is also available in Profiles in Object dictionary editor.
    • DS301_profile.eds, DS301_profile.md - Standard CANopen EDS file and markdown documentation file, automatically generated from DS301_profile.xpd.
    • OD.h/.c - CANopen Object dictionary source files, automatically generated from DS301_profile.xpd.
  • doc/ - Directory with documentation
    • CHANGELOG.md - Change Log file.
    • deviceSupport.md - Information about supported devices.
    • objectDictionary.md - Description of CANopen object dictionary interface.
    • CANopenNode.png - Little icon.
    • html - Directory with documentation - must be generated by Doxygen.
  • CANopen.h/.c - Initialization and processing of CANopen objects, suitable for common configurations.
  • codingStyle - Example of the coding style.
  • Doxyfile - Configuration file for the documentation generator doxygen.
  • LICENSE - License.
  • README.md - This file.

Object dictionary editor

Object Dictionary is one of the most essential parts of CANopen.

To customize the Object Dictionary it is necessary to use external application: CANopenEditor. Latest pre-compiled binaries are also available. Just extract the zip file and run the EDSEditor.exe. In Linux it runs with mono, which is available by default on Ubuntu. Just set file permissions to "executable" and then execute the program.

In program, in preferences, set exporter to "CANopenNode_V4". Then start new project or open the existing project file.

Many project file types are supported, EDS, XDD v1.0, XDD v1.1, old custom XML format. Generated project file can then be saved in XDD v1.1 file format (xmlns="http://www.canopen.org/xml/1.1"). Project file can also be exported to other formats, it can be used to generate documentation and CANopenNode source files for Object Dictionary.

If new project was started, then DS301_profile.xpd may be inserted. If existing (old) project is edited, then existing Communication Specific Parameters may be deleted and then new DS301_profile.xpd may be inserted. Alternative is editing existing communication parameters with observation to Object Dictionary Requirements By CANopenNode in objectDictionary.md.

To clone, add or delete, select object(s) and use right click. Some knowledge of CANopen is required to correctly set-up the custom Object Dictionary. Separate objects can also be inserted from another project.

CANopenNode includes some custom properties inside standard project file. See objectDictionary.md for more information.

Device support

CANopenNode can run on many different devices. Each device (or microcontroller) must have own interface to CANopenNode. CANopenNode can run with or without operating system.

It is not practical to have all device interfaces in a single project. Interfaces to other microcontrollers are in separate projects. See deviceSupport.md for list of known device interfaces.

Some details

RTR

RTR (remote transmission request) is a feature of CAN bus. Usage of RTR is not recommended for CANopen. RTR PDO is not implemented in CANopenNode.

Error control

When node is started (in NMT operational state), it is allowed to send or receive Process Data Objects (PDO). If Error Register (object 0x1001) is set, then NMT operational state may not be allowed.

Power saving

All CANopen objects calculates next timer info for OS. Calculation is based on various timers which expire in known time. Can be used to put microcontroller into sleep and wake at the calculated time.

Change Log

See CHANGELOG.md

License

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

canopennode's People

Contributors

ankit-eic avatar blazej1994 avatar burghart avatar canopennode avatar cfr-mir avatar dergentk avatar freddiechopin avatar geoffrey-vl avatar gotocoffee1 avatar heliochronix avatar henrikbrixandersen avatar inviz avatar iurly avatar joao404 avatar juprgn avatar lukegluke avatar majerle avatar maldus512 avatar martinwag avatar mlout avatar nli-brianlinari avatar norcio avatar odesenfans avatar oto313 avatar paoloteti avatar sicrisembay avatar sl-alex avatar ttmut avatar wilkinsw avatar willykaze avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

canopennode's Issues

GPL License Questions

My working environment is Linux.
I tested CANopen using CANopenSocket's canopend. It worked well.
I created shared memory in canopend and tried to exchange PDO data with other programs.

I know that CANopenNode is a GPL linking exception.
However, CANopenSocket is a generic GPL v2.

I tested with canopend and tried to use shared memory, but gave up because it was GPL v2.
So I tried to use the GPL linking exception CANopenNode/CANopenNode/example/main.c.
After analyzing the source, I found that the CANopenNode/CANopenSocket/canopend/src/main.c and CANopenNode stacks were very similar.
Both CANopenNode/CANopenNode/example/main.c and CANopenNode/CANopenSocket/canopend/src/main.c both use the stack of CANopenNode.

Both are thought of as a kind of daemon using CANopenNode.
This part confuses me.

  1. CANopenNode is a GPL linking exception, and canopend is GPL v2 intentionally?
  2. Can I refer to canopend's source when modifying CANopenNode/CANopenNode/example/main.c?

I am a newbie in connection with the GPL license.

I tried to find the mailing list but could not find it.
Is it a question to ask here?

I'm sorry I do not have enough English.

Pic18

Are Microchip PIC 18's supported?

GPL2 license

I apologize if I posted this question at wrong place. I tried to find your email address but not succeeded. So posted a question here.

I want to use your code in binary form in my commercial product. Can I use it? I have read the terms of GPL2 but it is confusing so I decided to ask you directly.

Adding LSS functionality

As mentioned here (https://sourceforge.net/p/canopennode/discussion/387151/thread/397f3912/) I'm in the process of implementing LSS.
I've pushed a first version to my local repo in lss branch (https://github.com/martinwag/CANopenNode/tree/add-lss). Feel free to have a look, but be aware that this is still experimental. If you find errors or have other hints, please let me know :-)

Current features

  • LSS slave

Current limitations:

  • needs #define CO_NO_LSS_SERVER 1 in CO_OD.h. This will need a change in the OD editor.
  • no Fastscan support yet
  • bitrate setting API untested. I've implemented this for the sake of completeness, I don't need it in my application.
  • #46 (driver stuff)
  • changed some of the other stack files, tried my best to remain compatible with standard non LSS CANopenNode
  • there is a bit of a mess about server/slave and master/client. But this is a mess in the other parts of the stack too :-(

Simultaneous SDO Transactions

I would like to know if it is possible with this stack to to multiple simultaneous SDO transactions.

Like reading from two different nodes at once. As I understand I have to call CO_SDOclient_setup every time my target changes before using CO_SDOclientDownloadInitiate or CO_SDOclientUploadInitiate. Is it somehow possible (like creating two instances of CO_SDOclient_t) to do to simultaneous transactions?

Getting Started

Hi Folks!

I am just about to getting started using this lib. I had a good look at the lib and have a few questions before I start.

  1. If I understand correctly, this lib provides the CANopen machinery and provides hooks where I can add in my own drivers. How to do this I can find in the drvTemplate. Correct?

  2. I want to use the lib on an STM32F072. There is two drivers for STM32's. Can I simply use the generic one or am I better off writing my own?

  3. To autogenerate the Object Database, a "Web Application" is needed. I figured that I can only use it in IE (ohwow.). But even in IE I get some errors and are unable to generate a project. How do I create a new project?

  4. The project is completely unmaintained. But there are a lot of pull requests and apparently interested people. Why not just create a fork of the project and have it maintained by some active people and not just one person? I would really love to use this lib and also contribute but with it largely unmaintained it's kind of bad ...

Thanks a lot for any answers & best regards,
Yatekii

CO_SDOclient_setup use

I need to act as SDO master for multiple slave nodes. For example, I am node ID 0x3. I need to read (client upload) from node 0x8 and also from node 0x9.

Initially I call CO_SDOclient_setup() for each node ID that I will be reading from. Then I call CO_CANsetNormalMode().

From what I can tell, every time change which node I am reading from, I need to call CO_SDOclient_setup() again. However CO_SDOclient_setup calls CO_CANrxBufferInit() which is only supposed to be called in the communications reset section. Hence switching from reading node 0x08 to 0x09 (for example) calls CO_CANrxBufferInit() after I have already exited the communications reset section, and the whole thing crashes.

Am I using this properly? What is the correct way to select which node ID I wish to talk to?

If I only talk to one node, everything works fine.

Expedited SDO download fails w/o size indication

While using a PLC from Frenzel+Berg, I noticed that the stack always assumes a data length of 4 bytes when a SDO download initiate message is received which has the size indication bit not set.
(excerpt from CO_SDO.c:806)

/* Expedited transfer */
        if((SDO->CANrxData[0] & 0x02U) != 0U){
            /* is size indicated? Get message length */
            if((SDO->CANrxData[0] & 0x01U) != 0U){
                len = 4U - ((SDO->CANrxData[0] >> 2U) & 0x03U);
            }
            else{
                len = 4U;
            }

This results in an abort message, if the triggered data type is not exactly 32 bytes long!
Is this really the desired behaviour?

Changing the else-case to

            /* get message length from OD */
            else{
                len = SDO->ODF_arg.dataLength;
            }

makes it work for me. This assumes the sender really knows what he is doing, the CO_SDO_writeOD() function will take as many bytes as needed*. Unfortunately the CIA-301 document does not say anything about this case, other that it exists.

Regards,
Kai

[* out of the 4 possible data bytes]

CO_init should take CANbaseAddress as void *

Now CO_init looks like this:

CO_ReturnError_t CO_init(
        int32_t                 CANbaseAddress,
        uint8_t                 nodeId,
        uint16_t                bitRate);

However, CANbaseAddress usually is an address of some kind of structure, for example, in stm32 it's a pointer to CAN_TypeDef.
So casting it to and from int32_t is:

  • ugly, especially in C++
  • may be undefined behaviour if size of pointer is bigger than int32_t

Since CANbaseAddress is used only for forwarding to CO_driver and not for it's numerical value, correct way of passing it will be as void *.

Clarification on GPLv2 with Classpath Exception vs. LGPL

I am interested in using this library with a STM32F4XX microcontroller. The project I am planning on using it with is a commercial project, and I would not be able to apply the GPL license to the commercial portion of the code.

I am trying to ascertain the correct approach to cleanly separating the commercial client code from the CANopenNode library code. Is the exemption applied in a similar manner to that of the LGPL? In other words, if I design my client code so that it only uses this library via linking, will that be allowed? If so, are both static and dynamic linking allowed?

Of course the terms of the GPL will be maintained otherwise, and this library's source, along with any modification made in order to get it working on the microcontroller (driver development, etc.) will be made available to anyone using the product being developed. It is also my intention to provide any updates to this code base back upstream via a pull request, presuming you are interested in such modifications.

Is this the correct approach?

reading DOMAIN via SDO > SDOBufferSize fails

I may be not understanding the way this is suppose to work but if i have a domain variable and i want to transfer a bigger buffer than CO_SDO_BUFFER_SIZE then it fails with an SDO abort of CO_SDO_AB_DEVICE_INCOMPAT

I have defined a OD access function via CO_OD_configure() and then i am doing the following in my function :-

if(ODF_arg->reading)
{

            ODF_arg->dataLengthTotal = com1_buffer.count;            
            ODF_arg->dataLength = com1_buffer.count;
            ODF_arg->data = com1_buffer.buffer;
}

So i have updated the data pointer to point at my buffer and set the sizes

if i set the ODF_arg->dataLength > CO_SDO_BUFFER_SIZE then the SDO transfer fails. If i remove the check on line 641 of CO_SDO.c which says :-

/* dataLength (upadted by pODFunc) must be inside limits */
        if((SDO->ODF_arg.dataLength == 0U) || (SDO->ODF_arg.dataLength > SDOBufferSize)){
            return CO_SDO_AB_DEVICE_INCOMPAT;     /* general internal incompatibility in the device */
        }

then it works perfectly and i get all bytes transferred by SDO (in my case a segmented sdo transfer)

Reading the comments on CO_SDO.h around line 323 it states
* Size must be at least equal to size of largest variable in @ref CO_SDO_objectDictionary.
* If data type is domain, data length is not limited to SDO buffer size.

So that comment would suggest that the above check should not be present for DOMAIN type variables?

Have i made a mistake with my implementation or is this a bug?

Thanks!

ODL_errorStatusBits_stringLength makes custom object mandatory

Not quite sure this an issue, but the ODL_errorStatusBits_stringLength must be at least 10, that makes the custom object 0x2100 mandatory. And this is not according DS301.

/* Verify features from CO_OD *************************************************/
    /* generate error, if features are not correctly configured for this project */
    #if        CO_NO_NMT_MASTER                           >  1     \
            || CO_NO_SYNC                                 != 1     \
            || CO_NO_EMERGENCY                            != 1     \
            || CO_NO_SDO_SERVER                           == 0     \
            || (CO_NO_SDO_CLIENT != 0 && CO_NO_SDO_CLIENT != 1)    \
            || (CO_NO_RPDO < 1 || CO_NO_RPDO > 0x200)              \
            || (CO_NO_TPDO < 1 || CO_NO_TPDO > 0x200)              \
            || ODL_consumerHeartbeatTime_arrayLength      == 0     \
            **|| ODL_errorStatusBits_stringLength           < 10**
        #error Features from CO_OD.h file are not corectly configured for this project!
    #endif

CO_driver init message buffers are only partly initialized

In CO_CANmodule_init() function, rxArray[] is only partly initialized. When not all elements are initialized by the following CANopenNode init functions, undefined behaviour occurs upon message reception.
This causes a problem for me on implementing LSS. In normal operation all elements are initialized correctly. But with LSS, there is a case where only LSS is initialized and the rest of the stack is not (Startup without valid node ID).
I've solved this by defaulting all values of the array as followed:

  for(i=0U; i<rxSize; i++){
      rxArray[i].ident = 0U;
      rxArray[i].mask = 0xFFFFFFFF;
      rxArray[i].object = NULL;
      rxArray[i].pFunct = NULL;
  }

Mask must be set to not mask out any bits as otherwise software filter in
if(((rcvMsgIdent ^ buffer->ident) & buffer->mask) == 0U){
will always match when buffer is not set up by stack.

For me this works as expected, but I don't know if we can just apply that to all the other avaliable drivers. There shouldn't be a problem as those values currently contain "random" values, but who knows...

txArray[] is also only partially initialzied. However, I think this is not a problem because those entries are only used after initialization.

problem with heartbeat

when the master stop to send heartbeat to canopennode 'node'
the node go to pre-op-> this is ok
but the node was locked, impossible to return to operational state.
canopen node dosn't accept the nmt message

Variable-Length Strings

I'm trying to implement a few variable-length strings in the Object Dictionary (read-only, so SDO upload).
What's the recommended way of going about it?

@martinwag: what I'm trying to do is read (among other things) the software version just like you posted here, would you care to share how you did that? Did you implement some custom OD function or do you just patch CO_OD.c before compiling?

Thank you!

Can't write to subindex zero of register 0x1003 Pre-defined error field

It is my understanding that this should be possible, and doing it should reset the error counter.

I also found this piece of code that suggests this has been thought of at some point.

If I try to do this write, the function above never gets executed, instead CO_SDO_AB_READONLY error is thrown here

This happens even though OD entry for this register in initialised like this with attribute of 0x8E and never changes. (Note that CO_ODA_READABLE == 0x04)

What happens is that when the object for this registered is fetched from the OD the attribute member is populated with this function that makes sure that subindex zero is never written to.

struct sCO_OD_ROM CO_OD_ROM - const?

Hi,

I can't find this in the docs - is there a reason that I shouldn't declare the ROM OD entries struct as const? This basically gives the compiler the option to not place this stuff inside RAM.

In the current implementation, I can't find a difference between ROM and RAM, both are loaded to ram, both are lost at reset.

Added K20 driver

My company is writing ARM code for the Kinetis K20. This is the platform also used by PJRC's Teensyduino.

I've written a driver for the K20 and so far it seems to be working great. I've commited the driver to a local branch, if you want to give me push access I'll add it and create a pull request so you can look it over.

Disclaimer: I've commented the code so it's reasonably legible, but I haven't cleaned it up to ensure it meets all the coding style guidelines. I've tested SDO, HB, and HB consumer but not PDO.

Multiple(xed) PDOs

Hi,

I need for a single node to autonomously transmit several process data (i.e. more than 4 PDOs * 8 bytes/PDO).
In my understanding there's a limit for each node to only send 4 different PDOs, and CANOpen already defines multiplexed PDOs to address such a case (at the cost of extra bandwidth of course).
Is there any plan or idea to implement such a feature in CANopenNode?

Would there be any alternative (e.g. by using custom COB-IDs?) I wouldn't need to deploy a huge number of nodes so I might as well restrict the usage of NodeIDs to e.g. 8,16,24 etc... so that the node with ID 16 can use up all the COB-IDs that would normally be used by 8 different nodes (with ID between 16 and 23).
Any suggestion welcome...
Thank you!

libedsharp CO_NO_NMT_MASTER

Using the excellent libedsharp EDSeditor V0.5.2 or 6 beta I have one problem: I can not get either version to set CO_NO_NMT_MASTER to 1. I am using it with the .eds file that comes with CANopenSocket. Any suggestions?

GPL License Questions #2 (socketCAN driver has no linking exception)

Hi Janez,

currently, CANopenNode is marked in the Readme.md as using GPL with linking exception. This is true for all sources, except the socketCAN driver. Those are GPLv2.
I would like to use this driver (and fix some bugs/add features to it). However GPL means that I can't integrate it into my application, forcing me to build a completely new one.

Can we change that to the license that is used for the driver template?

Thanks!

stm32 and CO_init

So, today I tried to compile the sample code for the STM32. There are a lot of build errors so I will try to fix them and add a pull as soon as possible. But first I had a question concerning CO_init(...)
So in the latest Version of the stack this function uses some fixed prototype of

CO_ReturnError_t CO_init(
        int32_t                 CANbaseAddress,
        uint8_t                 nodeId,
        uint16_t                bitRate)
{

So the problem here is that an STM32 has some different type here. It would be better to use CAN_TypeDef *CANbaseAddress, for STM32. But thats not possible because CO_init isn´t a driver part function. So what was your idea here? I the driver template there is some hit... could be different for other microcontroller. But then you use a fix int32_t.

The only solution here is to use a mapping in the driver...

CAN0 => CANbaseAdress 0x1 => mapps to CAN_TypeDef CAN1 in the function.
CAN0 => CANbaseAdress 0x2 => mapps to CAN_TypeDef CAN1 in the function.

or use some preprocessor magic.

cheers
mathias

Where do I download the Object Dictionary Editor?

Hello.

I am using the Object Dictionary Editor to create Object data for use with CANopenNode.

However, I could not find the Object Dictionary Editor in a subproject at https://github.com/CANopenNode.

I was able to find the Object Dictionary Editor at https://sourceforge.net/projects/canopennode/files/canopennode/CANopenNode-3.10/.

My idea is that the repository has been moved from sourceforge to github.
Perhaps this Object Dictionary Editor is an old version.

When I check, CO_OD.c and CO_OD.h created by Object Dictionary Editor downloaded from sourceforge are declared as LGPL.
object dictionary editor ver sourceforge

However, CANopenNode is a GPL linking exception.

/*
* CANopen Object Dictionary.
*
* This file was automatically generated with CANopenNode Object
* Dictionary Editor. DON'T EDIT THIS FILE MANUALLY !!!!
* Object Dictionary Editor is currently an older, but functional web
* application. For more info see See 'Object_Dictionary_Editor/about.html' in
* <http://sourceforge.net/p/canopennode/code_complete/ci/master/tree/>
* For more information on CANopen Object Dictionary see <CO_SDO.h>.
*
* @file CO_OD.c
* @author Janez Paternoster
* @copyright 2010 - 2016 Janez Paternoster
*
* This file is part of CANopenNode, an opensource CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
*
* CANopenNode is free and open source software: you can redistribute
* it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Following clarification and special exception to the GNU General Public
* License is included to the distribution terms of CANopenNode:
*
* Linking this library statically or dynamically with other modules is
* making a combined work based on this library. Thus, the terms and
* conditions of the GNU General Public License cover the whole combination.
*
* As a special exception, the copyright holders of this library give
* you permission to link this library with independent modules to
* produce an executable, regardless of the license terms of these
* independent modules, and to copy and distribute the resulting
* executable under terms of your choice, provided that you also meet,
* for each linked independent module, the terms and conditions of the
* license of that module. An independent module is a module which is
* not derived from or based on this library. If you modify this
* library, you may extend this exception to your version of the
* library, but you are not obliged to do so. If you do not wish
* to do so, delete this exception statement from your version.
*/

/*
* CANopen Object Dictionary.
*
* This file was automatically generated with CANopenNode Object
* Dictionary Editor. DON'T EDIT THIS FILE MANUALLY !!!!
* Object Dictionary Editor is currently an older, but functional web
* application. For more info see See 'Object_Dictionary_Editor/about.html' in
* <http://sourceforge.net/p/canopennode/code_complete/ci/master/tree/>
* For more information on CANopen Object Dictionary see <CO_SDO.h>.
*
* @file CO_OD.h
* @author Janez Paternoster
* @copyright 2010 - 2016 Janez Paternoster
*
* This file is part of CANopenNode, an opensource CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
*
* CANopenNode is free and open source software: you can redistribute
* it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Following clarification and special exception to the GNU General Public
* License is included to the distribution terms of CANopenNode:
*
* Linking this library statically or dynamically with other modules is
* making a combined work based on this library. Thus, the terms and
* conditions of the GNU General Public License cover the whole combination.
*
* As a special exception, the copyright holders of this library give
* you permission to link this library with independent modules to
* produce an executable, regardless of the license terms of these
* independent modules, and to copy and distribute the resulting
* executable under terms of your choice, provided that you also meet,
* for each linked independent module, the terms and conditions of the
* license of that module. An independent module is a module which is
* not derived from or based on this library. If you modify this
* library, you may extend this exception to your version of the
* library, but you are not obliged to do so. If you do not wish
* to do so, delete this exception statement from your version.
*/

This confuses me.
Where can I download the Object Dictionary Editor?

I'm sorry I do not have enough English. :)

Thanks!

sdo callbacks

Hi,
I want to trigger some events via canopen sdo messages, like writting to index 0x2000 should start some measurement. As I can see, there is no callback functionality per OD entry, so I wonder what is the recomended way to figure out which OD entry has changed and call right handler?

CANOpenNode + FreeRTOS

Hi there!

Sorry for my English)
I've reconstructed this code to work under OS control, using queues, semaphores and other instruments. Want to push it here and make a public property. How can I do it?
Please contact me: [email protected]

Avoiding multibyte object split

Hi folks,

CO_PDO.c lock/unlock as below are needed, no ?

int16_t CO_TPDOsend(CO_TPDO_t *TPDO){
:
    /* Copy data from Object dictionary. */
    CO_LOCK_OD();
    /* Prevent mid-use multibyte object dictionary item alter by interrupting item write */
    for(; i>0; i--) {
        *(pPDOdataByte++) = **(ppODdataByte++);
    }
    CO_UNLOCK_OD();  /* Allow object dictionary item alter */
:
}

This to prevent for example, interrupt when only one byte of a uint16 object has been copied,
then an interrupting user-code function updates the uint16 in the OD, then the above code
resumes and copies the second byte. Resulting in, the sent uint16 comprising an old and new byte,
which do not necessarily form a coherent whole, for the usage in question. At least, if you have an
interrupting routine that writes to the OD, as I have.

Of course, the same applies to any interrupted multibyte object copy. Such as a float, or a string
(max 8 bytes): If part old bytes, and part new bytes, are copied, the resultant sent whole might not
necessarily be coherent. Or even legitimate, for a float.

In CO_driver.h, lock/unlock macros defined for example thus:

#define CO_LOCK_OD()   __disable_irq( );  /**< Lock critical section when accessing Object Dictionary */
#define CO_UNLOCK_OD() __enable_irq( );   /**< Unlock critical section when accessing Object Dictionary */

Presently the stack uses just in SDO.c as below, same reason I'd guess:

uint32_t CO_SDO_readOD(CO_SDO_t *SDO, uint16_t SDOBufferSize){
:
    /* copy data from OD to SDO buffer if not domain */
    if(ODdata != NULL){
        CO_LOCK_OD();
        while(length--) *(SDObuffer++) = *(ODdata++);
        CO_UNLOCK_OD();
:

Best regards,

David

PIC32MX 1/2/5 devices only have 16 CAN filters

Available CAN filters for PIC32 is hardcoded to 32 (see line 137 of CO_driver.c), while PIC32MX 1/2/5 only have 16. Trying to configure filters past the 16th fails and the associated COB-ID message is ignored. For example PIC32MX530F128L is affected. The datasheet points to the CAN section of PIC32 family reference manual which says there are 32 filters, but the datasheet specifies 16 and reality agrees. See datasheet (DS60001290D-page 243 figure 23-1)

Dual CAN interfaces

My application requires that I independently control two motors via two independent CAN buses (latency concerns on single bus). I'm using Linux and socketCAN.

I'm looking at the CANopenNode library and it appears that it provides a nice implementation, however it also appears that I can only use a single CAN interface per application. Is this correct? I am guessing I would need to modify the library to support multiple interfaces? Or is there a cleaner way to approach this?

FYI - I searched the discussion forums on SourceForge and found a thread from 2014 (https://sourceforge.net/p/canopennode/discussion/387151/thread/04054e35/?limit=25#37dc). Is this still true? Best approach would be to modify and implement multiple COO globals? If so, is this something that may be desirable for the masses, thus would require me submitting a pull request?

Thanks!

Block Mode Transfer Issue

Dear All,

I'm working on CANopennode on dsPIC33 (PIC24_dsPIC33) custom hardware platform and I'm trying to set up SDO block mode upload.

I'm able to perform SDO segmented transfer, but I'm having some mistakes on SDO block mode upload on server side.

I'm sending the request from a client node to a server node and I want to read a 32 byte buffer.
I've done many tests and I'm gone deep inside the library also in debug mode in order to better understand how the block mode transfer works.
In the detail I need to read a 32Byte variable ( called "bufferSpare")@ Index Ox7000 on Server Side.

At the end I'm able to perform the data transfer (SDO block mode upload) only if the variable on the Object Dictionary on Server side is defined as "VISIBLE STRING".
This is the object dictionary definition
"{0x7000, 0x00, 0x3E, 32, (void*)&CO_OD_RAM.bufferSpare[0]},"

If I define the variable as an array of 32 elements , type unsigned 8 the SDO block mode fails (the server answer to the client as if it needs to perform a segmented mode). This seems to be connected to the lenght of data.
If I define the variable as array the SDO manager recognizes it as leght is 1 byte (ist this the lenght of the sigle array element?) ; If I define the variable as a "VISIBLE STRING" of 32 characters the SDO manager rcognizes the legnht as 32 and the SDO block transfer is done.

Is this something I need to configure on the Object Dictionary on Server Side to make werk the SDO Block Mode transfer also for Array variables? Or is there any implementation limit that frorce me to use "VISIBLE STRING" type variables for block mode transfer?

I'll very appreciate any helps.

Best Regards

Emanuele

thread/interrupt signaling

While looking at error #39, I came across receive message signaling. This is currently done by copying the message and then setting a flag in one thread/interrupt and evaluation in another thread/main loop. This might work on some embedded compilers (like the free microchip ones), but can break when enabling compiler optimization. As soon as you do that, your compiler is allowed to shuffle around memory copy operations as it likes to do. So you have no guarantee that xxx->CANrxNew = true; is actually executed last.

I'm thinking about the 'best way' to fix this. I can see some options that might be viable:

  • Add memory barrier and set the flag as volatile variable to ensure copy and evaluation order. With GCC this is __sync_synchronize(). I have no idea how (and if) to add the memory barrier with other compilers.
  • move this signaling to stack specific queueing functions (like it is done with e.g. memcpy), where the user can decide it the current behaviour is acceptable, or do something different like use the OSes queuing functions.

Section in Readme.md describing commercial use

It would be useful to just have a section in the Readme.md file which states that the library can be used in commercial projects. I read the License description but was still unsure if it really allows to use it in a commercial project. But fortunately I found the discussion in the forum (https://sourceforge.net/p/canopennode/discussion/387151/thread/b7910450/) which discusses the issue.
So to make this more obvious to anybody a extra section would be helpful.

Conflict type name and std macro

Hi all,
There is a conflict between a typedef in CO_OD.h and a macro defined in math.h
typedef domain_t DOMAIN; (l.53)

Of course, it is not dramatic at all, but hey, worth the shot to say it.

What is the communication recovery method when the cable is reconnected?

I am very much interested in implementing CANopen with the CANopenNode project.
I am currently analyzing canopend to analyze CANopenNode, but there is one question.
This is related to operatingState when reconnecting CANopen cable.

My environment is as follows.
CANopen PLC : LS's XBL-CMEA(NodeId:127)
canopend : mcp2515 + mcp2551(NodeID:77)
xbl_cmea
mcp2515

I have registered canopend's CANopenSocket.eds file in XBL-CMEA.
Below is a diagram of the network situation in XG-CANopen, a related program of XBL-CEMA. (XG-CANopen is a control program of XBML-CMEA)
2_xg_canopen_ok

I have a CAN to USB (CANtact) product for debugging CANopen.
I use this USB to check the can-bus data.

Now connect the cable and run canopend to send the heartbeat signals as shown below.
1_ok

Here, when I unplug the canopend cable, the following repetitive data appears.(Output data of XBL-CEMA)
3_cable_disconnect

If the cable is reconnected, canopend will not enter the operation state while repeating the same communication as the image below.(pre-operation state)
https://youtu.be/IgOp8XYmlrI
And PDO communication is not possible either.
I thought that reconnecting the cable to the canopend device would restore the operation and communicate smoothly.

In case of canopencomm 'reset communication' signal, communication is restored.

I wanted the communication to be automatically restored upon cable connection without going through canopencomm.
So I modified the source as shown below.
KwonTae-young/CANopenSocket@e01be10
test_source

When I tested it, the communication was restored automatically when the cable was connected.
https://youtu.be/bepekqQ_NdQ

I implemented it as if I did reset comunication in canopencomm in that part for testing.
Is reset communication the only way to recover communications in this situation?
Is this the best way?

I am a beginner in canopen.
I'm sorry if it was a basic question.

I'm sorry I do not have enough English. :)
Thanks!

Slave / master

I am new to CAN open protocol. Is it possible to create CAN Open slave using this library in PIC controller

inconsistent error behavior

Hey,
I'm testing with the Conformance Test Tool and observe a strange behavior at Test PDO 26, the test tries to map too long objects. However, the error bits are set in object 1001, for the other error tests e. g.: PDO 25 (too many objects) this does not happen. The reason for this is that the function CO_RPDOconfigMap is executed in line 630 of CO_PDO. c, which is not executed in the other tests.
Is that a bug? The error bits are not reset anywhere except during reset.

Missing breaks in switch statement

My interpretation of this code is that should the if statement evaluate to false the corresponding return won't be called, and the program will erroneously move onto the next case statement. Each case statement should end with a break;.

CANopenNode/stack/CO_PDO.c

Lines 843 to 850 in 5338015

case 8: if(*(--pPDOdataByte) != **(--ppODdataByte) && (TPDO->sendIfCOSFlags&0x80)) return 1;
case 7: if(*(--pPDOdataByte) != **(--ppODdataByte) && (TPDO->sendIfCOSFlags&0x40)) return 1;
case 6: if(*(--pPDOdataByte) != **(--ppODdataByte) && (TPDO->sendIfCOSFlags&0x20)) return 1;
case 5: if(*(--pPDOdataByte) != **(--ppODdataByte) && (TPDO->sendIfCOSFlags&0x10)) return 1;
case 4: if(*(--pPDOdataByte) != **(--ppODdataByte) && (TPDO->sendIfCOSFlags&0x08)) return 1;
case 3: if(*(--pPDOdataByte) != **(--ppODdataByte) && (TPDO->sendIfCOSFlags&0x04)) return 1;
case 2: if(*(--pPDOdataByte) != **(--ppODdataByte) && (TPDO->sendIfCOSFlags&0x02)) return 1;
case 1: if(*(--pPDOdataByte) != **(--ppODdataByte) && (TPDO->sendIfCOSFlags&0x01)) return 1;

SDO communication after "SDO block upload end" is dropped

When doing a SDO block upload and immediately after that starting another SDO request, this request is dropped.
This happens e.g. in the CANopen conformance test tool when checking SDO test 19 followed by 21. This is equivalent to the following linux commands

#do SDO upload block
cansend can0 67f#a0.00.10.00.14.00.00.00
sleep 0.1
cansend can0 67f#a3.00.00.00.00.00.00.00
sleep 0.1
cansend can0 67f#a2.01.14.00.00.00.00.00
sleep 0.1
#SDO block upload end
cansend can0 67f#a1.00.00.00.00.00.00.00
#immediately start next SDO communication
cansend can0 67f#C2.17.10.00.02.00.00.00

I've narrowed this down to the CO_SDO_receive() function. This receives the new request before the "SDO block upload end" message is processed, and therefore just drops it.
When looking at the spec, I can't find anything that would speak against having this sequence. I also think this is a realistic scenario for the client to just start the next request after one has finished.

From looking at the code, I have no idea how to fix this easily, at least for upstream...

I've also had a look at the other SDO transfer methods. They are not affected as the end message is always from server to client.

reference: CiA301, 7.2.4.3.12 Protocol SDO block upload

synchronous RPDOs lost

I’m using CANopenNode for an actuator project. Asynchronous RPDOs work fine. However, I noticed that some synchronous RPDO commands were getting lost. It looks like CO_RPDO_process() clears the CANrxNew flags every time it is called, rather than just when the sync flag is set and the RPDO processed. The main loop calls CO_process_SYNC_RPDO() once every one millisecond tick. If the sync message arrives once every 10ms and the RPDO arrives at some random time between syncs, there would be a 90% chance of the function resetting the new flag without processing the RPDO. I’m wondering if this is a bug or I’ve misunderstood something. Thanks.

canopennode as master(clinet)

hi
i wana use canopennode stack for stm32f4 to control other devices(servers or slaves) via sdo Protocol
but I've afew problem about it.
1- what is the process for config sdo?
2- what is the process for sending a sdo massage and check the respond packet for being sure about that writing to object dictionary of slave done correctly ?
3- I cant find any practical help or pdf for using this stack
thanks for helping me

Feature - PDO serial data streaming

Hi,

i've added a manual PDO mode to CANopenNode. This can be used for special use cases like serial data streaming via PDO where every PDO message must be delivered (like this gateway: https://www.ixxat.com/products/products-industrial/gateways-and-bridges/can-gw100-rs232).
This required me to do changes to PDO and CAN driver. This now contains a additional send function that checks for remaining queue space before sending.
This function is used when a PDO is sent. This applies to all TPDOs, not only the ones under user control!

I'm not sure if we want this changes in the mainline stack. Have a look at it, if we want it I can create a pull-request.

https://github.com/martinwag/CANopenNode/tree/add-manual-pdo

regards & have a nice christmas
Martin

Overrun ?

Hi folks,

I'm trying to understand the usage intent, of the code below, within drvTemplate > CO_driver.c.

In very general terms, the design intent would seem to be, send the message if the CAN CPU hardware is free (with the 1 in 1 && to be replaced by a check that it is, as the supplied CPU drivers have done).

But if not free, set the buffer->bufferFull flag, indicating that the buffer in question has a pending message to be sent, in due course, by interrupt. For example, TPDO->CANtxBuff>bufferFull.

And that it how I find the stack to be operating - I have it all up and running, on an Infineon XMC4 CPU, with a CO_driver.c I have created, from the template.

Just one problem, though: When the function below is again called, if the buffer->bufferFull flag is set,
a CO_EMC_CAN_OVERRUN EMCY is generated. And indeed, I see this EMCY, with a CANbus analyser. But it seems to me, this EMCY doesn't need to be generated. Because there hasn't really been an overrun and loss of message. Just, a message is waiting to be sent by interrupt.

But perhaps, I've got something wrong with my understanding, Can anyone shed some light ?

Infact, I think this CO_EMC_CAN_OVERRUN is constantly occurring. But of course, just the one EMCY occurs, because I think I read that CANOpen by design doesn't repeat the same EMCY, until cleared.

Anyway, a consequence of the EMCY, is that 1003h Pre-defined error, changes from 0 to 0x10, signifying a comms error. As a result, NMT blocks transition of my device to Operational mode, from Pre-Op or Stopped.

It goes OK to Operational at boot or on NMT comms reset, though.

Thanks,

David King

CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer){
    CO_ReturnError_t err = CO_ERROR_NO;

    /* Verify overflow */
    if(buffer->bufferFull){
        if(!CANmodule->firstCANtxMessage){
            /* don't set error, if bootup message is still on buffers */
            CO_errorReport((CO_EM_t*)CANmodule->em, CO_EM_CAN_TX_OVERFLOW, CO_EMC_CAN_OVERRUN, buffer->ident);
        }
        err = CO_ERROR_TX_OVERFLOW;
    }

    CO_LOCK_CAN_SEND();
    /* if CAN TX buffer is free, copy message to it */
    if(1 && CANmodule->CANtxCount == 0){
        CANmodule->bufferInhibitFlag = buffer->syncFlag;
        /* copy message and txRequest */
    }
    /* if no buffer is free, message will be sent by interrupt */
    else{
        buffer->bufferFull = true;
        CANmodule->CANtxCount++;
    }
    CO_UNLOCK_CAN_SEND();

    return err;
}

IO Demo code Documentation?

Hello,

I am getting my sample for the STM32F103 Olimex P103 demo more and more to work. So simple read and write seems to work. Now I do not really know how to add the interaction with the input and output´s. Is it right that the demo should support 8 digital in, 8 digital out, and 8 analog in, and 8 analog out?

I also study the STM32 example which i found in the old SVN repo i don't see any read and write of the outputs or inputs whether analog or digital.

I do not have any PIC but I tried to study the CANopenNodePIC demo also. Does this demo also use the main from the CANopenNode Stack example ... so is it also an IO demo using the IO.eds file from the stack reop? It isn´t really not easy for someone which is quite new to canopen.

So can someone help me: Which file is the right one for the IO example? How does the interaction with the IO´s work? And where should I read and write the output?

many thanks.
cheers
mathias

HOW TO USE EXAMPLE IO.HTML

How to use the example io.eds and io.html present in the canopennode example program to the canopen i/o module

Example files appear to use uninitialized pointer

Hello,
I am using your CANOpennode software on a SAMA5D2 processor for a project of ours.
I got everything to make and was using the provided example main to just test that things were working before moving to implementing the driver interface when I encounted a problem.
At the beginning of main.c there are these lines:
/* disable CAN and CAN interrupts */ printf("Disable CAN and interrupts\n\r"); CO->CANmodule[0]->CANnormal = false;

seems straight forward, but on my eval board the program hangs and won't continue after this statement. I get the output from the printf, and then nothing after that.
From what I can tell CO has been created, but it is set to NULL.
It only gets initialised after this call:
/* initialize CANopen */ printf("Calling CO_init\n\r"); err = CO_init(0/* CAN module address */, 10/* NodeID */, 250 /* bit rate */);

I have looked at the PIC example and it is the same, yet I would assume it runs.
I feel like using the pointer before it's initialized is incorrect, and it doesn't work on my board, but I don't see anyone else complaining.
What am I missing here.

Thank you.

Rewriting the ODE

Using the ODE based on XUL files didn't work for me after many hours of research.

So I started to develop a new ODE written in python3.
Hopefully this will make scripting really easy.

You can see my working copy at ExMachina repository

I'll make a PR once it's usable. Right now only the data structure and the configuration file is working.

Comments and remarks are welcome.

Best regards,
Ben

Problem with heartbeat

Hello,

During the development of my application, I have found a problem with the emission of the heartbeat when I choose to reset node.
In function CO_NMT_process, a negative value can appear and the heartbeat will be emit 3 or 4 times every ms and create an error with TX_OVERFLOW
So, I made a correction that I share here :

/* Heartbeat producer message & Bootup message */
if((HBtime && NMT->HBproducerTimer >= HBtime) || NMT->operatingState == CO_NMT_INITIALIZING){

    NMT->HBproducerTimer = NMT->HBproducerTimer - HBtime;

    NMT->HB_TXbuff->data[0] = NMT->operatingState;
    CO_CANsend(NMT->HB_CANdev, NMT->HB_TXbuff);

    if(NMT->operatingState == CO_NMT_INITIALIZING){
					if(HBtime > NMT->firstHBTime) 
						NMT->HBproducerTimer = HBtime - NMT->firstHBTime;
// ! CORRECTION ! //
				        else
						NMT->HBproducerTimer = 0;
    // ! CORRECTION ! //
        if((NMTstartup & 0x04) == 0) NMT->operatingState = CO_NMT_OPERATIONAL;
        else                         NMT->operatingState = CO_NMT_PRE_OPERATIONAL;
    }
}

Best regards,

Valentin

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.