Skip to content

Group baton_node

Modules > baton_node

One bus node (master or slave) on top of the Link .More...

Classes

Type Name
struct baton_channel
Stop-and-wait state of the channel to one peer, both directions.
struct baton_node
Node state.
struct baton_node_config
Node configuration passed to baton_node_init ; copied.
struct baton_stats
Diagnostic counters, see baton_node_get_stats() .

Public Types

Type Name
typedef void(* baton_critical_fn
Enter or leave the critical section shared with interrupts.
typedef void(* baton_drop_fn
An event was not delivered within event_ttl_ms.
typedef void(* baton_message_fn
A message (state or event) was received.
enum baton_msg_id
Message identifiers: BATON_MSG_<NAME>.
enum baton_msg_max_len
Maximum data lengths: BATON_MSG_<NAME>_MAX_LEN.
typedef void(* baton_poll_done_fn
Master only: one poll slot finished.

Public Functions

Type Name
void baton_node_default_config (struct baton_node_config * config)
Fill config with defaults for 9600 bit/s.
void baton_node_get_stats (const struct baton_node * node, struct baton_stats * stats)
Copy the diagnostic counters.
int baton_node_init (struct baton_node * node, const struct baton_node_config * config, uint32_t now_ms)
Validate the configuration and start the node.
void baton_node_process (struct baton_node * node, uint32_t now_ms)
Run the protocol.
int baton_node_publish (struct baton_node * node, uint8_t msg_id, const void * data, uint8_t length)
Update a state value; the latest value is delivered to every other node.
void baton_node_rx_isr (struct baton_node * node, uint8_t byte)
Store one received byte.
int baton_node_send (struct baton_node * node, uint8_t dst, uint8_t msg_id, const void * data, uint8_t length, uint8_t priority)
Queue an event for reliable delivery.
void baton_node_tx_done_isr (struct baton_node * node)
Signal the end of a transmission (only needed when rx_echo is false).

Macros

Type Name
define BATON_DEAD_POLL_DIV 4U
The master polls an unreachable slave only every BATON_DEAD_POLL_DIV-th cycle.
define BATON_DEAD_STREAK 3U
A node failing this many times in a row is treated as unreachable.
define BATON_ERR_ADDR (-5)
Unknown destination or own address.
define BATON_ERR_FULL (-6)
Event queue has no room; try again later.
define BATON_ERR_LEN (-4)
Data longer than the maximum length of the message.
define BATON_ERR_MSG_ID (-3)
Unknown message id, or wrong class (state vs event).
define BATON_ERR_NOT_INIT (-2)
baton_node_init() was not called or failed.
define BATON_ERR_PARAM (-1)
Invalid argument or configuration.
define BATON_EVENT_COUNT (0U BATON\_EVENT\_LIST(BATON\_X\_COUNT\_))
Number of EVENT messages.
define BATON_MASK_BYTES (([**BATON\_MAX\_NODES**](group__baton__config.md#define-baton_max_nodes) + 7U) / 8U)
Bytes of a node mask inside a RESP.
define BATON_MAX_MSG_LEN ([**BATON\_MAX\_PAYLOAD**](group__baton__config.md#define-baton_max_payload) - [**BATON\_RESP\_PREFIX**](group__baton__node.md#define-baton_resp_prefix) - [**BATON\_TLV\_HEADER\_SIZE**](group__baton__defs.md#define-baton_tlv_header_size))
Largest MAX_LEN of a message: one message must fit into any frame type.
define BATON_OK 0
Success.
define BATON_POLL_PREFIX 1U
POLL payload prefix: ACKB.
define BATON_PRIO_HIGH 1U
HIGH event queue, packed before NORMAL events.
define BATON_PRIO_NORMAL 0U
NORMAL event queue.
define BATON_RESP_PREFIX (1U + [**BATON\_MASK\_BYTES**](group__baton__node.md#define-baton_mask_bytes))
RESP payload prefix: ACKB and the NACK node mask.
define BATON_ROLE_MASTER 0U
The node that polls the slaves.
define BATON_ROLE_SLAVE 1U
A node that transmits only when polled.
define BATON_STATE_COUNT (0U BATON\_STATE\_LIST(BATON\_X\_COUNT\_))
Number of STATE messages.
define BATON_STATE_DATA_SIZE (1U BATON\_STATE\_LIST(BATON\_X\_STATE\_SIZE\_))
Bytes of the state mailboxes (one spare byte keeps the array non-empty).

Detailed Description

The master passes the baton (POLL) to the slaves in a fixed order; only the polled slave transmits, for at most slot_time_ms, so the bus never has collisions. Messages are of two classes, defined by the application message lists in baton_user_config.h: * EVENT: queued (HIGH or NORMAL priority), acknowledged, retransmitted, delivered exactly once and in order per (source, destination, priority), dropped after event_ttl_ms with an on_drop report; * STATE: a mailbox per state; the latest value is delivered to every other node, intermediate values may be skipped, it can never overflow.

Threading model: baton_node_init(), baton_node_process() and baton_node_get_stats() run in one context (main loop or one RTOS task). baton_node_rx_isr() and baton_node_tx_done_isr() are called from the UART interrupts. baton_node_send() and baton_node_publish() may be called from any context only when enter_critical and exit_critical are configured.

All memory is inside struct baton_node, owned by the caller. No function blocks, allocates memory or reads a clock.

** **

Public Types Documentation

typedef baton_critical_fn

Enter or leave the critical section shared with interrupts.

typedef void(* baton_critical_fn) (void *context);


typedef baton_drop_fn

An event was not delivered within event_ttl_ms.

typedef void(* baton_drop_fn) (void *context, uint8_t msg_id, uint8_t dst, uint32_t missed_nodes);

Parameters:

  • context Value of baton_node_config::context.
  • msg_id Message identifier.
  • dst Address given to baton_node_send().
  • missed_nodes Node mask of the nodes that did not acknowledge it (a node may still have received it when only its acknowledgement was lost).

typedef baton_message_fn

A message (state or event) was received.

typedef void(* baton_message_fn) (void *context, uint8_t src, uint8_t msg_id, const uint8_t *data, uint8_t length);

Called from baton_node_process(). data is valid only during the call.


enum baton_msg_id

Message identifiers: BATON_MSG_<NAME>.

enum baton_msg_id {
    BATON_STATE_LIST =(BATON_X_MSG_ENUM_) BATON_EVENT_LIST(BATON_X_MSG_ENUM_) BATON_MSG_INVALID_ =
        0x100
};


enum baton_msg_max_len

Maximum data lengths: BATON_MSG_<NAME>_MAX_LEN.

enum baton_msg_max_len {
    BATON_STATE_LIST =(BATON_X_MSG_ENUM_) BATON_EVENT_LIST(BATON_X_MSG_ENUM_) BATON_MSG_INVALID_ =
        0x100
};


typedef baton_poll_done_fn

Master only: one poll slot finished.

typedef void(* baton_poll_done_fn) (void *context, uint8_t slave, bool responded, uint32_t nack_nodes);

Parameters:

  • context Value of baton_node_config::context.
  • slave Address of the polled slave.
  • responded The slave answered with a RESP.
  • nack_nodes Node mask of the nodes that did not acknowledge DATA from that slave.

Public Functions Documentation

function baton_node_default_config

Fill config with defaults for 9600 bit/s.

void baton_node_default_config (
    struct baton_node_config * config
) 

Topology, write function and callbacks must still be set.

Parameters:

  • config Configuration to fill; NULL is ignored.

function baton_node_get_stats

Copy the diagnostic counters.

void baton_node_get_stats (
    const struct baton_node * node,
    struct baton_stats * stats
) 

Parameters:

  • node Node state.
  • stats Destination; nothing is written when an argument is NULL.

function baton_node_init

Validate the configuration and start the node.

int baton_node_init (
    struct baton_node * node,
    const struct baton_node_config * config,
    uint32_t now_ms
) 

Can be called again to restart.

Parameters:

  • node Node state.
  • config Configuration copied into the node.
  • now_ms Current time.

Return value:

  • BATON_OK Node ready.
  • BATON_ERR_PARAM NULL argument, inconsistent topology, duplicate message ids, a timing that does not allow one maximum-size exchange per slot, or an event that does not fit into a queue.

function baton_node_process

Run the protocol.

void baton_node_process (
    struct baton_node * node,
    uint32_t now_ms
) 

Call often (every 1 ms is recommended). Never blocks.

Parameters:

  • node Node state; ignored when NULL or not initialized.
  • now_ms Current time.

function baton_node_publish

Update a state value; the latest value is delivered to every other node.

int baton_node_publish (
    struct baton_node * node,
    uint8_t msg_id,
    const void * data,
    uint8_t length
) 

Parameters:

  • node Node state.
  • msg_id STATE message identifier.
  • data Data bytes, or NULL when length is zero.
  • length Number of data bytes (at most the MAX_LEN of the message).

Returns:

BATON_OK or BATON_ERR_* (see the return codes). Never fails for lack of space.


function baton_node_rx_isr

Store one received byte.

void baton_node_rx_isr (
    struct baton_node * node,
    uint8_t byte
) 

Call from the UART receive interrupt.

Parameters:

  • node Node state; NULL is ignored.
  • byte Received byte.

function baton_node_send

Queue an event for reliable delivery.

int baton_node_send (
    struct baton_node * node,
    uint8_t dst,
    uint8_t msg_id,
    const void * data,
    uint8_t length,
    uint8_t priority
) 

The data is copied.

The TTL of the event starts at the time of the last baton_node_process() call.

Parameters:

  • node Node state.
  • dst Node address or BATON_ADDR_BROADCAST.
  • msg_id EVENT message identifier.
  • data Data bytes, or NULL when length is zero.
  • length Number of data bytes (at most the MAX_LEN of the message).
  • priority BATON_PRIO_NORMAL or BATON_PRIO_HIGH.

Returns:

BATON_OK or BATON_ERR_* (see the return codes).


function baton_node_tx_done_isr

Signal the end of a transmission (only needed when rx_echo is false).

void baton_node_tx_done_isr (
    struct baton_node * node
) 

Parameters:

  • node Node state; NULL is ignored.

Macro Definition Documentation

define BATON_DEAD_POLL_DIV

The master polls an unreachable slave only every BATON_DEAD_POLL_DIV-th cycle.

#define BATON_DEAD_POLL_DIV `4U`


define BATON_DEAD_STREAK

A node failing this many times in a row is treated as unreachable.

#define BATON_DEAD_STREAK `3U`


define BATON_ERR_ADDR

Unknown destination or own address.

#define BATON_ERR_ADDR `(-5)`


define BATON_ERR_FULL

Event queue has no room; try again later.

#define BATON_ERR_FULL `(-6)`


define BATON_ERR_LEN

Data longer than the maximum length of the message.

#define BATON_ERR_LEN `(-4)`


define BATON_ERR_MSG_ID

Unknown message id, or wrong class (state vs event).

#define BATON_ERR_MSG_ID `(-3)`


define BATON_ERR_NOT_INIT

baton_node_init() was not called or failed.

#define BATON_ERR_NOT_INIT `(-2)`


define BATON_ERR_PARAM

Invalid argument or configuration.

#define BATON_ERR_PARAM `(-1)`


define BATON_EVENT_COUNT

Number of EVENT messages.

#define BATON_EVENT_COUNT `(0U BATON_EVENT_LIST(BATON_X_COUNT_))`


define BATON_MASK_BYTES

Bytes of a node mask inside a RESP.

#define BATON_MASK_BYTES `(( BATON_MAX_NODES + 7U) / 8U)`


define BATON_MAX_MSG_LEN

Largest MAX_LEN of a message: one message must fit into any frame type.

#define BATON_MAX_MSG_LEN `( BATON_MAX_PAYLOAD - BATON_RESP_PREFIX - BATON_TLV_HEADER_SIZE )`


define BATON_OK

Success.

#define BATON_OK `0`


define BATON_POLL_PREFIX

POLL payload prefix: ACKB.

#define BATON_POLL_PREFIX `1U`


define BATON_PRIO_HIGH

HIGH event queue, packed before NORMAL events.

#define BATON_PRIO_HIGH `1U`


define BATON_PRIO_NORMAL

NORMAL event queue.

#define BATON_PRIO_NORMAL `0U`


define BATON_RESP_PREFIX

RESP payload prefix: ACKB and the NACK node mask.

#define BATON_RESP_PREFIX `(1U + BATON_MASK_BYTES )`


define BATON_ROLE_MASTER

The node that polls the slaves.

#define BATON_ROLE_MASTER `0U`


define BATON_ROLE_SLAVE

A node that transmits only when polled.

#define BATON_ROLE_SLAVE `1U`


define BATON_STATE_COUNT

Number of STATE messages.

#define BATON_STATE_COUNT `(0U BATON_STATE_LIST(BATON_X_COUNT_))`


define BATON_STATE_DATA_SIZE

Bytes of the state mailboxes (one spare byte keeps the array non-empty).

#define BATON_STATE_DATA_SIZE `(1U BATON_STATE_LIST(BATON_X_STATE_SIZE_))`