Skip to content

Commit

Permalink
chore: catchup to d78cccc
Browse files Browse the repository at this point in the history
d78cccc Make sure can frame is zero initialized
e43524e New documentation templating
239170d Limit dlc to 8 in can reception
7a94f54 Add heartbeat state callback to public API
944ee04 Add heartbeat consumer state change callback
1b07023 Switch to using ticks instead of time in osal
249c12c Use Sphinx Press HTML theme
ea2b832 Fredrik's documentation updates 2022-12-23

Based-On-Commit: d78cccc
Change-Id: Iea72cb5f2dd4649edd6887fe9802a098a07e8b13
  • Loading branch information
rt-labs bot committed Jul 2, 2024
1 parent 26faaf3 commit 92e646e
Show file tree
Hide file tree
Showing 26 changed files with 203 additions and 108 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ CMakeCache.txt
install
docs/_build

# Python files
*env*

.cproject
.project
.dir-locals.el
Expand Down
7 changes: 7 additions & 0 deletions include/co_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,13 @@ typedef struct co_cfg
/** Notify callback */
void (*cb_notify) (co_net_t * net, uint16_t index, uint8_t subindex);

/** Heartbeat node state change callback */
void (*cb_heartbeat_state) (
co_net_t * net,
uint8_t node,
uint8_t old_state,
uint8_t new_state);

/** Function to open dictionary store */
void * (*open) (co_store_t store, co_mode_t mode);

Expand Down
9 changes: 5 additions & 4 deletions src/co_emcy.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
#define os_channel_send mock_os_channel_send
#define os_channel_get_state mock_os_channel_get_state
#define os_channel_bus_on mock_os_channel_bus_on
#define os_get_current_time_us mock_os_get_current_time_us
#define os_tick_current mock_os_tick_current
#define os_tick_from_us mock_os_tick_from_us
#endif

#include "co_emcy.h"
Expand Down Expand Up @@ -232,7 +233,7 @@ int co_emcy_tx (co_net_t * net, uint16_t code, uint16_t info, uint8_t msef[5])
uint8_t msg[8] = {0};
uint8_t * p = msg;
uint8_t reg;
uint32_t now;
os_tick_t now;
bool error_behavior = false;

if (net->number_of_errors < MAX_ERRORS)
Expand Down Expand Up @@ -263,7 +264,7 @@ int co_emcy_tx (co_net_t * net, uint16_t code, uint16_t info, uint8_t msef[5])
}

/* Send EMCY if inhibit time has expired */
now = os_get_current_time_us();
now = os_tick_current();
if (co_is_expired (now, net->emcy.timestamp, 100 * net->emcy.inhibit))
{
LOG_ERROR (CO_EMCY_LOG, "emcy %x\n", code);
Expand Down Expand Up @@ -325,7 +326,7 @@ int co_emcy_rx (co_net_t * net, uint32_t id, uint8_t * msg, size_t dlc)
void co_emcy_handle_can_state (co_net_t * net)
{
int status;
uint32_t now = os_get_current_time_us();;
os_tick_t now = os_tick_current();
os_channel_state_t previous = net->emcy.state;

/* Get current state */
Expand Down
45 changes: 38 additions & 7 deletions src/co_heartbeat.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

#ifdef UNIT_TEST
#define os_channel_send mock_os_channel_send
#define os_get_current_time_us mock_os_get_current_time_us
#define os_tick_current mock_os_tick_current
#define os_tick_from_us mock_os_tick_from_us
#define co_emcy_tx mock_co_emcy_tx
#endif

Expand Down Expand Up @@ -111,17 +112,40 @@ int co_heartbeat_rx (co_net_t * net, uint8_t node, void * msg, size_t dlc)
if (net->heartbeat[ix].node == node)
{
co_heartbeat_t * heartbeat = &net->heartbeat[ix];
uint8_t state;

heartbeat->timestamp = os_tick_current();
state = co_fetch_uint8 (msg);
LOG_DEBUG (
CO_HEARTBEAT_LOG,
"node %d got heartbeat state %02x\n",
heartbeat->node,
heartbeat->state);

heartbeat->timestamp = os_get_current_time_us();
heartbeat->is_alive = true;
LOG_DEBUG (CO_HEARTBEAT_LOG, "node %d got heartbeat\n", heartbeat->node);
/* Check for node state change */
if (state != heartbeat->state)
{
LOG_DEBUG (
CO_HEARTBEAT_LOG,
"node %d heartbeat state change\n",
heartbeat->node);

/* Call user callback */
if (net->cb_heartbeat_state)
{
net->cb_heartbeat_state (net, node, heartbeat->state, state);
}

/* Update node state */
heartbeat->state = state;
}
}
}

return 0;
}

