123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540 |
- #ifndef CANARD_H
- #define CANARD_H
- #include <stdint.h>
- #include <stddef.h>
- #include <stdbool.h>
- #include <assert.h>
- #if defined(CANARD_ENABLE_CUSTOM_BUILD_CONFIG) && CANARD_ENABLE_CUSTOM_BUILD_CONFIG
- # include "canard_build_config.h"
- #endif
- #ifdef __cplusplus
- extern "C" {
- #endif
- #define CANARD_VERSION_MAJOR 0
- #define CANARD_VERSION_MINOR 2
- #ifndef CANARD_ASSERT
- # define CANARD_ASSERT(x) assert(x)
- #endif
- #define CANARD_GLUE(a, b) CANARD_GLUE_IMPL_(a, b)
- #define CANARD_GLUE_IMPL_(a, b) a##b
- #ifndef CANARD_STATIC_ASSERT
- # if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) ||\
- (defined(__cplusplus) && (__cplusplus >= 201103L))
- # define CANARD_STATIC_ASSERT(...) static_assert(__VA_ARGS__)
- # else
- # define CANARD_STATIC_ASSERT(x, ...) typedef char CANARD_GLUE(_static_assertion_, __LINE__)[(x) ? 1 : -1]
- # endif
- #endif
- #define CANARD_OK 0
- #define CANARD_ERROR_INVALID_ARGUMENT 2
- #define CANARD_ERROR_OUT_OF_MEMORY 3
- #define CANARD_ERROR_NODE_ID_NOT_SET 4
- #define CANARD_ERROR_INTERNAL 9
- #define CANARD_ERROR_RX_INCOMPATIBLE_PACKET 10
- #define CANARD_ERROR_RX_WRONG_ADDRESS 11
- #define CANARD_ERROR_RX_NOT_WANTED 12
- #define CANARD_ERROR_RX_MISSED_START 13
- #define CANARD_ERROR_RX_WRONG_TOGGLE 14
- #define CANARD_ERROR_RX_UNEXPECTED_TID 15
- #define CANARD_ERROR_RX_SHORT_FRAME 16
- #define CANARD_ERROR_RX_BAD_CRC 17
- #define CANARD_MEM_BLOCK_SIZE 32U
- #define CANARD_CAN_FRAME_MAX_DATA_LEN 8U
- #define CANARD_BROADCAST_NODE_ID 0
- #define CANARD_MIN_NODE_ID 1
- #define CANARD_MAX_NODE_ID 127
- #define CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE (CANARD_MEM_BLOCK_SIZE - offsetof(CanardRxState, buffer_head))
- #define CANARD_BUFFER_BLOCK_DATA_SIZE (CANARD_MEM_BLOCK_SIZE - offsetof(CanardBufferBlock, data))
- #define CANARD_RECOMMENDED_STALE_TRANSFER_CLEANUP_INTERVAL_USEC 1000000U
- #define CANARD_TRANSFER_PRIORITY_HIGHEST 0
- #define CANARD_TRANSFER_PRIORITY_HIGH 8
- #define CANARD_TRANSFER_PRIORITY_MEDIUM 16
- #define CANARD_TRANSFER_PRIORITY_LOW 24
- #define CANARD_TRANSFER_PRIORITY_LOWEST 31
- #define CANARD_CAN_EXT_ID_MASK 0x1FFFFFFFU
- #define CANARD_CAN_STD_ID_MASK 0x000007FFU
- #define CANARD_CAN_FRAME_EFF (1UL << 31U)
- #define CANARD_CAN_FRAME_RTR (1UL << 30U)
- #define CANARD_CAN_FRAME_ERR (1UL << 29U)
- #define CANARD_TRANSFER_PAYLOAD_LEN_BITS 10U
- #define CANARD_MAX_TRANSFER_PAYLOAD_LEN ((1U << CANARD_TRANSFER_PAYLOAD_LEN_BITS) - 1U)
- typedef struct
- {
-
- uint32_t id;
- uint8_t data[CANARD_CAN_FRAME_MAX_DATA_LEN];
- uint8_t data_len;
- } CanardCANFrame;
- typedef enum
- {
- CanardTransferTypeResponse = 0,
- CanardTransferTypeRequest = 1,
- CanardTransferTypeBroadcast = 2
- } CanardTransferType;
- typedef enum
- {
- CanardResponse,
- CanardRequest
- } CanardRequestResponse;
- typedef struct CanardInstance CanardInstance;
- typedef struct CanardRxTransfer CanardRxTransfer;
- typedef struct CanardRxState CanardRxState;
- typedef struct CanardTxQueueItem CanardTxQueueItem;
- typedef bool (* CanardShouldAcceptTransfer)(const CanardInstance* ins,
- uint64_t* out_data_type_signature,
- uint16_t data_type_id,
- CanardTransferType transfer_type,
- uint8_t source_node_id);
- typedef void (* CanardOnTransferReception)(CanardInstance* ins,
- CanardRxTransfer* transfer);
- typedef union CanardPoolAllocatorBlock_u
- {
- char bytes[CANARD_MEM_BLOCK_SIZE];
- union CanardPoolAllocatorBlock_u* next;
- } CanardPoolAllocatorBlock;
- typedef struct
- {
- uint16_t capacity_blocks;
- uint16_t current_usage_blocks;
- uint16_t peak_usage_blocks;
- } CanardPoolAllocatorStatistics;
- typedef struct
- {
- CanardPoolAllocatorBlock* free_list;
- CanardPoolAllocatorStatistics statistics;
- } CanardPoolAllocator;
- typedef struct CanardBufferBlock
- {
- struct CanardBufferBlock* next;
- uint8_t data[];
- } CanardBufferBlock;
- struct CanardRxState
- {
- struct CanardRxState* next;
- CanardBufferBlock* buffer_blocks;
- uint64_t timestamp_usec;
- const uint32_t dtid_tt_snid_dnid;
-
- unsigned calculated_crc : 16;
- unsigned payload_len : CANARD_TRANSFER_PAYLOAD_LEN_BITS;
- unsigned transfer_id : 5;
- unsigned next_toggle : 1;
- uint16_t payload_crc;
- uint8_t buffer_head[];
- };
- CANARD_STATIC_ASSERT(offsetof(CanardRxState, buffer_head) <= 28, "Invalid memory layout");
- CANARD_STATIC_ASSERT(CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE >= 4, "Invalid memory layout");
- struct CanardInstance
- {
- uint8_t node_id;
- CanardShouldAcceptTransfer should_accept;
- CanardOnTransferReception on_reception;
- CanardPoolAllocator allocator;
- CanardRxState* rx_states;
- CanardTxQueueItem* tx_queue;
- void* user_reference;
- };
- struct CanardRxTransfer
- {
-
- uint64_t timestamp_usec;
-
- const uint8_t* payload_head;
-
-
-
-
- CanardBufferBlock* payload_middle;
-
- const uint8_t* payload_tail;
-
- uint16_t payload_len;
-
- uint16_t data_type_id;
- uint8_t transfer_type;
- uint8_t transfer_id;
- uint8_t priority;
- uint8_t source_node_id;
- };
- void canardInit(CanardInstance* out_ins,
- void* mem_arena,
- size_t mem_arena_size,
- CanardOnTransferReception on_reception,
- CanardShouldAcceptTransfer should_accept,
- void* user_reference);
- void* canardGetUserReference(CanardInstance* ins);
- void canardSetLocalNodeID(CanardInstance* ins,
- uint8_t self_node_id);
- uint8_t canardGetLocalNodeID(const CanardInstance* ins);
- int16_t canardBroadcast(CanardInstance* ins,
- uint64_t data_type_signature,
- uint16_t data_type_id,
- uint8_t* inout_transfer_id,
- uint8_t priority,
- const void* payload,
- uint16_t payload_len);
- int16_t canardRequestOrRespond(CanardInstance* ins,
- uint8_t destination_node_id,
- uint64_t data_type_signature,
- uint8_t data_type_id,
- uint8_t* inout_transfer_id,
- uint8_t priority,
- CanardRequestResponse kind,
- const void* payload,
- uint16_t payload_len);
- const CanardCANFrame* canardPeekTxQueue(const CanardInstance* ins);
- void canardPopTxQueue(CanardInstance* ins);
- int16_t canardHandleRxFrame(CanardInstance* ins,
- const CanardCANFrame* frame,
- uint64_t timestamp_usec);
- void canardCleanupStaleTransfers(CanardInstance* ins,
- uint64_t current_time_usec);
- int16_t canardDecodeScalar(const CanardRxTransfer* transfer,
- uint32_t bit_offset,
- uint8_t bit_length,
- bool value_is_signed,
- void* out_value);
- void canardEncodeScalar(void* destination,
- uint32_t bit_offset,
- uint8_t bit_length,
- const void* value);
- void canardReleaseRxTransferPayload(CanardInstance* ins,
- CanardRxTransfer* transfer);
- CanardPoolAllocatorStatistics canardGetPoolAllocatorStatistics(CanardInstance* ins);
- uint16_t canardConvertNativeFloatToFloat16(float value);
- float canardConvertFloat16ToNativeFloat(uint16_t value);
- CANARD_STATIC_ASSERT(((uint32_t)CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE) < 32,
- "Platforms where sizeof(void*) > 4 are not supported. "
- "On AMD64 use 32-bit mode (e.g. GCC flag -m32).");
- #ifdef __cplusplus
- }
- #endif
- #endif
|