Close

Code Overview 1: Array Messaging

A project log for HEXABITZ - Modular Electronics for REAL

A new kind of electronic prototyping!

hexabitzHexabitz 04/03/2018 at 03:050 Comments

I'll start a series of logs titled Code Overview to go over some areas in Hexabitz code in more detail. Here's the first one.

Messaging Protocol

Messaging in the array is carried out via short unacknowledged packets in the following format (each field is a single byte):

| Length || Destination | Source | Code | Code | Par. 1 | Par. 2 | ------- | CRC || 

Messaging Workflow:

  1. Source module builds a message in the form shown above.
  2. Source sends one byte representing the message length and waits for 1.5 msec.
  3. Destination receives the length byte (in the UART_RxCpltCallback) and activates a port-to-memory DMA stream to transfer the same amount of bytes requested. Once finished, receive interrupt is activated on this port again.
  4. After destination receives the last termination byte (0x75 or CRC), it executes UART_RxCpltCallback again and notifies the appropriate messaging task.
  5. Messages are parsed to read source, destination and code bytes. Received message length is checked againts the Length byte.
  6. If the message is a transit message, it'll be forwarded directly. If it's a broadcast message, it will be broadcasted and then processed.
  7. Messages are processed according to their message codes. After that buffers are cleared and receive interrupt is activated on this port again.
  8. Message response and TRACE flags are verified to generate the appropriate response.
  9. If the message is long, the longMessage flag is activated and can be used to concatenate consecutive payloads before processing them.

Routing

You can send Messages through the array using the following APIs. The first API sends a Message out a given port to the adjacent module. It is useful when you do not know your neighbor’s ID or you simply want to send something across all or some ports:

BOS_Status SendMessageFromPort(uint8_t port, uint8_t src, uint8_t dst, uint16_t code, uint16_t numberOfParams)

where port is the output port, src and dst are source and destination module IDs, code is the Message code and numberOfParams is number of Message parameters. If the Message is originating from this module, you can use src=myID. The next API sends a Message to a another module (whether adjacent or not) : 

BOS_Status SendMessageToModule(uint8_t dst, uint16_t code, uint16_t numberOfParams)

where dst is the destination module (source is always the current module), code is the Message code and numberOfParams is number of Message parameters. SendMessageToModule() API basically calculates the optimal route to destination and which port leads to that route and then calls SendMessageFromPort() to send the Message from that port. Using 0xFF or BOS_BROADCAST for destination, broadcasts the Message to the entire array. You can control response settings of a unicast or broadcast Message via the BOS.response parameter:

Before you call one of the APIs above to send a Message with parameters, you need to fill out the parameters array first:

messageParams[0] =  (uint8_t)(600000>>8); messageParams[1] = 2; messageParams[2] = FORWARD;etc..

Array topology (routing table) is saved in the two-dimensional array variable array, which will be either provided in the topology header file or generated by Explore()API. Learn more about topology header files here. The FindRoute() API utilizes Dijkstra's shortest path algorithm to calculate the optimal route between two modules in the array based on the pre-populated routing table:

uint8_t FindRoute(uint8_t sourceID, uint8_t desID)

To avoid sending redundant routing information with each Message, this API returns the module port (P1 .. Px) closest to destination module. The Message is sent through this port to the next module in the chain which runs the FindRoute() API again and forwards the Message until it reaches its destination. As mentioned above, you can call the SendMessageToModule() API and it will take care of the entire process.

Discussions