int co_heartbeat_timer (co_net_t * net, uint32_t now)
int co_heartbeat_timer (co_net_t * net, os_tick_t now)
{
unsigned int ix;
bool heartbeat_error = false;
Expand Down Expand Up @@ -171,21 +195,28 @@ int co_heartbeat_timer (co_net_t * net, uint32_t now)
continue;

/* Check that heartbeat has not already expired */
if (!heartbeat->is_alive)
if (heartbeat->state == 0)
continue;

/* Check heartbeat has not expired */
if (co_is_expired (now, heartbeat->timestamp, 1000 * heartbeat->time))
{
/* Expired */
heartbeat->is_alive = false;
co_bitmap_clear (net->nodes, heartbeat->node);
LOG_ERROR (
CO_HEARTBEAT_LOG,
"node %d heartbeat expired\n",
heartbeat->node);

/* Call user callback */
if (net->cb_heartbeat_state)
{
net->cb_heartbeat_state (net, heartbeat->node, heartbeat->state, 0);
}

heartbeat->state = 0;
heartbeat_error = true;

co_emcy_error_register_set (net, CO_ERR_COMMUNICATION);
co_emcy_tx (net, 0x8130, 0, NULL);
}
Expand Down
2 changes: 1 addition & 1 deletion src/co_heartbeat.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ int co_heartbeat_rx (co_net_t * net, uint8_t node, void * msg, size_t dlc);
*
* @return 0 on success, -1 on failure
*/
int co_heartbeat_timer (co_net_t * net, uint32_t now);
int co_heartbeat_timer (co_net_t * net, os_tick_t now);

#ifdef __cplusplus
}
Expand Down
7 changes: 4 additions & 3 deletions src/co_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ void co_handle_rx (co_net_t * net)

void co_handle_periodic (co_net_t * net)
{
uint32_t now = os_get_current_time_us();
os_tick_t now = os_tick_current();

co_sdo_server_timer (net, now);
co_sdo_client_timer (net, now);
Expand Down Expand Up @@ -278,7 +278,7 @@ int co_sdo_read (
job->sdo.data = data;
job->sdo.remain = size;
job->callback = co_job_callback;
job->timestamp = os_get_current_time_us();
job->timestamp = os_tick_current();
job->type = CO_JOB_SDO_READ;

os_mbox_post (net->mbox, job, OS_WAIT_FOREVER);
Expand Down Expand Up @@ -307,7 +307,7 @@ int co_sdo_write (
job->sdo.data = (uint8_t *)data;
job->sdo.remain = size;
job->callback = co_job_callback;
job->timestamp = os_get_current_time_us();
job->timestamp = os_tick_current();
job->type = CO_JOB_SDO_WRITE;

os_mbox_post (net->mbox, job, OS_WAIT_FOREVER);
Expand Down Expand Up @@ -421,6 +421,7 @@ co_net_t * co_init (const char * canif, const co_cfg_t * cfg)
net->cb_sync = cfg->cb_sync;
net->cb_emcy = cfg->cb_emcy;
net->cb_notify = cfg->cb_notify;
net->cb_heartbeat_state = cfg->cb_heartbeat_state;

net->restart_ms = cfg->restart_ms;

Expand Down
25 changes: 16 additions & 9 deletions src/co_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ typedef struct co_pdo
uint8_t sync_counter;
uint16_t inhibit_time;
uint16_t event_timer;
uint32_t timestamp;
os_tick_t timestamp;
uint64_t frame;
size_t bitlength;
uint8_t number_of_mappings;
Expand Down Expand Up @@ -149,7 +149,7 @@ typedef struct co_job
co_emcy_job_t emcy;
co_pdo_job_t pdo;
};
uint32_t timestamp;
os_tick_t timestamp;
struct co_client * client;
void (*callback) (struct co_job * job);
int result;
Expand All @@ -167,9 +167,9 @@ struct co_client
typedef struct co_heartbeat
{
uint8_t node;
bool is_alive;
uint8_t state;
uint16_t time;
uint32_t timestamp;
os_tick_t timestamp;
} co_heartbeat_t;

/** Node guarding state */
Expand All @@ -179,7 +179,7 @@ typedef struct co_node_guard
uint16_t guard_time;
uint8_t life_time_factor;
uint8_t toggle;
uint32_t timestamp;
os_tick_t timestamp;
} co_node_guard_t;

/** LSS states */
Expand All @@ -206,14 +206,14 @@ typedef struct co_sync
uint8_t counter;
uint8_t overflow;
uint32_t period;
uint32_t timestamp;
os_tick_t timestamp;
} co_sync_t;

