WARNING: This document is work in progress.

1. Introduction

This document describes the NoCAN wire-level protocol as implemented in the NoCAN project.

NoCAN is a protocol that is built on top of CAN bus. It is designed to make communications between micro-controller based nodes simple and cheap. All nodes are connected together through a common shared bus. A special node called the network manager, is also connected to the shared bus and takes care of managing nodes in the network. The network manager typically runs on a PC or Raspberry Pi and communicates with the network through a specific interface (i.e. the Omzlo PiMaster HAT controller).

NoCAN is designed to optionally work without a network manager with degraded functionalities but this mode of operation is not currently described in this document.

NoCAN offers the following features:

  • A publish/subscribe messaging system (pub/sub).
  • The ability to send messages of up to 64 bytes (CAN bus messages are only 8 bytes max).
  • Provisions for automated address assigned to each node in the network.
  • Specialised messaging for micro-controller firmware update and bootloader control.

The publish/subscribe messaging system is based on the concept of channels. A channel has an identifier channel_id and a textual description is the form of an ascii string of up to 64 bytes.

When a node wants to receive data, it subscribes to a channel by performing the following operations:

  1. The node performs a channel lookup, providing the name of the channel it is interested in (e.g. "garden/temperature")
  2. The node manager responds with a channel_id corresponding to that channel (or an error code if the channel does not exist).
  3. The node configures its internal CAN bus filters to accept all messages with the specific channel_id.
  4. The node then waits for messages

When a node wants to send data, it publishes to a channel by performing the following operations:

  1. The node performs a channel registration, providing the textual name of the channel it wants to publish to (e.g. "garden/temperature")
  2. The node manager responds with a channel_id corresponding to that channel.
  3. The node then sends messages with a channel identifier set to the channel_id provided in step 2.

All the steps above are supported by the NoCAN protocol though system messages and publish messages, as detailed in this document.

The rest of this specification is organized as follows:

  • Section 2 describes how NoCAN uses CAN bus frames.
  • Section 3 lists common messaging sequences used in NoCAN.
  • Sections 4 and 5 specify all messages used in NoCAN.

2. CAN bus frame structure used in Nocan

Nocan uses CAN extended data frames exclusively. Such frames are composed of 3 main parts:

  • eid: A 29 bit extended identifier,
  • dlc: A data length code with a value between 0 and 8,
  • data: 0 to 8 bytes of data, depending on the length specfied in the dlc.

While CAN frames are limited to 8 bytes of data, NoCAN allows creating messages of up to 64 bytes by combining up to 8 CAN frames together, as described below.

The 29 bits of the eid are used to carry both node address information and protocol parameters.

There are essentially two types of NoCAN messages:

  1. System messages: these messages are used to manage nodes and channel subscriptions. The eid notably contains a function identifier.
  2. Publish messages: these messages are used to send a message on a specific channel. The eid notably contains a channel identifier.

System messages and publish messages are distinguished by the 11th bit of the eid as described below.

2.1 The eid of a system CAN frame

The 29-bit eid of a system message has the following structure:

Position Length Field Description
0 1 first_packet_flag When set to 1, indicates that this is the first packet in a message.
1 7 node_id Node sending the message (0 to 127). 0 has a special meaning.
8 1 last_packet_flag When set to 1, indicates that this is the last packet in a message.
1 1 reserved always 0
10 1 sys_flag When set to 1 indicates that this is a "system" message
11 2 reserved always 0
13 8 function Function identifier (currently there are 27 function identifiers).
21 8 parameter Optional parameter, function dependent.

The flags first_packet_flag and last_packet_flag are used to construct NoCAN messages that are composed of 1 to 8 CAN frames:

  • The first frame in a message will have the first_packet_flag set to 1.
  • The last frame in a message will have the last_packet_flag set to 1.
  • Any intermediate frame that is neither the last nor the first will have both flags set to 0.
  • Any message that is composed of a single CAN frame will have both flags set to 1.

The node_id indicates the address of the node that has sent the message.

The value 0 has a special meaning when used as a node_id and can only be used:

  • By the node manager to send a message.
  • By an ordinary node when it sends the NOCAN_SYS_ADDRESS_REQUEST system message

In all other cases, nodes should never use node_id=0

The flag sys_flag is always set to 1 in system messages.

The function field describes a request or response to a request, most frequently directed to the node manager. The meaning of the function field is described in detail in a dedicated section of this document.

