From f56c96db3c65ef61e051db8c8aa02ea5188cc25c Mon Sep 17 00:00:00 2001 From: Janez Date: Mon, 17 May 2021 13:29:13 +0200 Subject: [PATCH] Documentation arrangement according to doxygen. - Minor changes in most files - add CANopenNode.png - update doxyfile - move doc/LSSusage.md and doc/gettingStarted.md into CANopenDemo repository - update README.md --- 301/CO_Emergency.h | 5 +- 301/CO_HBconsumer.h | 5 +- 301/CO_NMT_Heartbeat.h | 5 +- 301/CO_ODinterface.h | 2 + 301/CO_PDO.h | 5 +- 301/CO_SDOclient.h | 5 +- 301/CO_SDOserver.h | 4 +- 301/CO_SYNC.h | 5 +- 301/CO_TIME.h | 5 +- 301/CO_config.h | 16 +++- 301/CO_driver.h | 8 +- 301/CO_fifo.h | 2 + 301/crc16-ccitt.h | 4 +- 303/CO_LEDs.h | 2 + 304/CO_GFC.h | 5 +- 304/CO_SRDO.h | 5 +- 305/CO_LSS.h | 5 +- 305/CO_LSSmaster.h | 8 +- 305/CO_LSSslave.h | 5 +- 309/CO_gateway_ascii.h | 7 +- CANopen.h | 3 +- Doxyfile | 107 +++++++++++++++------ README.md | 174 +++++++++++++-------------------- codingStyle | 9 +- doc/CANopenNode.png | Bin 0 -> 12693 bytes doc/CHANGELOG.md | 69 +++++++------ doc/LSSusage.md | 121 ----------------------- doc/deviceSupport.md | 9 +- doc/gettingStarted.md | 192 ------------------------------------- doc/traceUsage.md | 2 + example/DS301_profile.md | 18 ++-- extra/CO_trace.h | 5 +- storage/CO_storage.c | 2 +- storage/CO_storage.h | 4 +- storage/CO_storageEeprom.h | 2 + 35 files changed, 265 insertions(+), 560 deletions(-) create mode 100644 doc/CANopenNode.png delete mode 100644 doc/LSSusage.md delete mode 100644 doc/gettingStarted.md diff --git a/301/CO_Emergency.h b/301/CO_Emergency.h index e4d71b5..3015402 100644 --- a/301/CO_Emergency.h +++ b/301/CO_Emergency.h @@ -60,11 +60,10 @@ extern "C" { /** * @defgroup CO_Emergency Emergency - * @ingroup CO_CANopen_301 - * @{ - * * CANopen Emergency protocol. * + * @ingroup CO_CANopen_301 + * @{ * Error control and Emergency is used for control internal error state * and for sending a CANopen Emergency message. * diff --git a/301/CO_HBconsumer.h b/301/CO_HBconsumer.h index 73a5b09..4409760 100644 --- a/301/CO_HBconsumer.h +++ b/301/CO_HBconsumer.h @@ -50,11 +50,10 @@ extern "C" { /** * @defgroup CO_HBconsumer Heartbeat consumer - * @ingroup CO_CANopen_301 - * @{ - * * CANopen Heartbeat consumer protocol. * + * @ingroup CO_CANopen_301 + * @{ * Heartbeat consumer monitors Heartbeat messages from remote nodes. If any * monitored node don't send his Heartbeat in specified time, Heartbeat consumer * sends emergency message. If all monitored nodes are operational, then diff --git a/301/CO_NMT_Heartbeat.h b/301/CO_NMT_Heartbeat.h index 0362754..4254806 100644 --- a/301/CO_NMT_Heartbeat.h +++ b/301/CO_NMT_Heartbeat.h @@ -42,11 +42,10 @@ extern "C" { /** * @defgroup CO_NMT_Heartbeat NMT and Heartbeat - * @ingroup CO_CANopen_301 - * @{ - * * CANopen Network management and Heartbeat producer protocol. * + * @ingroup CO_CANopen_301 + * @{ * CANopen device can be in one of the @ref CO_NMT_internalState_t * - Initializing. It is active before CANopen is initialized. * - Pre-operational. All CANopen objects are active, except PDOs. diff --git a/301/CO_ODinterface.h b/301/CO_ODinterface.h index 00c2e22..32c80e6 100644 --- a/301/CO_ODinterface.h +++ b/301/CO_ODinterface.h @@ -34,6 +34,8 @@ extern "C" { /** * @defgroup CO_ODinterface OD interface + * CANopen Object Dictionary interface. + * * @ingroup CO_CANopen_301 * @{ * See @ref doc/objectDictionary.md diff --git a/301/CO_PDO.h b/301/CO_PDO.h index 5863db9..6a6bd87 100644 --- a/301/CO_PDO.h +++ b/301/CO_PDO.h @@ -51,11 +51,10 @@ extern "C" { /** * @defgroup CO_PDO PDO - * @ingroup CO_CANopen_301 - * @{ - * * CANopen Process Data Object protocol. * + * @ingroup CO_CANopen_301 + * @{ * Process data objects are used for real-time data transfer with no protocol * overhead. * diff --git a/301/CO_SDOclient.h b/301/CO_SDOclient.h index f84c044..7c9b32d 100644 --- a/301/CO_SDOclient.h +++ b/301/CO_SDOclient.h @@ -52,11 +52,10 @@ extern "C" { /** * @defgroup CO_SDOclient SDO client + * CANopen Service Data Object - client protocol. + * * @ingroup CO_CANopen_301 * @{ - * - * CANopen Service Data Object - client protocol (master functionality). - * * @see @ref CO_SDOserver */ diff --git a/301/CO_SDOserver.h b/301/CO_SDOserver.h index 3daa6e8..594cd5c 100644 --- a/301/CO_SDOserver.h +++ b/301/CO_SDOserver.h @@ -46,11 +46,11 @@ extern "C" { /** * @defgroup CO_SDOserver SDO server + * CANopen Service Data Object - server protocol. + * * @ingroup CO_CANopen_301 * @{ * - * CANopen Service Data Object - server protocol. - * * Service data objects (SDOs) allow the access to any entry of the CANopen * Object dictionary. By SDO a peer-to-peer communication channel between two * CANopen devices is established. In addition, the SDO protocol enables to diff --git a/301/CO_SYNC.h b/301/CO_SYNC.h index 8843bd9..9bc3384 100644 --- a/301/CO_SYNC.h +++ b/301/CO_SYNC.h @@ -48,11 +48,10 @@ extern "C" { /** * @defgroup CO_SYNC SYNC - * @ingroup CO_CANopen_301 - * @{ - * * CANopen Synchronisation protocol. * + * @ingroup CO_CANopen_301 + * @{ * For CAN identifier see #CO_Default_CAN_ID_t * * SYNC message is used for synchronization of the nodes on network. One node diff --git a/301/CO_TIME.h b/301/CO_TIME.h index ababf37..2f12d19 100644 --- a/301/CO_TIME.h +++ b/301/CO_TIME.h @@ -46,11 +46,10 @@ extern "C" { /** * @defgroup CO_TIME TIME - * @ingroup CO_CANopen_301 - * @{ - * * CANopen Time-stamp protocol. * + * @ingroup CO_CANopen_301 + * @{ * For CAN identifier see @ref CO_Default_CAN_ID_t * * TIME message is used for time synchronization of the nodes on the network. diff --git a/301/CO_config.h b/301/CO_config.h index 0b905f2..8bef9a0 100644 --- a/301/CO_config.h +++ b/301/CO_config.h @@ -33,9 +33,9 @@ extern "C" { /** * @defgroup CO_STACK_CONFIG Stack configuration - * @ingroup CO_driver + * Stack configuration and enabling macros. * - * Stack configuration macros specify, which parts of the stack will be enabled. + * @ingroup CO_driver * * Default values for stack configuration macros are set in corresponding * header files. The same default values are also provided in this file, but @@ -57,6 +57,7 @@ extern "C" { /** * @defgroup CO_STACK_CONFIG_COMMON Common definitions + * Constants for common definitions. * @{ */ /** @@ -125,6 +126,7 @@ extern "C" { /** * @defgroup CO_STACK_CONFIG_NMT_HB NMT master/slave and HB producer/consumer + * Specified in standard CiA 301 * @{ */ /** @@ -198,6 +200,7 @@ extern "C" { /** * @defgroup CO_STACK_CONFIG_EMERGENCY Emergency producer/consumer + * Specified in standard CiA 301 * @{ */ /** @@ -335,6 +338,7 @@ extern "C" { /** * @defgroup CO_STACK_CONFIG_SDO SDO server/client + * Specified in standard CiA 301 * @{ */ /** @@ -417,6 +421,7 @@ extern "C" { /** * @defgroup CO_STACK_CONFIG_TIME Time producer/consumer + * Specified in standard CiA 301 * @{ */ /** @@ -441,6 +446,7 @@ extern "C" { /** * @defgroup CO_STACK_CONFIG_SYNC_PDO SYNC and PDO producer/consumer + * Specified in standard CiA 301 * @{ */ /** @@ -499,7 +505,7 @@ extern "C" { /** * @defgroup CO_STACK_CONFIG_STORAGE Data storage - * Data storage with CANopen OD objects 1010 and 1011 + * Data storage with CANopen OD objects 1010 and 1011, CiA 301 * @{ */ /** @@ -691,7 +697,7 @@ extern "C" { /** * @defgroup CO_STACK_CONFIG_CRC16 CRC 16 calculation - * Helper object + * Helper object for CRC-16 checksum * @{ */ /** @@ -711,7 +717,7 @@ extern "C" { /** * @defgroup CO_STACK_CONFIG_FIFO FIFO buffer - * Helper object + * Helper object for FIFO buffer * @{ */ /** diff --git a/301/CO_driver.h b/301/CO_driver.h index f881b1b..3d2bb05 100644 --- a/301/CO_driver.h +++ b/301/CO_driver.h @@ -60,11 +60,10 @@ extern "C" { /** * @defgroup CO_driver Driver - * @ingroup CO_CANopen_301 - * @{ - * * Interface between CAN hardware and CANopenNode. * + * @ingroup CO_CANopen_301 + * @{ * CANopenNode is designed for speed and portability. It runs efficiently on * devices from simple 16-bit microcontrollers to PC computers. It can run in * multiple threads. Reception of CAN messages is pre-processed with very fast @@ -393,6 +392,9 @@ typedef struct { /** * @defgroup CO_critical_sections Critical sections * @{ + * + * Protection of critical sections in multi-threaded operation. + * * CANopenNode is designed to run in different threads, as described in * [README.md](index.html). Threads are implemented differently in different * systems. In microcontrollers threads are interrupts with different diff --git a/301/CO_fifo.h b/301/CO_fifo.h index c241365..b6f657e 100644 --- a/301/CO_fifo.h +++ b/301/CO_fifo.h @@ -41,6 +41,8 @@ extern "C" { /** * @defgroup CO_CANopen_301_fifo FIFO circular buffer + * FIFO circular buffer for continuous data flow. + * * @ingroup CO_CANopen_301 * @{ * diff --git a/301/crc16-ccitt.h b/301/crc16-ccitt.h index 186e534..8fe3070 100644 --- a/301/crc16-ccitt.h +++ b/301/crc16-ccitt.h @@ -42,11 +42,11 @@ extern "C" { /** * @defgroup CO_crc16_ccitt CRC 16 CCITT + * Calculation of CRC 16 CCITT polynomial. + * * @ingroup CO_CANopen_301 * @{ * - * Calculation of CRC 16 CCITT polynomial. - * * Equation: * * `x^16 + x^12 + x^5 + 1` diff --git a/303/CO_LEDs.h b/303/CO_LEDs.h index d8937f9..21f02de 100644 --- a/303/CO_LEDs.h +++ b/303/CO_LEDs.h @@ -43,6 +43,8 @@ extern "C" { /** * @defgroup CO_LEDs LED indicators + * Specified in standard CiA 303-3. + * * @ingroup CO_CANopen_303 * @{ * diff --git a/304/CO_GFC.h b/304/CO_GFC.h index 07a0b22..575b6bd 100644 --- a/304/CO_GFC.h +++ b/304/CO_GFC.h @@ -41,11 +41,10 @@ extern "C" { /** * @defgroup CO_GFC GFC - * @ingroup CO_CANopen_304 - * @{ - * * Global fail-safe command protocol. * + * @ingroup CO_CANopen_304 + * @{ * Very simple consumer/producer protocol. * A net can have multiple GFC producer and multiple GFC consumer. * On a safety-relevant the producer can send a GFC message (ID 0, DLC 0). diff --git a/304/CO_SRDO.h b/304/CO_SRDO.h index 10ef427..37783db 100644 --- a/304/CO_SRDO.h +++ b/304/CO_SRDO.h @@ -47,11 +47,10 @@ extern "C" { /** * @defgroup CO_SRDO SRDO - * @ingroup CO_CANopen_304 - * @{ - * * CANopen Safety Related Data Object protocol. * + * @ingroup CO_CANopen_304 + * @{ * The functionality is very similar to that of the PDOs. * The main differences is every message is send and received twice. * The second message must be bitwise inverted. The delay between the two messages and between each message pair is monitored. diff --git a/305/CO_LSS.h b/305/CO_LSS.h index dae9625..8207a87 100644 --- a/305/CO_LSS.h +++ b/305/CO_LSS.h @@ -43,11 +43,10 @@ extern "C" { /** * @defgroup CO_LSS LSS - * @ingroup CO_CANopen_305 - * @{ - * * CANopen Layer Setting Services protocol (common). * + * @ingroup CO_CANopen_305 + * @{ * LSS protocol is according to CiA DSP 305 V3.0.0. * * LSS services and protocols are used to inquire or to change the settings diff --git a/305/CO_LSSmaster.h b/305/CO_LSSmaster.h index 6802809..0957880 100644 --- a/305/CO_LSSmaster.h +++ b/305/CO_LSSmaster.h @@ -37,11 +37,10 @@ extern "C" { /** * @defgroup CO_LSSmaster LSS Master - * @ingroup CO_CANopen_305 - * @{ - * * CANopen Layer Setting Service - master protocol. * + * @ingroup CO_CANopen_305 + * @{ * The client/master can use the following services * - node selection via LSS address * - node selection via LSS fastscan @@ -59,8 +58,7 @@ extern "C" { * * ###Usage * - * Usage of the CANopen LSS master is demonstrated in CANopenSocket application, - * see CO_LSS_master.c / CO_LSS_master.h files. + * Usage of the CANopen LSS master is demonstrated in file 309/CO_gateway_ascii.c * * It essentially is always as following: * - select node(s) diff --git a/305/CO_LSSslave.h b/305/CO_LSSslave.h index 5593e7d..cb3da5d 100644 --- a/305/CO_LSSslave.h +++ b/305/CO_LSSslave.h @@ -38,11 +38,10 @@ extern "C" { /** * @defgroup CO_LSSslave LSS Slave - * @ingroup CO_CANopen_305 - * @{ - * * CANopen Layer Setting Service - slave protocol. * + * @ingroup CO_CANopen_305 + * @{ * The slave provides the following services * - node selection via LSS address * - node selection via LSS fastscan diff --git a/309/CO_gateway_ascii.h b/309/CO_gateway_ascii.h index b79fe42..832107b 100644 --- a/309/CO_gateway_ascii.h +++ b/309/CO_gateway_ascii.h @@ -47,11 +47,10 @@ extern "C" { /** * @defgroup CO_CANopen_309_3 Gateway ASCII mapping - * @ingroup CO_CANopen_309 - * @{ - * * CANopen access from other networks - ASCII mapping (CiA 309-3 DSP v3.0.0) * + * @ingroup CO_CANopen_309 + * @{ * This module enables ascii command interface (CAN gateway), which can be used * for master interaction with CANopen network. Some sort of string input/output * stream can be used, for example serial port + terminal on microcontroller or @@ -70,6 +69,8 @@ extern "C" { /** * @defgroup CO_CANopen_309_3_Syntax Command syntax + * ASCII command syntax. + * * @{ * * @code{.unparsed} diff --git a/CANopen.h b/CANopen.h index 44f6be8..0fe3434 100644 --- a/CANopen.h +++ b/CANopen.h @@ -55,8 +55,7 @@ extern "C" { * @defgroup CO_CANopen CANopen * @{ * - * CANopenNode is free and open source implementation of CANopen communication - * protocol. + * CANopenNode is free and open source CANopen communication protocol stack. * * CANopen is the internationally standardized (EN 50325-4) (CiA DS-301) * CAN-based higher-layer protocol for embedded control system. For more diff --git a/Doxyfile b/Doxyfile index 7bfa59c..acaab7e 100644 --- a/Doxyfile +++ b/Doxyfile @@ -44,14 +44,14 @@ PROJECT_NUMBER = # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = +PROJECT_BRIEF = "CANopen protocol stack" # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. -PROJECT_LOGO = +PROJECT_LOGO = doc/CANopenNode.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is @@ -126,7 +126,17 @@ REPEAT_BRIEF = YES # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. -ABBREVIATE_BRIEF = +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief @@ -326,7 +336,7 @@ MARKDOWN_SUPPORT = YES # Minimum value: 0, maximum value: 99, default value: 5. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. -TOC_INCLUDE_HEADINGS = 0 +TOC_INCLUDE_HEADINGS = 5 # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can @@ -376,7 +386,7 @@ IDL_PROPERTY_SUPPORT = YES # all members of a group must be documented explicitly. # The default value is: NO. -DISTRIBUTE_GROUP_DOC = YES +DISTRIBUTE_GROUP_DOC = NO # If one adds a struct or class to a group and this option is enabled, then also # any nested class or struct is added to the same group. By default this option @@ -823,8 +833,7 @@ INPUT = README.md \ 305 \ 309 \ storage \ - extra \ - socketCAN + extra # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -851,7 +860,53 @@ INPUT_ENCODING = UTF-8 # C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, # *.vhdl, *.ucf, *.qsf and *.ice. -FILE_PATTERNS = +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.doc \ + *.txt \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f18 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. @@ -906,7 +961,7 @@ EXAMPLE_PATH = # *.h) to filter out the source-files in the directories. If left blank all # files are included. -EXAMPLE_PATTERNS = +EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands @@ -975,7 +1030,7 @@ FILTER_SOURCE_PATTERNS = # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = README.md +USE_MDFILE_AS_MAINPAGE = ./README.md #--------------------------------------------------------------------------- # Configuration options related to source browsing @@ -1244,7 +1299,7 @@ HTML_COLORSTYLE_GAMMA = 80 # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_TIMESTAMP = YES +HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that @@ -1263,7 +1318,7 @@ HTML_DYNAMIC_MENUS = YES # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_DYNAMIC_SECTIONS = NO +HTML_DYNAMIC_SECTIONS = YES # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand @@ -1276,7 +1331,7 @@ HTML_DYNAMIC_SECTIONS = NO # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_INDEX_NUM_ENTRIES = 100 +HTML_INDEX_NUM_ENTRIES = 35 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development @@ -1475,7 +1530,7 @@ ECLIPSE_DOC_ID = org.doxygen.Project # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -DISABLE_INDEX = YES +DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag @@ -1492,7 +1547,7 @@ DISABLE_INDEX = YES # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -GENERATE_TREEVIEW = YES +GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. @@ -1587,7 +1642,7 @@ MATHJAX_FORMAT = HTML-CSS # The default value is: https://cdn.jsdelivr.net/npm/mathjax@2. # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2 # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example @@ -1717,7 +1772,7 @@ LATEX_OUTPUT = latex # the output language. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_CMD_NAME = latex +LATEX_CMD_NAME = # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate # index for LaTeX. @@ -2159,13 +2214,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = CO_DOXYGEN=1 \ - CO_NO_SYNC=1 \ - CO_NO_SDO_CLIENT=1 \ - CO_NO_NMT_MASTER=1 \ - CO_NO_LSS_SERVER=1 \ - CO_NO_LSS_CLIENT=1 \ - CO_NO_TRACE=1 +PREDEFINED = CO_DOXYGEN=1 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -2209,7 +2258,7 @@ TAGFILES = # tag file that is based on the input files it reads. See section "Linking to # external documentation" for more information about the usage of tag files. -GENERATE_TAGFILE = +GENERATE_TAGFILE = doc/html/CANopenNode.tag # If the ALLEXTERNALS tag is set to YES, all external class will be listed in # the class index. If set to NO, only the inherited external classes will be @@ -2243,7 +2292,7 @@ EXTERNAL_PAGES = YES # powerful graphs. # The default value is: YES. -CLASS_DIAGRAMS = NO +CLASS_DIAGRAMS = YES # You can include diagrams made with dia in doxygen documentation. Doxygen will # then run dia to produce the diagram and insert it in the documentation. The @@ -2265,7 +2314,7 @@ HIDE_UNDOC_RELATIONS = YES # set to NO # The default value is: YES. -HAVE_DOT = NO +HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed # to run in parallel. When set to 0 doxygen will base this on the number of @@ -2427,7 +2476,7 @@ DIRECTORY_GRAPH = YES # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_IMAGE_FORMAT = png +DOT_IMAGE_FORMAT = svg # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. @@ -2439,7 +2488,7 @@ DOT_IMAGE_FORMAT = png # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -INTERACTIVE_SVG = NO +INTERACTIVE_SVG = YES # The DOT_PATH tag can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. diff --git a/README.md b/README.md index 4db5354..0df8fb1 100644 --- a/README.md +++ b/README.md @@ -3,77 +3,62 @@ CANopenNode CANopenNode is free and open source CANopen protocol stack. -CANopen is the internationally standardized (EN 50325-4) -([CiA301](http://can-cia.org/standardization/technical-documents)) -higher-layer protocol for embedded control system built on top of CAN. -For more information on CANopen see http://www.can-cia.org/ +CANopen is the internationally standardized (EN 50325-4) ([CiA301](http://can-cia.org/standardization/technical-documents)) 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. -Linux implementation with CANopen master functionalities is included. +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 ordered in CANopen Object -Dictionary and are accessible from both: C code and from CANopen network. +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`. +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](https://www.can-cia.org/can-knowledge/canopen/device-architecture/) - offers clear and flexible organisation of any variables. Variables can be accessed - directly or via read/write functions. - - [NMT](https://www.can-cia.org/can-knowledge/canopen/network-management/) - slave to start, stop, reset device. Simple NMT master. - - [Heartbeat](https://www.can-cia.org/can-knowledge/canopen/error-control-protocols/) - producer/consumer error control for monitoring of CANopen devices. - - [PDO](https://www.can-cia.org/can-knowledge/canopen/pdo-protocol/) 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](https://www.can-cia.org/can-knowledge/canopen/sdo-protocol/) server - enables expedited, segmented and block transfer access to all Object - Dictionary variables inside CANopen device. - - [SDO](https://www.can-cia.org/can-knowledge/canopen/sdo-protocol/) client can - access any Object Dictionary variable on any CANopen device inside the network. - - [Emergency](https://www.can-cia.org/can-knowledge/canopen/special-function-protocols/) - message producer/consumer. - - [Sync](https://www.can-cia.org/can-knowledge/canopen/special-function-protocols/) - producer/consumer enables network synchronized transmission of the PDO objects, etc. - - [Time-stamp](https://www.can-cia.org/can-knowledge/canopen/special-function-protocols/) - producer/consumer enables date and time synchronization in millisecond resolution. - - [LSS](https://www.can-cia.org/can-knowledge/canopen/cia305/) CANopen node-id - and bitrate setup, master and slave, LSS fastscan. - - [CANopen gateway](https://www.can-cia.org/can-knowledge/canopen/cia309/), - 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 + - [Object Dictionary](https://www.can-cia.org/can-knowledge/canopen/device-architecture/) offers clear and flexible organisation of any variables. Variables can be accessed directly or via read/write functions. + - [NMT](https://www.can-cia.org/can-knowledge/canopen/network-management/) slave to start, stop, reset device. Simple NMT master. + - [Heartbeat](https://www.can-cia.org/can-knowledge/canopen/error-control-protocols/) producer/consumer error control for monitoring of CANopen devices. + - [PDO](https://www.can-cia.org/can-knowledge/canopen/pdo-protocol/) 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](https://www.can-cia.org/can-knowledge/canopen/sdo-protocol/) server enables expedited, segmented and block transfer access to all Object Dictionary variables inside CANopen device. + - [SDO](https://www.can-cia.org/can-knowledge/canopen/sdo-protocol/) client can access any Object Dictionary variable on any CANopen device inside the network. + - [Emergency](https://www.can-cia.org/can-knowledge/canopen/special-function-protocols/) message producer/consumer. + - [Sync](https://www.can-cia.org/can-knowledge/canopen/special-function-protocols/) producer/consumer enables network synchronized transmission of the PDO objects, etc. + - [Time-stamp](https://www.can-cia.org/can-knowledge/canopen/special-function-protocols/) producer/consumer enables date and time synchronization in millisecond resolution. + - [LSS](https://www.can-cia.org/can-knowledge/canopen/cia305/) CANopen node-id and bitrate setup, master and slave, LSS fastscan. + - [CANopen gateway](https://www.can-cia.org/can-knowledge/canopen/cia309/), 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 ### Other - [Suitable for 16-bit microcontrollers and above](#device-support) - [Multithreaded, real-time](#flowchart-of-a-typical-canopennode-implementation) - [Object Dictionary editor](#object-dictionary-editor) - - Non-volatile storage for Object Dictionary or other variables. Automatic or - controlled by standard CANopen commands, configurable. + - Non-volatile storage for Object Dictionary or other variables. Automatic or controlled by standard CANopen commands, configurable. - [Power saving possible](#power-saving) - [Bootloader possible](https://github.com/CANopenNode/CANopenNode/issues/111) (for firmware update) +Related projects +---------------- + - [CANopenNode](https://github.com/CANopenNode/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](https://github.com/CANopenNode/CANopenDemo): Demo device with CANopenNode and different target systems, tutorial and testing tools. + - [CANopenNode.github.io](https://github.com/CANopenNode/CANopenNode.github.io): Html documentation, compiled by doxygen, for CANopenDemo, CANopenNode and other devices, available also online: https://canopennode.github.io + - [libedssharp](https://github.com/robincornelius/libedssharp): 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. + - [CANopenLinux](https://github.com/CANopenNode/CANopenLinux): CANopenNode on Linux devices. It can be a basic CANopen device or more advanced with commander functionalities. + - [CANopenPIC](https://github.com/CANopenNode/CANopenPIC): CANopenNode on PIC microcontrollers from Microchip. Works with 16-bit and 32 bit devices. Includes example for Arduino style [Max32](https://reference.digilentinc.com/reference/microprocessor/max32/start) board. + - [doc/deviceSupport.md](doc/deviceSupport.md): List of other implementations of CANopenNode on different devices. + + Documentation, support and contributions ---------------------------------------- -Documentation with [Getting started](doc/gettingStarted.md), -[Objec Dictionary](doc/objectDictionary.md) and [LSS usage](doc/LSSusage.md) -is in `doc` directory. -Code is documented in header files. Running [doxygen](http://www.doxygen.nl/) -in project base directory will produce complete html documentation. -Just open CANopenNode/doc/html/index.html in the browser. Alternatively browse -documentation [online](https://canopennode.github.io/CANopenSocket/). -Further documented examples are available in [CANopenSocket](https://github.com/CANopenNode/CANopenSocket) project. +All code is documented in the source header files. Some additional documents are in `doc` directory. + +To generate complete html documentation, run [doxygen](http://www.doxygen.nl/) 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](https://github.com/CANopenNode/CANopenDemo) repository. Report issues on https://github.com/CANopenNode/CANopenNode/issues @@ -81,15 +66,13 @@ For discussion on [Slack](https://canopennode.slack.com/) see: https://github.co 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. Some basic formatting -rules should be followed: Linux style with indentation of 4 spaces. There is -also a `codingStyle` file with example and a configuration file for -`clang-format` tool. +Contributions are welcome. Best way to contribute your code is to fork a project, modify it and then send a pull request. Some basic formatting +rules should be followed: Linux style with indentation of 4 spaces. There is also a `codingStyle` file with example and a configuration file for `clang-format` tool. -Flowchart of a typical CANopenNode implementation -------------------------------------------------- +CANopenNode configuration +------------------------- +Flowchart of a typical CANopenNode implementation: ~~~ ----------------------- | Program start | @@ -125,6 +108,16 @@ Flowchart of a typical CANopenNode implementation ---------------------- ------------------------ ----------------------- ~~~ +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 -------------- @@ -154,7 +147,7 @@ File structure - **309/** - CANopen access from other networks. - **CO_gateway_ascii.h/.c** - Ascii mapping: NMT master, LSS master, SDO client. - **storage/** - - **CO_OD_storage.h/.c** - CANopen data storage base object. + - **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/** @@ -163,25 +156,20 @@ File structure - **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. + - **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. - - **gettingStarted.md, LSSusage.md, traceUsage.md** - Getting started and usage. - **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. + - **CANopen.h/.c** - Initialization and processing of CANopen objects, suitable for common configurations. - **codingStyle** - Example of the coding style. - - **.clang-format** - Definition file for the coding style. - **Doxyfile** - Configuration file for the documentation generator *doxygen*. - - **canopend** - Executable for Linux, build with `make`. - **LICENSE** - License. - **README.md** - This file. @@ -190,62 +178,36 @@ 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: -[libedssharp](https://github.com/robincornelius/libedssharp). Latest pre-compiled -[binaries](https://github.com/robincornelius/libedssharp/raw/gh-pages/build/OpenEDSEditor-latest.zip) -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. +To customize the Object Dictionary it is necessary to use external application: [libedssharp](https://github.com/robincornelius/libedssharp). Latest pre-compiled [binaries](https://github.com/robincornelius/libedssharp/raw/gh-pages/build/OpenEDSEditor-latest.zip) 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. +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. +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](doc/objectDictionary.md). +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](doc/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. +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](doc/objectDictionary.md) for more information. +CANopenNode includes some custom properties inside standard project file. See [objectDictionary.md](doc/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. +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](doc/deviceSupport.md) for list of known device interfaces. +It is not practical to have all device interfaces in a single project. Interfaces to other microcontrollers are in separate projects. See [deviceSupport.md](doc/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 and it is not implemented in CANopenNode. +RTR (remote transmission request) is a feature of CAN bus. Usage of RTR is not recommended for CANopen and it 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. +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. +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 diff --git a/codingStyle b/codingStyle index 6452ba8..a2dde73 100644 --- a/codingStyle +++ b/codingStyle @@ -51,9 +51,6 @@ extern "C" { * * Doxygen specifics: If description of the structure member is one sentence * only, don't use period after the sentence. - * - * ###Misra C - * Code shall follow MISRA-C:2012 standard. */ @@ -75,15 +72,15 @@ typedef struct { * This is global function. Local functions (and variables) used inside one file * are declared as static and not documented by Doxygen. * - * @param obj Pointer to object. Function operates on this object (not on global - * variables). + * @param thisObj Pointer to object. Function operates on this object (not on + * global variables). * @param argument_2 Description of the argument. * @param argument_2 Description of the argument. * @param argument_4 Description of the argument. * * @return Some value. */ -int32_t foo1(object1_t *obj, +int32_t foo1(object1_t *thisObj, int32_t argument_2, uint16_t argument_3, float32_t argument_4) diff --git a/doc/CANopenNode.png b/doc/CANopenNode.png new file mode 100644 index 0000000000000000000000000000000000000000..4d8855596963d24a9b25d657681418b846f82f33 GIT binary patch literal 12693 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 P00000NkvXXu0mjf<1#d6 literal 0 HcmV?d00001 diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index a2c019d..6f75471 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -1,9 +1,10 @@ Change Log ========== -[newOD] -------------------------- -- [Full ChangeLog](https://github.com/CANopenNode/CANopenNode/compare/master...newOD) +v4.0 - current +-------------- +- [Source Code](https://github.com/CANopenNode/CANopenNode/tree/newOD) +- [Full ChangeLog](https://github.com/CANopenNode/CANopenNode/compare/v2.0-master...newOD) ### Removed - Driver for Linux (socketCAN directory) moved to own repository https://github.com/CANopenNode/CANopenLinux. ### Changed @@ -16,9 +17,11 @@ Change Log - Rewritten PDO. PDO mapped variables are accessed via fast read/write functions. New RPDO event timer (timeout). - CO_Emergency is mostly rewritten. Now is much easier customization. All other objects has been adjusted to newOD, inspected and some parts were redesigned. -[Unreleased master] -------------------------- -- [Full ChangeLog](https://github.com/CANopenNode/CANopenNode/compare/v1.3...master) + +v2.0 - 2020-02-25 +----------------- +- [Source Code](https://github.com/CANopenNode/CANopenNode/tree/v2.0-master) +- [Full ChangeLog](https://github.com/CANopenNode/CANopenNode/compare/v1.3-master...v2.0-master) ### Removed - All drivers removed from this project, except Neuberger-socketCAN for Linux. ### Changed @@ -56,9 +59,11 @@ Change Log - CO_fifo.h/c for fifo data buffer, used with rewritten SDO client, etc. - CANopen gateway-ascii command interface according to CiA309-3 as a microcontroller independent module. It includes NMT master, LSS master and SDO client interface. Interface is non-blocking, it is added to mainline. Example for Linux stdio and socket is included. -[v1.3] - 2020-04-27 -------------------- -- [Full ChangeLog](https://github.com/CANopenNode/CANopenNode/compare/v1.2...v1.3) + +v1.3 - 2020-04-27 +----------------- +- [Source Code](https://github.com/CANopenNode/CANopenNode/tree/v1.3-master) +- [Full ChangeLog](https://github.com/CANopenNode/CANopenNode/compare/v1.2...v1.3-master) ### Changed - License changed to Apache 2.0. - NMT self start functionality (OD object 1F80) implemented to strictly follow standard. Default value for object 1F80 have to be updated in OD editor. See README.md. @@ -68,8 +73,10 @@ Change Log ### Added - CANopen TIME protocol added. -[v1.2] - 2019-10-08 -------------------- + +v1.2 - 2019-10-08 +----------------- +- [Source Code](https://github.com/CANopenNode/CANopenNode/tree/v1.2) - [Full ChangeLog](https://github.com/CANopenNode/CANopenNode/compare/v1.1...v1.2) ### Fixed - Memory barrier implemented for setting/clearing flags for CAN received message. @@ -80,38 +87,38 @@ Change Log - Emergency consumer added. - Callbacks added to Emergency and Heartbeat consumer. -[v1.1] - 2019-10-08 -------------------- + +v1.1 - 2019-10-08 +----------------- +- [Source Code](https://github.com/CANopenNode/CANopenNode/tree/v1.1) - [Full ChangeLog](https://github.com/CANopenNode/CANopenNode/compare/v1.0...v1.1) - Bugfixes. Some non-critical warnings in stack, some formatting warnings in tracing stuff. -[v1.0] - 2017-08-01 -------------------- + +v1.0 - 2017-08-01 +----------------- +- [Source Code](https://github.com/CANopenNode/CANopenNode/tree/v1.0) - [Full ChangeLog](https://github.com/CANopenNode/CANopenNode/compare/v0.5...v1.0) - Stable. -[v0.5] - 2015-10-20 -------------------- + +v0.5 - 2015-10-20 +----------------- +- [Source Code](https://github.com/CANopenNode/CANopenNode/tree/v0.5) - Git repository started on GitHub. -[v0.4] - 2012-02-26 -------------------- + +v0.4 - 2012-02-26 +----------------- +- [Source Code](https://sourceforge.net/p/canopennode/code_complete/ci/master/tree/) - Git repository started on Sourceforge git. -[v0.1] - 2004-06-29 -------------------- + +v0.1 - 2004-06-29 +----------------- +- [Source Code](https://sourceforge.net/projects/canopennode/files/canopennode/CANopenNode-0.80/) - First edition of CANopenNode on SourceForge, files section. (V0.80 on SourceForge). ------ Changelog written according to recommendations from https://keepachangelog.com/ - -[newOD]: https://github.com/CANopenNode/CANopenNode/tree/newOD -[Unreleased master]: https://github.com/CANopenNode/CANopenNode -[v1.3]: https://github.com/CANopenNode/CANopenNode/tree/v1.3 -[v1.2]: https://github.com/CANopenNode/CANopenNode/tree/v1.2 -[v1.1]: https://github.com/CANopenNode/CANopenNode/tree/v1.1 -[v1.0]: https://github.com/CANopenNode/CANopenNode/tree/v1.0 -[v0.5]: https://github.com/CANopenNode/CANopenNode/tree/v0.5 -[v0.4]: https://sourceforge.net/p/canopennode/code_complete/ci/master/tree/ -[v0.1]: https://sourceforge.net/projects/canopennode/files/canopennode/CANopenNode-0.80/ diff --git a/doc/LSSusage.md b/doc/LSSusage.md deleted file mode 100644 index f632a96..0000000 --- a/doc/LSSusage.md +++ /dev/null @@ -1,121 +0,0 @@ -LSS usage -========= - -LSS (Layer settings service) is an extension to CANopen described in CiA DSP 305. The -interface is described in CiA DS 309 3.0.0 (ASCII mapping). -LSS allows the user to change node ID and bitrate, as well as setting the node ID on an -unconfigured node. - -LSS uses the the OD Identity register (0x1018) as an unique value to select a node. Therefore -the LSS address always consists of four 32 bit values. This also means that LSS relies -on this register to actually be unique. (_vendorID_, _productCode_, _revisionNumber_ and -_serialNumber_ must be configured and unique on each device.) - -### Preparation for testing on Linux virtual CAN -LSS can be tested on Linux virtual CAN, similar as in gettingStarted.md. - -1. Open terminal, setup _vcan0_ and _cd_ to CANopenNode directory. -2. Make some unique CANopen devices: - - Edit CO_OD.c, change initialization for identity, for example change line to `/*1018*/ {0x4, 0x1L, 0x2L, 0x3L, 0x4L},` - - `make` - - `mv canopend canopend4` - - Edit CO_OD.c, for example: `/*1018*/ {0x4, 0x1L, 0x2L, 0x3L, 0x5L},` - - `make` - - `mv canopend canopend5` - - Repeat this step and create three further "unique" CANopen devices. -3. Clear default OD storage file. We will use default (empty) storage for all instances: - - `echo "-" > od_storage` -4. Run "master" with command interface and node-id = 1. Note that this device - has enabled both: LSS master and LSS slave. But LSS master does not 'see' own LSS slave. - - `make` - - `./canopend vcan0 -i1 -c "stdio"` -5. Run one CANopen device with node-id=22 in own terminal: - - `./canopend4 vcan0 -i22` -6. Run other unique CANopen devices with unconfigured node-id, each in own terminal: - - `./canopend5 vcan0 -i0xFF` - - `./canopend6 vcan0 -i0xFF` - - `./canopend7 vcan0 -i0xFF` - - `./canopend8 vcan0 -i0xFF` -7. Note that `lss_store` does not work in this example. For it to work, OD storage must be used properly. - -### Typical usage of LSS - - Changing the node ID for a known slave, store the new node ID to eeprom, apply new node ID. - The node currently has the node ID 22. - - help lss - - lss_switch_sel 0x00000001 0x00000002 0x00000003 0x00000004 - lss_set_node 10 - lss_store - lss_switch_glob 0 - 22 reset communication - - Note that the node ID change is not done until reset communication/node. - - - Changing the node ID for a known slave, store the new node ID to eeprom, apply new node ID. - The node currently has an invalid node ID. - - lss_switch_sel 0x00000001 0x00000002 0x00000003 0x00000005 - lss_set_node 11 - lss_store - lss_switch_glob 0 - - Note that the node ID is automatically applied. This can be seen on `candump`. - -### LSS fastscan - - Search for a node via LSS fastscan, store the new node ID to eeprom, apply new node ID - - _lss_fastscan - - [0] 0x00000001 0x00000002 0x00000003 0x00000006 - - lss_set_node 12 - lss_store - lss_switch_glob 0 - - To increase scanning speed, you can use - - _lss_fastscan 25 - - where 25 is the scan step delay in ms. Be aware that the scan will become unreliable when - the delay is set to low. - - We won't configure this node now, reset LSS. Now we have 1+3 nodes operational in our example. - - lss_switch_glob 0 - -### Auto enumerate all nodes - - Auto enumerate all nodes via LSS fastscan. Enumeration automatically begins at node ID 2 - and node ID is automatically stored to eeprom. Like with _lss_fastscan, an optional - parameter can be used to change default delay time. - - lss_allnodes - - # Node-ID 2 assigned to: 0x00000001 0x00000002 0x00000003 0x00000007 - # Node-ID 3 assigned to: 0x00000001 0x00000002 0x00000003 0x00000008 - # Found 2 nodes, search finished. - [0] OK - - - To get further control over the fastscan process, the lss_allnodes command supports - an extended parameter set. - Auto enumerate all nodes via LSS fastscan. Set delay time to 25ms, set enumeration start - to node ID 7, do not store LSS address in eeprom, enumerate only devices with vendor ID - "0x428", ignore product code and software revision, scan for serial number - - lss_allnodes 25 7 0 2 0x428 1 0 1 0 0 0 - - The parameters are as following: - - 25 scan step delay time in ms - - 7 enumeration start - - 0 store node IDs to eeprom; 0 = no, 1 = yes - - 2 vendor ID scan selector; 0 = fastscan, 2 = match value in next parameter - - 0x428 vendor ID to match - - 1 product code scan selector; 0 = fastscan, 1 = ignore, 2 = match value in next parameter - - 0 product code to match (ignored in this example) - - 1 software version scan selector; 0 = fastscan, 1 = ignore, 2 = match value in next parameter - - 0 software version to match (ignored in this example) - - 0 serial number scan selector; 0 = fastscan, 1 = ignore, 2 = match value in next parameter - - 0 serial number to match (not used in this example) - - Note that only unconfigured nodes (those without a valid node ID) will take part in - fastscan! diff --git a/doc/deviceSupport.md b/doc/deviceSupport.md index 94034db..fb33100 100644 --- a/doc/deviceSupport.md +++ b/doc/deviceSupport.md @@ -8,15 +8,16 @@ It is necessary to implement interface to specific hardware. Interface to Linux Note for device driver contributors ----------------------------------- -Most up-to-date implementations of CANopenNode are: socketCAN for Linux, which is part of CANopenNode and [CANopenPIC](https://github.com/CANopenNode/CANopenPIC) for PIC32 microcontroller (bare-metal). Those can be used for reference. There is also an example directory, which doesn't include specific device interface. It should compile on any system and can be used as a template. Device interface is documented in common CO_driver.h file. +Most up-to-date implementations of CANopenNode are: [CANopenLinux](https://github.com/CANopenNode/CANopenLinux) and [CANopenPIC](https://github.com/CANopenNode/CANopenPIC) for PIC32 microcontroller (bare-metal). Those can be used for reference. There is also an example directory, which doesn't include specific device interface. It should compile on any system and can be used as a template. Device interface is documented in common CO_driver.h file. There are many advantages of sharing the base code such as this. For the driver developers, who wish to share and cooperate, I recommend the following approach: 1. Make own git repo for the Device specific demo project on the Github or somewhere. 2. Add https://github.com/CANopenNode/CANopenNode into your project (or at side of your project). For example, include it in your project as a git submodule: `git submodule add https://github.com/CANopenNode/CANopenNode` 3. Add specific driver and other files. -4. Add description of new device into this file (deviceSupport.md) and make a pull request to CANopenNode. Alternatively create an issue for new device on https://github.com/CANopenNode/CANopenNode/issues. -5. Make a demo folder, which contains project files, etc., necessary to run the demo. -6. Write a good README.md file, where you describe your project, specify demo board, tools used, etc. +4. Write a good README.md file, where you describe your project, specify demo board, tools used, etc. +5. Optionally prepare a demoDevice in [CANopenDemo](https://github.com/CANopenNode/CANopenDemo) repository and run the tests. +6. Share your work: add description of new device into this file (deviceSupport.md) and make a pull request to CANopenNode. Alternatively create an issue for new device on https://github.com/CANopenNode/CANopenNode/issues. +7. Offer your work for inclusiun under the CANopenNode project and become its developer. It will increase code quality and functionality. Linux diff --git a/doc/gettingStarted.md b/doc/gettingStarted.md deleted file mode 100644 index 5a4cdbf..0000000 --- a/doc/gettingStarted.md +++ /dev/null @@ -1,192 +0,0 @@ -Getting Started -=============== - -CANopen -------- -Before getting started with CANopenNode you should be familiar with the CANopen. -CANopen is the internationally standardized CAN-based higher-layer protocol for embedded control system. -It is specified by CiA301 (or by EN 50325-4) standard. It can be freely downloaded from https://can-cia.org/groups/specifications/. -Some information about CAN and CANopen can be found on https://can-cia.org/can-knowledge/ website. Very efficient way to get familiar with CANopen is by reading a book, for example [Embedded Networking with CAN and CANopen](https://can-newsletter.org/engineering/engineering-miscellaneous/nr_e_cia_can_books_3-2008_emb_can_pfeiffer_120529). - -CANopen itself is not a typical master/slave protocol. It is more like producer/consumer protocol. It is also possible to operate CANopen network without a master. For example, pre-configured process data objects (PDO) are transmitted from producers. Each PDO may be consumed by multiple nodes. Other useful CANopen functionalities of each CANopen device are also: Heartbeat producer and consumer, Emergency producer, Sync producer or consumer, Time producer or consumer, SDO server (Service data objects - serve variables from Object dictionary), NMT slave (network management - start or stop parts of communication), LSS slave (configuration of Node-Id and Bitrate). - -CANopen network usually has one device with master functionalities for network configuration. It may have additional CANopen functionalities, such as: NMT master, LSS master, SDO client, Emergency consumer. Master functionalities in CANopenNode are implemented with Ascii command line interface according to standard CiA309-3. - - -CANopenNode on Linux --------------------- -CANopenNode should run on any Linux machine. Examples below was tested on Debian based machines, including Ubuntu and Raspberry PI. It is possible to run tests described below without real CAN interface, because Linux kernel already contains virtual CAN interface. -All necessary Linux specific files are included in socketCAN directory of CANopenNode and Makefile is included in base directory. - -Windows or Mac users, who don't have Linux installed, can use [VirtualBox](https://www.virtualbox.org/) and install [Ubuntu](https://ubuntu.com/download/desktop) or similar. - - -### Preparation -We will use Linux command line interface (Terminal) for all examples below. Open the terminal and cd to your working directory. -First install supporting packages: [can-utils](https://github.com/linux-can/can-utils), which is very useful tool for working with CAN interface and [git](https://git-scm.com/), which is recommended for working with repositories. -Then clone [CANopenNode](https://github.com/CANopenNode/CANopenNode) from Github and build the executable program. - - sudo apt-get install git - sudo apt-get install can-utils - git clone https://github.com/CANopenNode/CANopenNode.git - cd CANopenNode - # For update just use 'git pull' here - make - -Now prepare CAN virtual device and run _candump_, which will show all CAN traffic. Use a second terminal: - - sudo modprobe vcan - sudo ip link add dev vcan0 type vcan - sudo ip link set up vcan0 - candump vcan0 - - -### First CANopen device -Go to the first terminal, where we have recently build executable, named _canopend_. -First print help, then run the program with some options. - - ./canopend --help - ./canopend vcan0 -i 4 - -You are now running a fully functional CANopen device on virtual CAN network. It is running in background until you terminate the process (with CTRL+C for example) or it receives a reset message from CAN network. By default process also shows some info messages on terminal, for example changes of NMT state or emergency messages, own and remote. - -On the second terminal you can see some CAN traffic. After _canopend_ startup, first messages are: - - vcan0 704 [1] 00 # Boot-up message. - vcan0 084 [8] 00 50 01 2F 03 00 00 00 # Emergency message. - -Boot-up message of node 4 have CAN-ID equal to 0x704. CAN-ID is 11-bit standard CAN identifier. - -Also, both, first and second terminal shows, that there is an Emergency message after the boot-up. Also Heartbeat messages shows NMT pre-operational state. - -The easiest way to find the reason of the emergency message is to check the byte 4 (errorBit). It has value of 0x2F. Go to CANopenNode source code and open the file "301/CO_Emergency.h", section "Error status bits". 0x2F means "CO_EM_NON_VOLATILE_MEMORY", which is generic, critical error with access to non volatile device memory. - -This byte is CANopenNode specific. You can observe also first two bytes, which shows standard error code (0x5000 - Device Hardware) or third byte, which shows error register. If error register is different than zero, then node may be prohibited to enter operational and PDOs can not be exchanged with it. - -You can follow the reason of the problem inside the source code. However, data storage was not yet initialized, files are missing. CANopen device works, but NMT operational state is not possible. Data storage files on running new device can be generated by CANopen gateway command `4 write 0x1010 1 u32 0x65766173` or `4 write 0x1011 1 u32 0x64616F6C`. Or files can be generated manually with the Linux commands below. - -Go to the first terminal, terminate the application with CTRL+C, add files and run _canopend_ again. - - echo "-" > lss.persist - echo "-" > od_comm.persist - ./canopend vcan0 -i 4 - -Second terminal now shows new boot-up message without emergency. - - vcan0 704 [1] 00 - - -### Second CANopen device -Open the third terminal and cd to the same directory as is in the first terminal. First generate data storage files with prefix, so data won't mix. Then start second instance of _canopend_ with NodeID = 1 and prefix for data storage. Enable command interface on standard IO (terminal). - - echo "-" > node1_lss.persist - echo "-" > node1_od_comm.persist - ./canopend vcan0 -i1 -s "node1_" -c "stdio" - -Now you should see in second terminal (_candump_) boot-up message of new CANopen device. - - -### CANopen command interface -Second instance of _canopend_ was started with command interface enabled. This is CANopen gateway interface with ascii mapping, as specified in standard CiA309-3. This enables usage of CANopen master functionalities via basic terminal. Go to third terminal, type "help" and press enter to see its functionalities. - - help - help datatype - -#### SDO client -For example read Heartbeat producer parameter on CANopen device with ID=4. Parameter is located at index 0x1017, subindex 0, it is 16-bit unsigned integer. - - [1] 4 read 0x1017 0 u16 - -You should see the response, which says that Heartbeats are disabled: - - [1] 0 - -In CAN dump you can see some SDO communication. SDO communication can be quite complicated, if observing on _candump_, especially if larger data is split between multiple segments. However, there is no need to know the details, everything should work correctly in the background. Details about SDO communication can be found in CiA301 standard and partly also in 301/CO_SDOserver.h file, description of CO_SDO_state_t enumerator. - - [2] 4 write 0x1017 0 u16 5000 - [2] OK #response - -In _candump_ you will notice, that heartbeats from node 4 are coming in 5 second interval now. Heartbeat message is similar to boot-up message. 0x7F in heartbeat message means, that node is in NMT pre-operational state. 0x05 means operational and 0x04 means stopped. - -You can do the same also for node 1, but you won't see SDO messages on _candump_, because data are written into itself directly. In "stdio" you can omit sequence number, to make typing easier. - - 1 w 0x1017 0 u16 2500 - [0] OK - -Now store Object dictionary on node-ID 4, so it will preserve variables on next start of the program. - - 4 w 0x1010 1 u32 0x65766173 - [0] OK - -0x65766173 are ascii characters for 's', 'a', 'v', 'e', so it is easier to simply write visible string instead of unsigned 32. This is equivalent to the above command: - - 4 w 0x1010 1 vs save - [0] OK - -More details about Object dictionary variables can be found in CiA301 standard or in example/DS301_profile.md file. - - -#### NMT master -If node is operational (started), it can exchange all objects, including PDO, SDO, etc. In NMT pre-operational, PDOs are disabled, SDOs works. In stopped only NMT messages are accepted. Try following commands and observe _candump_. - - set node 4 - [0] OK - - start - [0] OK - - preop - [0] OK - - stop - [0] OK - - r 0x1017 0 i16 - [0] ERROR: 0x05040000 #SDO protocol timed out. - - reset communication - [0] OK - - 0 start - [0] OK - - reset node - [0] OK - - 1 reset communication - [0] OK - - 1 reset node - [0] OK - - -#### Other communication channels -We used simple stdio for command interface. In Linux also sockets can be used, either local or tcp. See `./canopend --help` for options. Simple Linux tool for establishing socket connection is _netcat_ or _nc_. For example `nc -U /tmp/CO_command_socket` for local socket or `nc 60000` for tcp socket. There are also some tools from [CANopenSocket](https://github.com/CANopenNode/CANopenSocket) project. - -Please be careful when exposing your CANopen network to the outside world, it is your responsibility, if something dangerous happen. - - -### Next steps -Assigning Node-ID or CAN bitrate, which support LSS configuration, is described in *LSSusage.md*. - -Further CANopenNode related tools and examples are available in [CANopenSocket](https://github.com/CANopenNode/CANopenSocket). Especially interesting is [basicDevice](https://github.com/CANopenNode/CANopenSocket/examples/basicDevice) - -Custom CANopen device can be created based on own Object Dictionary, see README.md. There are also many very useful and high quality specifications for different [device profiles](http://www.can-cia.org/standardization/specifications/), some of them are public and free to download, for example CiA401. - -For own CANopen device with own microcontroller, see *deviceSupport.md*. There is a bare-metal demo for [PIC microcontrollers](https://github.com/CANopenNode/CANopenPIC), most complete example is for PIC32. - -Another interesting tool is [CANopen for Python](https://github.com/christiansandberg/canopen). - -Examples here worked in virtual CAN interface, for simplicity. Virtual CAN runs inside Linux kernel only, it does not have much practical usability. If one has real CAN network configuration, then above examples are suitable also for this network, if Linux machine is connected to it and CAN interface is properly configured. When connecting your devices to real CAN network, make sure, you have at least two devices communicating, connected with ground and pair of wires, terminated with two 120ohm resistors, correct baudrate, etc. - -Accessing real CANopen devices is the same as described above for virtual CAN interface. Some tested USB to CAN interfaces, which are native in Linux kernel are: - - Simple serial [USBtin](http://www.fischl.de/usbtin/) - Start with (-s5=250kbps): `sudo slcand -f -o -c -s5 /dev/ttyACM0 can0; sudo ip link set up can0` - - [EMS CPC-USB](https://www.ems-wuensche.com/?post_type=product&p=746) or [PCAN-USB FD](http://www.peak-system.com/PCAN-USB-FD.365.0.html?&L=1) - Start with: `sudo ip link set up can0 type can bitrate 250000` - - You can get the idea of other supported CAN interfaces in [Linux kernel source](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/net/can) (Kconfig files). - - Raspberry PI or similar has CAN capes available. - -Examples here run in Linux, for simplicity. However, real usability of CANopen network is, when simple, microcontroller based devices are connected together with or without more advanced commander device. CANopenNode is basically written for simple microcontrollers and also has more advanced commander features, like above used CANopen gateway with ascii command interface. - -Now you can enter the big world of [CANopen devices](http://can-newsletter.org/hardware). - -Here we played with virtual CAN interface and result shown as pixels on screen. If you connect a real CAN interface to your computer, things may become dangerous. Keep control and safety on your machines! diff --git a/doc/traceUsage.md b/doc/traceUsage.md index 63992a4..ab3ecb6 100644 --- a/doc/traceUsage.md +++ b/doc/traceUsage.md @@ -1,6 +1,8 @@ Trace usage =========== +**TRACE DOES NOT WORK IN THE LAST VERSION** + CANopenNode includes optional trace functionality (non-standard). It monitors choosen variables from Object Dictionary. On change of state of variable it makes a record with timestamp into circular buffer. String with points can later diff --git a/example/DS301_profile.md b/example/DS301_profile.md index b3987c2..df6ca40 100644 --- a/example/DS301_profile.md +++ b/example/DS301_profile.md @@ -15,15 +15,11 @@ CANopen device documentation This file was automatically generated with [libedssharp](https://github.com/robincornelius/libedssharp) Object Dictionary Editor v0.8-114-gc3a898f -* [Device Information](#device-information) -* [PDO Mapping](#pdo-mapping) -* [Communication Specific Parameters](#communication-specific-parameters) -* [Manufacturer Specific Parameters](#manufacturer-specific-parameters) -* [Device Profile Specific Parameters](#device-profile-specific-parameters) +[TOC] -Device Information {#device-information} ----------------------------------------- +Device Information +------------------ | | | | ------------ | ------------------------------ | | Vendor Name | | @@ -48,11 +44,11 @@ Device Information {#device-information} * [ ] auto -PDO Mapping {#pdo-mapping} --------------------------- +PDO Mapping +----------- -Communication Specific Parameters {#communication-specific-parameters} ----------------------------------------------------------------------- +Communication Specific Parameters +--------------------------------- ### 0x1000 - Device type | Object Type | Count Label | Storage Group | diff --git a/extra/CO_trace.h b/extra/CO_trace.h index 8dc632b..a2e5ae5 100644 --- a/extra/CO_trace.h +++ b/extra/CO_trace.h @@ -42,11 +42,10 @@ extern "C" { /** * @defgroup CO_trace Trace - * @ingroup CO_CANopen_extra - * @{ - * * CANopen trace object for recording variables over time. * + * @ingroup CO_CANopen_extra + * @{ * In embedded systems there is often a need to monitor some variables over time. * Results are then displayed on graph, similar as in oscilloscope. * diff --git a/storage/CO_storage.c b/storage/CO_storage.c index b69f172..fde1999 100644 --- a/storage/CO_storage.c +++ b/storage/CO_storage.c @@ -1,5 +1,5 @@ /* - * CANopen data storage object + * CANopen data storage base object * * @file CO_storage.c * @author Janez Paternoster diff --git a/storage/CO_storage.h b/storage/CO_storage.h index 36b4d8f..f338e9d 100644 --- a/storage/CO_storage.h +++ b/storage/CO_storage.h @@ -1,5 +1,5 @@ /** - * CANopen data storage object + * CANopen data storage base object * * @file CO_storage.h * @ingroup CO_storage @@ -42,6 +42,8 @@ extern "C" { /** * @defgroup CO_storage Data storage base + * Base module for Data storage. + * * @ingroup CO_CANopen_storage * @{ * diff --git a/storage/CO_storageEeprom.h b/storage/CO_storageEeprom.h index dcb3de1..dc8b180 100644 --- a/storage/CO_storageEeprom.h +++ b/storage/CO_storageEeprom.h @@ -36,6 +36,8 @@ extern "C" { /** * @defgroup CO_storage_eeprom Data storage in eeprom + * Eeprom specific data storage functions. + * * @ingroup CO_CANopen_storage * @{ *