I have a system with multiple subsystems communicating with CANOpen. There is a main unit with a screen (for men-machine interface and stuff) and sub-units for minor operations(like sample button status, manage power, take measurements...).
We defined a CANOpen based communication protocol for this system. Subsystems share their conditions periodically with TPDO messages and do stuff according to main unit's commands sent with RPDO messages. And also some NMTs are in use too.
So I've been asked to add a new command to this protocol, zeroize. This command shall be sent broadcast and it shall cause everybody to delete softwares. What is the right way to do this?
Maybe I can use a RPDO? Are we allowed to define new NMT commands in CANopen? Maybe I can do it with NMT but by using a new commandt hat is not in use already?
Thanks in advance
Ip.
It is a bit confusing what you mean with TPDO and RPDO since the main unit's TPDO is going to be the peripheral units' RPDO and vice versa. But yes, the correct way to send out some custom broadcast message would be with a PDO.
Although, depending on what you mean with "delete software", CANopen might provide a mean for it. There are the save (OD 1010h) and load (OD 1011h) registers in the object dictionary. Save is to be used for the purpose of storing all CANopen communication (PDO configuration, mapping etc) in non-volatile memory. And load is used to restore CANopen parameters to factory defaults. These should however not be used to save/load application-specific settings.
You are not allowed to define new NMT commands.
Objects 1010h and 1011h can be used to reset the values in the object dictionary. If you really want to delete the software, the firmware upgrade protocol from CiA 302-3 might help. Writing 00h (Stop program) followed by 03h (Clear program) to object 1F51h sub-index 1 on the slave will delete the application. Whether it's actually "zeroed out" depends on the implementation. You'll need two SDO requests per slave for this though. The standard specifies that object 1F51h cannot be PDO mapped. Although that requirement may not be enforced for your devices, in which case you could achieve broadcast "zeroing" with two PDOs.
Related
I am working on CANopen architecture and had three questions:
1- When the 'synchronous window' is closed until the next SYNC message, should we send the SDO message? Can we not send a message during this period?
2- Is it possible not to send the PDO message during the simultaneous window?
3- What is the answer that the slaves give in the SYNC message?
Disclaimer: I don't have exact answers but I just wanted to share my assumptions & thoughts.
CiA 301 doesn't mention the relation between synchronous window and SDOs. In normal operation after the initial configuration, one may assume that SDOs aren't present on the system, or at least they are rare compared to PDOs. Although not strictly necessary, SDOs are generally initiated by a device which has the master role, and that device also produces the SYNC messages (again, it's not strictly necessary but it's the usual/common implementation). So, the master device may adjust the timing of SDO requests according to the synchronous window.
Here is a quote from CiA 301:
If the synchronous window length expires all synchronous TPDOs may be
discarded and an EMCY message may be transmitted; all synchronous
RPDOs may be discarded until the next SYNC message is received.
Synchronous RPDO processing is resumed with the next SYNC message.
CiA 301 uses the word "may" (see the quote above). So I'm not sure if it's mandatory or not. In my opinion, it makes sense to follow the advice and abort synchronous TPDO transmissions after the synchronous window and send an EMCY message. Event-driven (non-synchronous) TPDOs can be sent within or after the synchronous window.
There is no direct response to SYNC messages. On SYNC reception, SYNC consumers (slaves) sample their inputs, drive their outputs according to the previous RPDOs, and start transmitting their TPDOs containing the previous samples (or the current ones? I'm not sure about this).
Synchronous windows are for specific PDO synchronization only. For hard real-time systems, data might be required to arrive within certain fixed time intervals - not too early, not too late. That is, it acts as a real-time deadline. If such features are enabled, you need to take that in consideration when doing the specific CANopen bus implementation.
For example if some SDO communication would occupy the bus so that the PDO can't meet its time window, that would be a problem. But this is easily solved by giving the PDO a lower COBID than the SDO, which should already be the case in most default device profile setups like "DS401 GPIO module". Other than that, you would have to make sure there is no ridiculous bus loads or that nodes hang up or get busy doing other things.
In systems with hard real-time requirements you probably don't want to allow any SDO communication during operational mode to begin with.
What is the answer that the slaves give in the SYNC message?
That question doesn't make any sense. You need to study what the SYNC message does and what it is for.
I'm wondering if this is possible to setup a timeout for receiving data over USB interface in STM32 microcontrollers. Such approach is possible for example in UART connection (please refer to AN3109, section 2. Receive DMA timeout).
I can't find anything similar related to USB interface. What's more, it is said that DMA for USB should be enabled only if really necessary because data transfer shall be aligned to 32-bit word.
You have a receive call back function (if you use the HAL) in your ...._if.c file. Copy reived chars to the buffer. Implement timeout there.
What you refer to in case of UART is either DMA receive timeout as you've said or (when not using DMA) an IDLE interrupt. I'm not aware of such thing coming "out of the box" for USB CDC - you'd have to implement this timeout yourself, which shouldn't be too hard. Have a timer (hardware of software) that you re-trigger every time you receive data. Set its period to the timeout value of your choice and do protocol parsing after timeout elapses.
If I had to add anything - these kind of problems (not knowing how many bytes to receive) are typically solved at the protocol level. Assuming binary protocol, one way of achieving this is having frame start and end bytes which never occur in data (and if they do - you escape them) in which case you receive everything starting after "start byte" until you reveive "end byte". Yet another way is having a "start byte" and a field indicating how many bytes there are to receive. All of it should of course be checksumed in some way.
Having said that, if you have an option to change the protocol, you really should do so. Relying on timings in your communication, especially on such low level only invites problems and headaches in the long run. You introduce tight coupling between your protocol layer and interface layer. This is going to backfire on you every time you decide to use a different interface, as you'll have to re-invent the same thing again. Not to mention how painful it's going to be when you decide to move to TCP/IP with all its greatness - network jitter, dropped packets etc.
I would like to use dbus to signal other instances of the same family of applications.
It seems that to issue a signal I must execute a g_bus_own_name, emit the signal when the name is acquired, then g_bus_unown_name.
This seems like a bit of palava just to send a signal.
When the name is acquired, another instance of the application will hang waiting for this instance to 'unown' the name.
The deprecated way of dbus_message_new_signal/dbus_connection_send was much more straight forward.
Is there a simpler way to send the signal (without owning the name).
Yes, as Michael K says, use g_dbus_connection_emit_signal(). You only have to own a well-known name if you want other users of the bus to be able to address your application by that well-known name, rather than a unique name which changes every time you connect to the bus.
I will use CANOpen in linux. In kernel, linux has socketcan and i have some questions for further implementation.
1-) How object dictionary looks like, is it a header file or EDS file?
2-) Do i need to use object dictionary for pdo and sdo configurations?
3-) Should i implement my custom canopen library which implements only required some protocols or use a library like canfestival which implements almost all protocols and object dictionary?
1) The object dictionary defines a set of objects where data can be stored on a CANopen node. Objects in the object dictionary can be read and written from the CAN bus using the SDO protocol by giving an object index and sub-index. They can also be read and written from the local application on the CANopen node. You can say the object dictionary forms the API for accessing the CANopen node from other CANopen nodes.
The EDS file contains a list of all objects present in a specific model of CANopen node, including data type, default value, min and max values and some attributes. This helps tools communicate with the CANopen node.
2) Configuration is done over the CAN bus using the SDO protocol to write to the object dictionary of the CANopen node.
3) If you develop a commercial product you probably want to use a commercial CANopen stack to support the full protocol. (One example is the Kvaser CANopen Stack which we maintain, but there are many others to choose from)
If your projects licensing policy allows it you can use one of the open source CANopen stacks. CANFestival and CANopenNode comes to my mind, but there's others too.
But if you just need minimal functionality you can also code the bare minimum from the specification. An NMT state machine, read only SDO expedited transfer, an object dictionary with the few mandatory objects and hard coded PDOs might even give you a standard compliant minimalistic node.
The following objects are mandatory in CiA 301
0x1000 Device Type (Read Only)
0x1001 Error Register (Read Only)
0x1017 Producer Heartbeat Time (Const)
0x1018 Identity Object (Read Only)
In addition you need Communication Parameters and Mapping parameters for
every PDO, but these are allowed to be constants.
If you want to go a step further you might be able to pre-configure all other nodes on the network to auto start, then just send and receive fixed PDOs that the other nodes are programmed to recognize. This is not standard compliant, but might work if you do a quick hack to use in your lab.
I did this for a prototype once, just a fixed PDO and heartbeat, then switching over to a commercial stack for the final product.
My experience in using canopen of canfestival:
1)it is a header and a source file
2)yes ,you should
Object dictionary for each node define the sdo and pdo specification of that and its variable and callback for them, it is automatically done by objectdictgen in canfestival
3)some drivers are written similar to serial , tcp ,... but if you have a specific protocol you can write your own driver
The OD has a form of electronic datasheet, device configuration file or source files
yes
provide your own library could be very hard, error-prone and time-consuming, I will definitelly recommend to use existing CANOpen libraries.
I have created a video explaning basics of OD - please look here https://youtu.be/dOWHLk5QwOI
I really like the message passing primitives that D implements. I have only seen examples of message passing within a program though. Is there support for distributing the messages over e.g. a network?
The message passing functions are in std.concurrency, which only deals with threads. So, the type of message passing used to pass messages between threads is for threads only. There is no RMI or anything like that in Phobos. That's not to say that we'll never get something like that in Phobos (stuff is being added to Phobos all the time), but it doesn't exist right now.
There is, however, the std.socket module which deals with talking to sockets, which is obviously network-related. I haven't used it myself, but it looks like it sends and receives void[]. So, it's not as nice as sending immutable objects around like you do with std.concurrency, but it does allow you to do network communication via sockets and presumably in a much nicer manner than if you were using C calls directly.
Seems that this has been considered. From the Phobos documentation (found it through Jonathan M Davis answer)
This is a low-level messaging API upon
which more structured or restrictive
APIs may be built. The general idea is
that every messageable entity is
represented by a common handle type
(called a Cid in this implementation),
which allows messages to be sent to
in-process threads, on-host processes,
and foreign-host processes using the
same interface. This is an important
aspect of scalability because it
allows the components of a program to
be spread across available resources
with few to no changes to the actual
implementation.
Right now, only in-process threads are
supported and referenced by a more
specialized handle called a Tid. It is
effectively a subclass of Cid, with
additional features specific to
in-process messaging.