The parameter field complements the function field in some situations or is used to carry a response code (by convention 0 means success, while 255 indicates a failure).

2.2 The eid of a publish CAN frame

The 29-bit eid of a publish message has the following structure:

Position Length Field Description
0 1 first_packet_flag When set to 1, indicates that this is the first packet in a message.
1 7 node_id Node sending the message (0 to 127). 0 has a special meaning.
8 1 last_packet_flag When set to 1, indicates that this is the last packet in a message.
1 1 reserved always 0
10 1 sys_flag When set to 0 indicates that this is a "publish" message
11 2 reserved always 0
13 16 channel_id Channel identifier (0 to 65534). The value 65535 indicates an error.

The flags first_packet_flag and last_packet_flag are used to construct Nocan messages that are composed of 1 to 8 CAN frames, in the same way as they are used for system messages (see 2.1).

The node_id indicates the address of the node that publishes the message.

The channel_id field indicates the channel to which the message is published.

2.3 Data types and conventions

A node_id represents a value between 0 and 127, where 0 has a special meaning described previously.

A channel_id represents a value between 0 and 65534. The value 65535 is reserved to indicate an error.

A Nocan message can be composed of 1 to 8 CAN bus frames:

  • This limit is enforced by software.
  • Except for NOCAN_SYS_CHANNEL_REGISTER and NOCAN_SYS_CHANNEL_LOOKUP system messages (see section 5), which can contain up to 8 frames, all system messages are composed of 1 CAN frame.
  • All CAN frames in a system message are expected to have the same value for the function and node_id fields.
  • All CAN frames in a publish message are expected to have the same value for the channel_id and node_id fields.

The number of channels a single node can subscribe to may be limited by software/hardware constraints. On the Omzlo One, each node can subscribe to up to 12 channels simultaneously.

3. Nocan protocol messaging sequences

This section presents a high-level view of the most common protocol sequences used in Nocan. Individual messages are detailed in section 4 and 5.

3.1 Address allocation

When a node wants to obtain a unique address (i.e. a node_id), the following exchange takes place:

  1. The node sends a NOCAN_SYS_ADDRESS_REQUEST message with a unique 8-byte device identifier.
  2. The node manager responds with a NOCAN_SYS_ADDRESS_CONFIGURE message with the same unique 8 byte device identifier and a parameter value set to the new address allocated to the node.
  3. The node responds with NOCAN_SYS_ADDRESS_CONFIGURE_ACK.

Note that in steps 1 and 2, node_id is set to 0.

3.2 Registering a channel

When a node wants to create a new channel to publish data, the following exchanges take place:

  1. The node sends a NOCAN_SYS_CHANNEL_REGISTER message containing a textual description of the channel (e.g. "garden/temperature").
  2. The node manager responds with a NOCAN_SYS_CHANNEL_REGISTER_ACK message containing the channel_id corresponding to the channel name provided in step 1.

Note that if the channel defined in step 1 already exists, the node manager will not create a new channel_id but will return the existing one. A node can also perform a channel lookup using (NOCAN_SYS_CHANNEL_LOOKUP) and proceed to step 1 above only if the lookup fails (returning param=255).

3.3 Subscribing to a channel

When a node wants to subscribe to a channel, the following actions take place:

  1. The node sends a NOCAN_SYS_CHANNEL_LOOKUP message containing a textual description of the channel (e.g. "garden/temperature").
  2. The node manager responds with a NOCAN_SYS_CHANNEL_LOOKUP_ACK message containing the channel_id corresponding to the channel name provided in step 1.
  3. The node sends an advisory NOCAN_SYS_CHANNEL_SUBSCRIBE message, specifying the channel_id it wants to subscribe to.
  4. The node configures its CAN bus driver filters to accept 'publish' messages with an eid that contains channel_id.

In step 2, if the channel has not been previously registered (see 3.2), an error is returned by the node manager.

3.4 Publishing to a channel

When a node wants to publish data, the following exchanges will take place:

  1. The node sends a NOCAN_SYS_CHANNEL_LOOKUP message containing a textual description of the channel (e.g. "garden/temperature").
  2. The node manager responds with a NOCAN_SYS_CHANNEL_LOOKUP_ACK message containing the channel_id corresponding to the channel name provided in step 1.
  3. The node sends a "publish" message with the data it wants to publish. That message will use the channel_id obtained in step 2.

