114 lines
2.8 KiB
C
114 lines
2.8 KiB
C
/**
|
|
* @ingroup can
|
|
* @defgroup can_frame Frame pooling
|
|
* @brief RX frame pooling
|
|
* @date Oct 29, 2015
|
|
* @author jjacobs
|
|
* @copyright 2015 Dual Inventive Technology Centre B.V.
|
|
*
|
|
* CAN frame pooling
|
|
* @{
|
|
*/
|
|
#ifndef LIBDI_INCLUDE_DI_CAN_FRAME_H_
|
|
#define LIBDI_INCLUDE_DI_CAN_FRAME_H_
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <di/array.h>
|
|
#include <di/semaphore.h>
|
|
#include <di/can/defines.h>
|
|
|
|
struct di_can_ctx;
|
|
|
|
/** Declare di_can_msg array */
|
|
#define DI_CAN_FRAME_RX_DECL_ARRAY(name, elements) \
|
|
static struct di_can_frame_rx name[elements]
|
|
|
|
/** CAN-bus frame */
|
|
struct di_can_frame_tx {
|
|
size_t size;
|
|
uint32_t canid;
|
|
uint8_t *buf;
|
|
const struct di_can_ctx *ctx; /** DI CAN context */
|
|
};
|
|
|
|
/** CAN-bus RX frame */
|
|
struct di_can_frame_rx {
|
|
uint64_t timeout; /**< Timeout for GC in milliseconds since di_time_get_uptime() */
|
|
uint16_t flags;
|
|
size_t size;
|
|
uint32_t canid;
|
|
uint8_t buf[8];
|
|
const struct di_can_ctx *ctx; /**< DI CAN context */
|
|
};
|
|
|
|
/**
|
|
* CAN frame subsystem
|
|
*/
|
|
struct di_can_frame {
|
|
di_bsem_t lock;
|
|
struct di_array pool;
|
|
uint32_t timeout; /**< Garbage collection timeout of frames (milliseconds) */
|
|
};
|
|
|
|
#include <di/can.h>
|
|
|
|
/**
|
|
* Initialize can frame subsystem
|
|
* @param ctx CAN context
|
|
* @param list List of can rx frames
|
|
* @param size Elements of can rx frames in list
|
|
* @note When the subsystem is already initialized next function calls will be ignored
|
|
*/
|
|
void di_can_frame_init(struct di_can_ctx *ctx, struct di_can_frame_rx *list, size_t size);
|
|
|
|
/**
|
|
* Get unused can frame
|
|
*/
|
|
struct di_can_frame_rx *di_can_frame_get_unused(struct di_can_ctx *ctx);
|
|
|
|
/**
|
|
* Get used + ready can frame for reassembly of message
|
|
*/
|
|
struct di_can_frame_rx *di_can_frame_get_ready(struct di_can_ctx *ctx);
|
|
|
|
/**
|
|
* Return can frame to notify it is ready
|
|
*/
|
|
void di_can_frame_return_ready(struct di_can_frame_rx *frame);
|
|
|
|
/**
|
|
* Destroy and return the can frame so it is free
|
|
*/
|
|
void di_can_frame_return_unused(struct di_can_frame_rx *frame);
|
|
|
|
/**
|
|
* Garbage collect where di_can_frame_rx timeouts are exceeded
|
|
* This will use the di_time_get_uptime to test against
|
|
* the message timeout
|
|
* * When di_can_frame_rx.timeout is set to DI_CAN_TIMEOUT_GC_SKIP it is not garbage collected
|
|
* * When di_can_frame_rx.timeout is set to DI_CAN_TIMEOUT_GC_IMMEDIATE it is immediate collected
|
|
* @note This should be run with ~50ms interval from thread with all being freed up
|
|
*/
|
|
void di_can_frame_gc(struct di_can_ctx *ctx, enum di_can_gc gc);
|
|
|
|
/**
|
|
* Get application specific private_data set with
|
|
* di_can_set_private_data
|
|
*/
|
|
void *di_can_frame_rx_get_private_data(const struct di_can_frame_rx *frame);
|
|
|
|
void *di_can_frame_tx_get_private_data(const struct di_can_frame_tx *frame);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
/** @} */
|
|
|
|
#endif /* LIBDI_INCLUDE_DI_CAN_FRAME_H_ */
|