/** EMCY state */
typedef struct co_emcy
{
uint32_t cobid; /**< EMCY COB ID */
uint32_t timestamp; /**< Timestamp of last EMCY */
os_tick_t timestamp; /**< Timestamp of last EMCY */
uint32_t bus_off_timestamp; /**< Timestamp of bus-off event */
uint16_t inhibit; /**< Inhibit time [100 us] */
uint8_t error; /**< Error register */
Expand All @@ -238,9 +238,9 @@ struct co_net
co_emcy_t emcy; /**< EMCY state */
co_sync_t sync; /**< SYNC state */
co_state_t state; /**< NMT state */
uint32_t hb_timestamp; /**< Heartbeat producer timestamp */
os_tick_t hb_timestamp; /**< Heartbeat producer timestamp */
uint32_t hb_time; /**< Heartbeat producer time */
uint32_t sync_timestamp; /**< Timestamp of last SYNC */
os_tick_t sync_timestamp; /**< Timestamp of last SYNC */
uint32_t sync_window; /**< Synchronous window length */
uint32_t restart_ms; /**< Delay before attempting to recover from bus-off */
co_pdo_t pdo_tx[MAX_TX_PDO]; /**< TPDOs */
Expand Down Expand Up @@ -279,6 +279,13 @@ struct co_net
/** Notify callback */
void (*cb_notify) (co_net_t * net, uint16_t index, uint8_t subindex);

/** Heartbeat node state change callback */
void (*cb_heartbeat_state) (
co_net_t * net,
uint8_t node,
uint8_t old_state,
uint8_t new_state);

/** Function to open dictionary store */
void * (*open) (co_store_t store, co_mode_t mode);

Expand Down
7 changes: 4 additions & 3 deletions src/co_node_guard.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
#ifdef UNIT_TEST
#define os_channel_send mock_os_channel_send
#define os_channel_receive mock_os_channel_receive
#define os_get_current_time_us mock_os_get_current_time_us
#define os_tick_current mock_os_tick_current
#define os_tick_from_us mock_os_tick_from_us
#endif

#include "co_node_guard.h"
Expand Down Expand Up @@ -84,7 +85,7 @@ int co_node_guard_rx (co_net_t * net, uint32_t id, void * msg, size_t dlc)
return -1;

net->node_guard.is_alive = true;
net->node_guard.timestamp = os_get_current_time_us();
net->node_guard.timestamp = os_tick_current();

/* Heartbeat producer (heartbeat is prioritised over node guarding)*/
if (net->hb_time == 0)
Expand Down Expand Up @@ -113,7 +114,7 @@ int co_node_guard_rx (co_net_t * net, uint32_t id, void * msg, size_t dlc)
return 0;
}