Step 1 and 2 only need to be performed once. After that step 3 can be repeated indefinitely.

3.5 Rebooting a node

When the node manager wants to reboot a node, it sends a NOCAN_SYS_NODE_BOOT_REQUEST message to the target node.

On the CANZERO this message is captured by the NoCAN driver IC (STM32F042), which in turn performs a hard reset on the main IC (the SAMD21). This is designed to allow rebooting the main IC even if it is "stuck".

3.6 Node firmware upgrade over the network

When the node manager wants to update the flash or eeprom memory of a node, the following exchanges take place:

  1. The node manager reboots the node (see 3.5).
  2. The node starts in "bootloader mode". The node requests and obtains an address (see 3.1).
  3. The node sends a NOCAN_SYS_NODE_BOOT_ACK message to signify that it is in "bootloader mode".
  4. The node manager sends a NOCAN_SYS_BOOTLOADER_SET_ADDRESS with the memory type and address it wants to update.
  5. The node responds with a NOCAN_SYS_BOOTLOADER_SET_ADDRESS_ACK.
  6. The node manager sends a NOCAN_SYS_BOOTLOADER_WRITE message with up to 8 bytes of data to write, and parameter set 0.
  7. The node responds with a NOCAN_SYS_BOOTLOADER_WRITE_ACK, stores the data in a temporary location.
  8. If there is still data to write in the memory block, we go back to step 6, otherwise, we continue to step 9.
  9. The node manager sends a NOCAN_SYS_BOOTLOADER_WRITE with parameter set to 1.
  10. The node updates the memory block and responds with a NOCAN_SYS_BOOTLOADER_WRITE_ACK.
  11. If more memory needs to be updated, we go back to step 4, otherwise, we stop.

When updating flash memory, the steps 4 to 10 need to be repeated for each "page" of memory (one page is 128 bytes for the Atmega328pb).

4. NoCAN publish message

Publish messages have a specific eid described in 2.2 and are composed of 1 to 8 CAN frames. Publish messages are not acknowledged.

5. NoCAN system messages

This section describes system messages used in NoCAN, based on the value of the function field.

5.1 NOCAN_SYS_ADDRESS_REQUEST (1)

STRUCTURE

node_id function parameter DLC data
0 1 - 8 8 byte unique device identifier

DESCRIPTION

The node sends this message with an 8-byte unique device identifier to request the attribution of an address (node_id).

In the Omzlo One, this unique device identifier is derived from the serial number of the STM32F042 chip used as a CAN bus interface.

The node manager responds with a NOCAN_SYS_ADDRESS_CONFIGURE message containing the assigned node_id.

5.2 NOCAN_SYS_ADDRESS_CONFIGURE (2)

STRUCTURE

node_id function parameter DLC data
0 1 1 to 127 or 255 8 8 byte unique device identifier

Parameter: 1 to 127 as the new node_id assigned to the node or 255 (0xFF) for failure.

DESCRIPTION

This message attributes the value defined in parameter as an address (i.e. a node_id) to the node that has the 8-byte unique device identifier provided in data.

This message is sent as a response to a NOCAN_SYS_ADDRESS_CONFIGURE message.

The node that receives this message should respond with a NOCAN_SYS_ADDRESS_CONFIGURE_ACK message to finalize the node identifier attribution.

5.3 NOCAN_SYS_ADDRESS_CONFIGURE_ACK (3)

STRUCTURE

node_id function parameter DLC data
id > 0 3 - 0 -

DESCRIPTION

This message is sent by a node to finalizes the attribution of an address to itself.

This message is sent as a response to a NOCAN_SYS_ADDRESS_CONFIGURE message.

5.4 NOCAN_SYS_ADDRESS_LOOKUP (4)

Not implemented.

5.5 NOCAN_SYS_ADDRESS_LOOKUP_ACK (5)

Not implemented.

5.6 NOCAN_SYS_NODE_BOOT_REQUEST (6)

STRUCTURE

node_id function parameter DLC data
id > 0 6 1 0 -

DESCRIPTION

Causes the node identified by node_id to reboot.

On the Omzlo One, this message causes the STM32F042 to lower the reset pin of the Atmega328pb, causing a hardware reset.

NOCAN_SYS_NODE_BOOT_ACK (7)

STRUCTURE

node_id function parameter DLC data
id > 0 7 - 0 -

DESCRIPTION

This message is sent by the bootloader once it has received an address (see NOCAN_SYS_ADDRESS_CONFIGURE and other related messages), to indicate that it is ready to accept bootloader commands (e.g. firmware update).

On the Omzlo One, the bootloader is active for 10 seconds approximately before automatically booting to the main application.

NOCAN_SYS_NODE_PING (8)

STRUCTURE

node_id function parameter DLC data
id > 0 8 - 0 to 8 0 to 8 bytes

DESCRIPTION

When a node receives this message it is expected to respond with NOCAN_SYS_NODE_PING_ACK message that contains a copy of the data provided here.

On the Omzlo CANZERO this message is directly processed by the network driver IC (STM32F042) and is not passed along to the main microcontroller (SAMD21G18).

NOCAN_SYS_NODE_PING_ACK (9)

STRUCTURE

node_id function parameter DLC data
id > 0 9 - 0 to 8 0 to 8 bytes

DESCRIPTION

This message is provided in response to a NOCAN_SYS_NODE_PING message.

NOCAN_SYS_CHANNEL_REGISTER (10)

STRUCTURE

node_id function parameter DLC data
id > 0 10 - 1-64 1 to 64 bytes, representing an ascii channel name

DESCRIPTION

This message is sent by a node to register a channel with the name provided in data.

The node manager will respond with a NOCAN_SYS_CHANNEL_REGISTER_ACK containing the channel_id of the channel. If a channel with a similar name has already been registered with a channel_id that value will be provided in response.

Note that the channel name is not 0 terminated as strings are in the C language.

NOCAN_SYS_CHANNEL_REGISTER_ACK (11)

STRUCTURE

node_id function parameter DLC data
id > 0 11 0 or 255 2 A 16 bit channel_id (MSB first)

DESCRIPTION

This message is provided by the node manager to a node in reponse to a NOCAN_SYS_CHANNEL_REGISTER message.

Parameter is 0 in case of success and 255 in case of failure. The data contains a 16-bit channel id in case of success.

NOCAN_SYS_CHANNEL_UNREGISTER (12)

STRUCTURE

node_id function parameter DLC data
id > 0 12 - 2 A 16 bit channel_id (MSB first)

DESCRIPTION

This message is sent by a node to unregister the channel identified by the 16 bit channel_id.

If there are no other nodes that have registered channel_id, the channel manager will release internal resources associated with that channel.

The node manager will respond with a NOCAN_SYS_CHANNEL_UNREGISTER_ACK message.

NOCAN_SYS_CHANNEL_UNREGISTER_ACK (13)

STRUCTURE

node_id function parameter DLC data
id > 0 13 0 or 255 0 -

DESCRIPTION

This message is sent by the node manager in response to a NOCAN_SYS_CHANNEL_UNREGISTER message.

Parameter is 0 in case of success and 255 in case of failure.

NOCAN_SYS_CHANNEL_SUBSCRIBE (14)

STRUCTURE

node_id function parameter DLC data
id > 0 14 - 2 A 16 bit channel_id (MSB first)

DESCRIPTION

This message is sent by a node to signal that it is subscribing to the channel identified by channel_id.

This message is only advisory and is not acknowledged by the node manager.

NOCAN_SYS_CHANNEL_UNSUBSCRIBE (15)

STRUCTURE

node_id function parameter DLC data
id > 0 15 - 2 A 16 bit channel_id (MSB first)

DESCRIPTION

This message is sent by a node to signal that it is stoping its subscription to the channel identified by channel_id.

This message is only advisory and is not acknowledged by the node manager.

NOCAN_SYS_CHANNEL_LOOKUP (16)

STRUCTURE

node_id function parameter DLC data
id > 0 16 - 1 to 64 1 to 64 bytes, representing an ascii channel name

DESCRIPTION

This message is sent by a node to request the value of channel_id that corresponds to the provided channel name.

The node manager will respond with NOCAN_SYS_CHANNEL_LOOKUP_ACK, providing the channel_id.

NOCAN_SYS_CHANNEL_LOOKUP_ACK (17)

STRUCTURE

node_id function parameter DLC data
id > 0 17 0 or 255 2 A 16 bit channel_id (MSB first)

DESCRIPTION

This message is sent by the node manager in response to a NOCAN_SYS_CHANNEL_LOOKUP message.

Parameter is 0 in case of success and 255 in case of failure. The data contains a 16 bit channel id in case of success.

NOCAN_SYS_BOOTLOADER_GET_SIGNATURE (18)