int co_node_guard_timer (co_net_t * net, uint32_t now)
int co_node_guard_timer (co_net_t * net, os_tick_t now)
{
uint32_t guard_factor =
(net->node_guard.guard_time * net->node_guard.life_time_factor);
Expand Down
2 changes: 1 addition & 1 deletion src/co_node_guard.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ int co_node_guard_rx (co_net_t * net, uint32_t id, void * msg, size_t dlc);
*
* @return 0 on success, -1 on failure
*/
int co_node_guard_timer (co_net_t * net, uint32_t now);
int co_node_guard_timer (co_net_t * net, os_tick_t now);

#ifdef __cplusplus
}
Expand Down
17 changes: 9 additions & 8 deletions src/co_pdo.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

#ifdef UNIT_TEST
#define os_channel_send mock_os_channel_send
#define os_get_current_time_us mock_os_get_current_time_us
#define os_tick_current mock_os_tick_current
#define os_tick_from_us mock_os_tick_from_us
#define co_obj_find mock_co_obj_find
#define co_entry_find mock_co_entry_find
#define co_emcy_tx mock_co_emcy_tx
Expand Down Expand Up @@ -532,7 +533,7 @@ uint32_t co_od1A00_fn (
static void co_pdo_transmit (co_net_t * net, co_pdo_t * pdo)
{
size_t dlc;
uint32_t now = os_get_current_time_us();
os_tick_t now = os_tick_current();

if (IS_EVENT (pdo->transmission_type) && pdo->inhibit_time > 0)
{
Expand All @@ -549,7 +550,7 @@ static void co_pdo_transmit (co_net_t * net, co_pdo_t * pdo)
pdo->queued = false;
}

int co_pdo_timer (co_net_t * net, uint32_t now)
int co_pdo_timer (co_net_t * net, os_tick_t now)
{
unsigned int ix;

Expand Down Expand Up @@ -659,7 +660,7 @@ int co_pdo_sync (co_net_t * net, uint8_t * msg, size_t dlc)
if (net->state != STATE_OP)
return -1;

net->sync_timestamp = os_get_current_time_us();
net->sync_timestamp = os_tick_current();

/* Transmit TPDOs */
for (ix = 0; ix < MAX_TX_PDO; ix++)
Expand Down Expand Up @@ -735,7 +736,7 @@ int co_pdo_sync (co_net_t * net, uint8_t * msg, size_t dlc)
void co_pdo_rx (co_net_t * net, uint32_t id, void * msg, size_t dlc)
{
unsigned int ix;
uint32_t now;
os_tick_t now;

/* Check state */
if (net->state != STATE_OP)
Expand All @@ -762,7 +763,7 @@ void co_pdo_rx (co_net_t * net, uint32_t id, void * msg, size_t dlc)
/* Transmit value sampled at previous SYNC */
dlc = CO_BYTELENGTH (pdo->bitlength);
os_channel_send (net->channel, pdo->cobid, &pdo->frame, dlc);
pdo->timestamp = os_get_current_time_us();
pdo->timestamp = os_tick_current();
pdo->queued = false;
}
}
Expand All @@ -787,14 +788,14 @@ void co_pdo_rx (co_net_t * net, uint32_t id, void * msg, size_t dlc)
if (pdo->transmission_type <= CO_PDO_TT_CYCLIC_MAX && net->sync_window > 0)
{
/* Check that sync window has not expired */
now = os_get_current_time_us();
now = os_tick_current();
if (co_is_expired (now, net->sync_timestamp, net->sync_window))
continue;
}

/* Buffer frame */
memcpy (&pdo->frame, msg, dlc);
pdo->timestamp = os_get_current_time_us();
pdo->timestamp = os_tick_current();

if (IS_EVENT (pdo->transmission_type))
{
Expand Down
2 changes: 1 addition & 1 deletion src/co_pdo.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ void co_pdo_rx (co_net_t * net, uint32_t id, void * msg, size_t dlc);
*
* @return 0 on success, -1 on failure
*/
int co_pdo_timer (co_net_t * net, uint32_t now);
int co_pdo_timer (co_net_t * net, os_tick_t now);

/**
* PDO trigger
Expand Down
Loading

0 comments on commit 92e646e

Please sign in to comment.