STRUCTURE

node_id function parameter DLC data
id > 0 18 - 0 -

DESCRIPTION

This message is sent by the node manager to request the device id of the main chip in the node.

The node is expected to respond with a NOCAN_SYS_BOOTLOADER_GET_SIGNATURE_ACK message. A node is only required to respond to this message when it is in bootloader mode.

NOCAN_SYS_BOOTLOADER_GET_SIGNATURE_ACK (19)

STRUCTURE

node_id function parameter DLC data
id > 0 19 - 1-8 The device signature.

DESCRIPTION

This message is sent by a node in response to a NOCAN_SYS_BOOTLOADER_GET_SIGNATURE message.

On the Omzlo One DLC=3 and data is 0x1E, 0x95, 0x16.

NOCAN_SYS_BOOTLOADER_SET_ADDRESS (20)

STRUCTURE

node_id function parameter DLC data
id > 0 20 'F' or 'E' 4 32 bits address (MSB first).

DESCRIPTION

This message is sent by the node manager to set the address of the next flash or eeprom memory that will be read or written.

Reaging or writing is performed by LL_SYS_BOOTLOADER_READ and LL_SYS_BOOTLOADER_WRITE.

Parameter is set to 'F' to indicate flash memory, and 'E' to indicate eeprom.

NOCAN_SYS_BOOTLOADER_SET_ADDRESS_ACK (21)

STRUCTURE

node_id function parameter DLC data
id > 0 21 0 or 255 0 -

DESCRIPTION

This message is sent by a node in response to a NOCAN_SYS_BOOTLOADER_SET_ADDRESS message.

NOCAN_SYS_BOOTLOADER_WRITE (22)

STRUCTURE

node_id function parameter DLC data
id > 0 22 0 or 1 0-8 Data to be writen to flash or eeprom.

DESCRIPTION

This message is sent by the node manager to request data to be written in flash or eeprom.

The memory address where data is written is set by a call to NOCAN_SYS_BOOTLOADER_SET_ADDRESS and is then incremented automatically by each call to NOCAN_SYS_BOOTLOADER_WRITE.

If parameter is 0 the data is stored in a buffer and the flash/eeprom is not updated. A parameter set to 1 marks the final bytes of data in a block and the buffer is written to flash or eeprom.

NOCAN_SYS_BOOTLOADER_WRITE_ACK (23)

STRUCTURE

node_id function parameter DLC data
id > 0 23 0, 1 or 255 0 -

DESCRIPTION

This message is sent by a node in response to a NOCAN_SYS_BOOTLOADER_WRITE message.

In case of success parameter takes the same value (0 or 1) as in the NOCAN_SYS_BOOTLOADER_WRITE message.

In case of failure parameter is set to 255.

NOCAN_SYS_BOOTLOADER_READ (24)

STRUCTURE

node_id function parameter DLC data
id > 0 24 0 to 8 0 -

DESCRIPTION

This message is sent by the node manager to request data to be read from flash or eeprom.

The memory address where data is read is set by a call to NOCAN_SYS_BOOTLOADER_SET_ADDRESS and is then incremented automatically by each call to NOCAN_SYS_BOOTLOADER_READ.

The value of parameter indicates the number of bytes to read.

NOCAN_SYS_BOOTLOADER_READ_ACK (25)

STRUCTURE

node_id function parameter DLC data
0 > id 25 0 or 255 0 to 8 Data read from flash or eeprom.

DESCRIPTION

This message is sent by a node in response to a NOCAN_SYS_BOOTLOADER_READ message.

Parameter is 0 in case of success and 255 in case of failure.

NOCAN_SYS_BOOTLOADER_LEAVE (26)

STRUCTURE

node_id function parameter DLC data
0 > id 26 - 0 -

DESCRIPTION

This message is sent by the node manager to request a node to leave bootloader mode and start the main application.

On the Omzlo One, the bootloader is active for 10 seconds approximately before automatically booting to the main application: this message allows to shorten this delay by explicitly requesting the node to launch the application.

The node is expected to acknowledge this message with a NOCAN_SYS_BOOTLOADER_LEAVE_ACK message.

NOCAN_SYS_BOOTLOADER_LEAVE_ACK (27)

STRUCTURE

node_id function parameter DLC data
0 > id 27 - 0 -

DESCRIPTION

This message is sent by a node in response to a NOCAN_SYS_BOOTLOADER_LEAVE message.