canard.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. /*
  2. * Copyright (c) 2016-2019 UAVCAN Team
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all
  12. * copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. *
  22. * Contributors: https://github.com/UAVCAN/libcanard/contributors
  23. *
  24. * Documentation: http://uavcan.org/Implementations/Libcanard
  25. */
  26. #ifndef CANARD_H
  27. #define CANARD_H
  28. #include <stdint.h>
  29. #include <stddef.h>
  30. #include <stdbool.h>
  31. #include <assert.h>
  32. /// Build configuration header. Use it to provide your overrides.
  33. #if defined(CANARD_ENABLE_CUSTOM_BUILD_CONFIG) && CANARD_ENABLE_CUSTOM_BUILD_CONFIG
  34. # include "canard_build_config.h"
  35. #endif
  36. #ifdef __cplusplus
  37. extern "C" {
  38. #endif
  39. /// Libcanard version. API will be backwards compatible within the same major version.
  40. #define CANARD_VERSION_MAJOR 0
  41. #define CANARD_VERSION_MINOR 2
  42. #ifndef CANARD_ENABLE_CANFD
  43. #define CANARD_ENABLE_CANFD 0
  44. #endif
  45. #ifndef CANARD_MULTI_IFACE
  46. #define CANARD_MULTI_IFACE 0
  47. #endif
  48. #ifndef CANARD_ENABLE_DEADLINE
  49. #define CANARD_ENABLE_DEADLINE 0
  50. #endif
  51. #ifndef CANARD_ENABLE_TAO_OPTION
  52. #if CANARD_ENABLE_CANFD
  53. #define CANARD_ENABLE_TAO_OPTION 1
  54. #else
  55. #define CANARD_ENABLE_TAO_OPTION 0
  56. #endif
  57. #endif
  58. /// By default this macro resolves to the standard assert(). The user can redefine this if necessary.
  59. #ifndef CANARD_ASSERT
  60. #ifdef CANARD_ENABLE_ASSERTS
  61. # define CANARD_ASSERT(x) assert(x)
  62. #else
  63. # define CANARD_ASSERT(x)
  64. #endif
  65. #endif // CANARD_ASSERT
  66. #define CANARD_GLUE(a, b) CANARD_GLUE_IMPL_(a, b)
  67. #define CANARD_GLUE_IMPL_(a, b) a##b
  68. /// By default this macro expands to static_assert if supported by the language (C11, C++11, or newer).
  69. /// The user can redefine this if necessary.
  70. #ifndef CANARD_STATIC_ASSERT
  71. # if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) ||\
  72. (defined(__cplusplus) && (__cplusplus >= 201103L))
  73. # define CANARD_STATIC_ASSERT(...) static_assert(__VA_ARGS__)
  74. # else
  75. # define CANARD_STATIC_ASSERT(x, ...) typedef char CANARD_GLUE(_static_assertion_, __LINE__)[(x) ? 1 : -1]
  76. # endif
  77. #endif
  78. #ifndef CANARD_ALLOCATE_SEM
  79. #define CANARD_ALLOCATE_SEM 0
  80. #endif
  81. /// Error code definitions; inverse of these values may be returned from API calls.
  82. #define CANARD_OK 0
  83. // Value 1 is omitted intentionally, since -1 is often used in 3rd party code
  84. #define CANARD_ERROR_INVALID_ARGUMENT 2
  85. #define CANARD_ERROR_OUT_OF_MEMORY 3
  86. #define CANARD_ERROR_NODE_ID_NOT_SET 4
  87. #define CANARD_ERROR_INTERNAL 9
  88. #define CANARD_ERROR_RX_INCOMPATIBLE_PACKET 10
  89. #define CANARD_ERROR_RX_WRONG_ADDRESS 11
  90. #define CANARD_ERROR_RX_NOT_WANTED 12
  91. #define CANARD_ERROR_RX_MISSED_START 13
  92. #define CANARD_ERROR_RX_WRONG_TOGGLE 14
  93. #define CANARD_ERROR_RX_UNEXPECTED_TID 15
  94. #define CANARD_ERROR_RX_SHORT_FRAME 16
  95. #define CANARD_ERROR_RX_BAD_CRC 17
  96. /// The size of a memory block in bytes.
  97. #if CANARD_ENABLE_CANFD
  98. #define CANARD_MEM_BLOCK_SIZE 128U
  99. #elif CANARD_ENABLE_DEADLINE
  100. #define CANARD_MEM_BLOCK_SIZE 40U
  101. #else
  102. #define CANARD_MEM_BLOCK_SIZE 32U
  103. #endif
  104. #define CANARD_CAN_FRAME_MAX_DATA_LEN 8U
  105. #if CANARD_ENABLE_CANFD
  106. #define CANARD_CANFD_FRAME_MAX_DATA_LEN 64U
  107. #endif
  108. /// Node ID values. Refer to the specification for more info.
  109. #define CANARD_BROADCAST_NODE_ID 0
  110. #define CANARD_MIN_NODE_ID 1
  111. #define CANARD_MAX_NODE_ID 127
  112. /// Refer to the type CanardRxTransfer
  113. #define CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE (CANARD_MEM_BLOCK_SIZE - offsetof(CanardRxState, buffer_head))
  114. /// Refer to the type CanardBufferBlock
  115. #define CANARD_BUFFER_BLOCK_DATA_SIZE (CANARD_MEM_BLOCK_SIZE - offsetof(CanardBufferBlock, data))
  116. /// Refer to canardCleanupStaleTransfers() for details.
  117. #define CANARD_RECOMMENDED_STALE_TRANSFER_CLEANUP_INTERVAL_USEC 1000000U
  118. /// Transfer priority definitions
  119. #define CANARD_TRANSFER_PRIORITY_HIGHEST 0
  120. #define CANARD_TRANSFER_PRIORITY_HIGH 8
  121. #define CANARD_TRANSFER_PRIORITY_MEDIUM 16
  122. #define CANARD_TRANSFER_PRIORITY_LOW 24
  123. #define CANARD_TRANSFER_PRIORITY_LOWEST 31
  124. /// Related to CanardCANFrame
  125. #define CANARD_CAN_EXT_ID_MASK 0x1FFFFFFFU
  126. #define CANARD_CAN_STD_ID_MASK 0x000007FFU
  127. #define CANARD_CAN_FRAME_EFF (1UL << 31U) ///< Extended frame format
  128. #define CANARD_CAN_FRAME_RTR (1UL << 30U) ///< Remote transmission (not used by UAVCAN)
  129. #define CANARD_CAN_FRAME_ERR (1UL << 29U) ///< Error frame (not used by UAVCAN)
  130. #define CANARD_TRANSFER_PAYLOAD_LEN_BITS 10U
  131. #define CANARD_MAX_TRANSFER_PAYLOAD_LEN ((1U << CANARD_TRANSFER_PAYLOAD_LEN_BITS) - 1U)
  132. #ifndef CANARD_64_BIT
  133. #ifdef __WORDSIZE
  134. #define CANARD_64_BIT (__WORDSIZE == 64)
  135. #else
  136. #define CANARD_64_BIT 0
  137. #endif
  138. #endif
  139. /*
  140. canard_buffer_idx_t is used to avoid pointers in data structures
  141. that have to have the same size on both 32 bit and 64 bit
  142. platforms. It is an index into mem_arena passed to canardInit
  143. treated as a uint8_t array
  144. A value of CANARD_BUFFER_IDX_NONE means a NULL pointer
  145. */
  146. #if CANARD_64_BIT
  147. typedef uint32_t canard_buffer_idx_t;
  148. #define CANARD_BUFFER_IDX_NONE 0U
  149. #else
  150. typedef void* canard_buffer_idx_t;
  151. #define CANARD_BUFFER_IDX_NONE NULL
  152. #endif
  153. /**
  154. * This data type holds a standard CAN 2.0B data frame with 29-bit ID.
  155. */
  156. typedef struct
  157. {
  158. /**
  159. * Refer to the following definitions:
  160. * - CANARD_CAN_FRAME_EFF
  161. * - CANARD_CAN_FRAME_RTR
  162. * - CANARD_CAN_FRAME_ERR
  163. */
  164. uint32_t id;
  165. #if CANARD_ENABLE_DEADLINE
  166. uint64_t deadline_usec;
  167. #endif
  168. #if CANARD_ENABLE_CANFD
  169. uint8_t data[CANARD_CANFD_FRAME_MAX_DATA_LEN];
  170. #else
  171. uint8_t data[CANARD_CAN_FRAME_MAX_DATA_LEN];
  172. #endif
  173. uint8_t data_len;
  174. uint8_t iface_id;
  175. #if CANARD_MULTI_IFACE
  176. uint8_t iface_mask;
  177. #endif
  178. #if CANARD_ENABLE_CANFD
  179. bool canfd;
  180. #endif
  181. } CanardCANFrame;
  182. /**
  183. * Transfer types are defined by the UAVCAN specification.
  184. */
  185. typedef enum
  186. {
  187. CanardTransferTypeResponse = 0,
  188. CanardTransferTypeRequest = 1,
  189. CanardTransferTypeBroadcast = 2
  190. } CanardTransferType;
  191. /**
  192. * Types of service transfers. These are not applicable to message transfers.
  193. */
  194. typedef enum
  195. {
  196. CanardResponse,
  197. CanardRequest
  198. } CanardRequestResponse;
  199. /*
  200. * Forward declarations.
  201. */
  202. typedef struct CanardInstance CanardInstance;
  203. typedef struct CanardRxTransfer CanardRxTransfer;
  204. typedef struct CanardRxState CanardRxState;
  205. typedef struct CanardTxQueueItem CanardTxQueueItem;
  206. /**
  207. * This struture provides information about encoded dronecan frame that needs
  208. * to be put on the wire.
  209. *
  210. * In case of broadcast or request pointer to the Transfer ID should point to a persistent variable
  211. * (e.g. static or heap allocated, not on the stack); it will be updated by the library after every transmission.
  212. * The Transfer ID value cannot be shared between transfers that have different descriptors!
  213. * More on this in the transport layer specification.
  214. *
  215. * For the case of response, the pointer to the Transfer ID is treated as const and generally points to transfer id
  216. * in CanardRxTransfer structure.
  217. *
  218. */
  219. typedef struct {
  220. CanardTransferType transfer_type; ///< Type of transfer: CanardTransferTypeBroadcast, CanardTransferTypeRequest, CanardTransferTypeResponse
  221. uint64_t data_type_signature; ///< Signature of the message/service
  222. uint16_t data_type_id; ///< ID of the message/service
  223. uint8_t* inout_transfer_id; ///< Transfer ID reference
  224. uint8_t priority; ///< Priority of the transfer
  225. const uint8_t* payload; ///< Pointer to the payload
  226. uint16_t payload_len; ///< Length of the payload
  227. #if CANARD_ENABLE_CANFD
  228. bool canfd; ///< True if CAN FD is enabled
  229. #endif
  230. #if CANARD_ENABLE_DEADLINE
  231. uint64_t deadline_usec; ///< Deadline in microseconds
  232. #endif
  233. #if CANARD_MULTI_IFACE
  234. uint8_t iface_mask; ///< Bitmask of interfaces to send the transfer on
  235. #endif
  236. #if CANARD_ENABLE_TAO_OPTION
  237. bool tao; ///< True if tail array optimization is enabled
  238. #endif
  239. } CanardTxTransfer;
  240. struct CanardTxQueueItem
  241. {
  242. CanardTxQueueItem* next;
  243. CanardCANFrame frame;
  244. };
  245. CANARD_STATIC_ASSERT(sizeof(CanardTxQueueItem) <= CANARD_MEM_BLOCK_SIZE, "Unexpected memory block size");
  246. /**
  247. * The application must implement this function and supply a pointer to it to the library during initialization.
  248. * The library calls this function to determine whether the transfer should be received.
  249. *
  250. * If the application returns true, the value pointed to by 'out_data_type_signature' must be initialized with the
  251. * correct data type signature, otherwise transfer reception will fail with CRC mismatch error. Please refer to the
  252. * specification for more details about data type signatures. Signature for any data type can be obtained in many
  253. * ways; for example, using the command line tool distributed with Libcanard (see the repository).
  254. */
  255. typedef bool (* CanardShouldAcceptTransfer)(const CanardInstance* ins, ///< Library instance
  256. uint64_t* out_data_type_signature, ///< Must be set by the application!
  257. uint16_t data_type_id, ///< Refer to the specification
  258. CanardTransferType transfer_type, ///< Refer to CanardTransferType
  259. uint8_t source_node_id); ///< Source node ID or Broadcast (0)
  260. /**
  261. * This function will be invoked by the library every time a transfer is successfully received.
  262. * If the application needs to send another transfer from this callback, it is highly recommended
  263. * to call canardReleaseRxTransferPayload() first, so that the memory that was used for the block
  264. * buffer can be released and re-used by the TX queue.
  265. */
  266. typedef void (* CanardOnTransferReception)(CanardInstance* ins, ///< Library instance
  267. CanardRxTransfer* transfer); ///< Ptr to temporary transfer object
  268. /**
  269. * INTERNAL DEFINITION, DO NOT USE DIRECTLY.
  270. * A memory block used in the memory block allocator.
  271. */
  272. typedef union CanardPoolAllocatorBlock_u
  273. {
  274. char bytes[CANARD_MEM_BLOCK_SIZE];
  275. union CanardPoolAllocatorBlock_u* next;
  276. } CanardPoolAllocatorBlock;
  277. /**
  278. * This structure provides usage statistics of the memory pool allocator.
  279. * This data helps to evaluate whether the allocated memory is sufficient for the application.
  280. */
  281. typedef struct
  282. {
  283. uint16_t capacity_blocks; ///< Pool capacity in number of blocks
  284. uint16_t current_usage_blocks; ///< Number of blocks that are currently allocated by the library
  285. uint16_t peak_usage_blocks; ///< Maximum number of blocks used since initialization
  286. } CanardPoolAllocatorStatistics;
  287. /**
  288. * INTERNAL DEFINITION, DO NOT USE DIRECTLY.
  289. * Buffer block for received data.
  290. */
  291. typedef struct CanardBufferBlock
  292. {
  293. struct CanardBufferBlock* next;
  294. uint8_t data[];
  295. } CanardBufferBlock;
  296. /**
  297. * INTERNAL DEFINITION, DO NOT USE DIRECTLY.
  298. */
  299. typedef struct
  300. {
  301. // user should initialize semaphore after the canardInit
  302. // or at first call of canard_allocate_sem_take
  303. void *semaphore;
  304. CanardPoolAllocatorBlock* free_list;
  305. CanardPoolAllocatorStatistics statistics;
  306. void *arena;
  307. } CanardPoolAllocator;
  308. /**
  309. * INTERNAL DEFINITION, DO NOT USE DIRECTLY.
  310. */
  311. struct CanardRxState
  312. {
  313. canard_buffer_idx_t next;
  314. canard_buffer_idx_t buffer_blocks;
  315. uint64_t timestamp_usec;
  316. const uint32_t dtid_tt_snid_dnid;
  317. // We're using plain 'unsigned' here, because C99 doesn't permit explicit field type specification
  318. unsigned calculated_crc : 16;
  319. unsigned payload_len : CANARD_TRANSFER_PAYLOAD_LEN_BITS;
  320. unsigned transfer_id : 5;
  321. unsigned next_toggle : 1; // 16+10+5+1 = 32, aligned.
  322. uint16_t payload_crc;
  323. uint8_t iface_id;
  324. uint8_t buffer_head[];
  325. };
  326. CANARD_STATIC_ASSERT(offsetof(CanardRxState, buffer_head) <= 27, "Invalid memory layout");
  327. CANARD_STATIC_ASSERT(CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE >= 5, "Invalid memory layout");
  328. /**
  329. * This is the core structure that keeps all of the states and allocated resources of the library instance.
  330. * The application should never access any of the fields directly! Instead, API functions should be used.
  331. */
  332. struct CanardInstance
  333. {
  334. uint8_t node_id; ///< Local node ID; may be zero if the node is anonymous
  335. CanardShouldAcceptTransfer should_accept; ///< Function to decide whether the application wants this transfer
  336. CanardOnTransferReception on_reception; ///< Function the library calls after RX transfer is complete
  337. CanardPoolAllocator allocator; ///< Pool allocator
  338. CanardRxState* rx_states; ///< RX transfer states
  339. CanardTxQueueItem* tx_queue; ///< TX frames awaiting transmission
  340. void* user_reference; ///< User pointer that can link this instance with other objects
  341. #if CANARD_ENABLE_TAO_OPTION
  342. bool tao_disabled; ///< True if TAO is disabled
  343. #endif
  344. };
  345. /**
  346. * This structure represents a received transfer for the application.
  347. * An instance of it is passed to the application via callback when the library receives a new transfer.
  348. * Pointers to the structure and all its fields are invalidated after the callback returns.
  349. */
  350. struct CanardRxTransfer
  351. {
  352. /**
  353. * Timestamp at which the first frame of this transfer was received.
  354. */
  355. uint64_t timestamp_usec;
  356. /**
  357. * Payload is scattered across three storages:
  358. * - Head points to CanardRxState.buffer_head (length of which is up to CANARD_PAYLOAD_HEAD_SIZE), or to the
  359. * payload field (possibly with offset) of the last received CAN frame.
  360. *
  361. * - Middle is located in the linked list of dynamic blocks (only for multi-frame transfers).
  362. *
  363. * - Tail points to the payload field (possibly with offset) of the last received CAN frame
  364. * (only for multi-frame transfers).
  365. *
  366. * The tail offset depends on how much data of the last frame was accommodated in the last allocated block.
  367. *
  368. * For single-frame transfers, middle and tail will be NULL, and the head will point at first byte
  369. * of the payload of the CAN frame.
  370. *
  371. * In simple cases it should be possible to get data directly from the head and/or tail pointers.
  372. * Otherwise it is advised to use canardDecodeScalar().
  373. */
  374. const uint8_t* payload_head; ///< Always valid, i.e. not NULL.
  375. ///< For multi frame transfers, the maximum size is defined in the constant
  376. ///< CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE.
  377. ///< For single-frame transfers, the size is defined in the
  378. ///< field payload_len.
  379. CanardBufferBlock* payload_middle; ///< May be NULL if the buffer was not needed. Always NULL for single-frame
  380. ///< transfers.
  381. const uint8_t* payload_tail; ///< Last bytes of multi-frame transfers. Always NULL for single-frame
  382. ///< transfers.
  383. uint16_t payload_len; ///< Effective length of the payload in bytes.
  384. /**
  385. * These fields identify the transfer for the application.
  386. */
  387. uint16_t data_type_id; ///< 0 to 255 for services, 0 to 65535 for messages
  388. uint8_t transfer_type; ///< See CanardTransferType
  389. uint8_t transfer_id; ///< 0 to 31
  390. uint8_t priority; ///< 0 to 31
  391. uint8_t source_node_id; ///< 1 to 127, or 0 if the source is anonymous
  392. #if CANARD_ENABLE_TAO_OPTION
  393. bool tao;
  394. #endif
  395. #if CANARD_ENABLE_CANFD
  396. bool canfd; ///< frame canfd
  397. #endif
  398. };
  399. /**
  400. * Initializes a library instance.
  401. * Local node ID will be set to zero, i.e. the node will be anonymous.
  402. *
  403. * Typically, size of the memory pool should not be less than 1K, although it depends on the application. The
  404. * recommended way to detect the required pool size is to measure the peak pool usage after a stress-test. Refer to
  405. * the function canardGetPoolAllocatorStatistics().
  406. */
  407. void canardInit(CanardInstance* out_ins, ///< Uninitialized library instance
  408. void* mem_arena, ///< Raw memory chunk used for dynamic allocation
  409. size_t mem_arena_size, ///< Size of the above, in bytes
  410. CanardOnTransferReception on_reception, ///< Callback, see CanardOnTransferReception
  411. CanardShouldAcceptTransfer should_accept, ///< Callback, see CanardShouldAcceptTransfer
  412. void* user_reference); ///< Optional pointer for user's convenience, can be NULL
  413. /**
  414. * Returns the value of the user pointer.
  415. * The user pointer is configured once during initialization.
  416. * It can be used to store references to any user-specific data, or to link the instance object with C++ objects.
  417. */
  418. void* canardGetUserReference(const CanardInstance* ins);
  419. /**
  420. * Assigns a new node ID value to the current node.
  421. * Node ID can be assigned only once.
  422. */
  423. void canardSetLocalNodeID(CanardInstance* ins,
  424. uint8_t self_node_id);
  425. /**
  426. * Returns node ID of the local node.
  427. * Returns zero (broadcast) if the node ID is not set, i.e. if the local node is anonymous.
  428. */
  429. uint8_t canardGetLocalNodeID(const CanardInstance* ins);
  430. /**
  431. * Forgets the current node ID value so that a new Node ID can be assigned.
  432. */
  433. void canardForgetLocalNodeID(CanardInstance* ins);
  434. /**
  435. * Initialise TX transfer object.
  436. * Should be called at least once before using transfer object to send transmissions.
  437. */
  438. void canardInitTxTransfer(CanardTxTransfer* transfer);
  439. /**
  440. * Sends a broadcast transfer.
  441. * If the node is in passive mode, only single frame transfers will be allowed (they will be transmitted as anonymous).
  442. *
  443. * For anonymous transfers, maximum data type ID (CanardTxTransfer::data_type_id) is limited to 3 (see specification for details).
  444. *
  445. * Please refer to the specification for more details about data type signatures (CanardTxTransfer::data_type_signature). Signature for
  446. * any data type can be obtained in many ways; for example, using the generated code generated using dronecan_dsdlc (see the repository).
  447. *
  448. * Use CanardTxTransfer structure to pass the transfer parameters. The structure is initialized by the
  449. * canardInitTxTransfer() function.
  450. *
  451. * Pointer to the Transfer ID (CanardTxTransfer::inout_transfer_id) should point to a persistent variable
  452. * (e.g. static or heap allocated, not on the stack); it will be updated by the library after every transmission.
  453. * The Transfer ID value cannot be shared between transfers that have different descriptors!
  454. * More on this in the transport layer specification.
  455. *
  456. * Returns the number of frames enqueued, or negative error code.
  457. */
  458. int16_t canardBroadcastObj(CanardInstance* ins, ///< Library instance
  459. CanardTxTransfer* transfer ///< Transfer object
  460. );
  461. // Legacy API, try to avoid using it, as this will not be extended with new features
  462. int16_t canardBroadcast(CanardInstance* ins, ///< Library instance
  463. uint64_t data_type_signature, ///< See above
  464. uint16_t data_type_id, ///< Refer to the specification
  465. uint8_t* inout_transfer_id, ///< Pointer to a persistent variable containing the transfer ID
  466. uint8_t priority, ///< Refer to definitions CANARD_TRANSFER_PRIORITY_*
  467. const void* payload, ///< Transfer payload
  468. uint16_t payload_len ///< Length of the above, in bytes
  469. #if CANARD_ENABLE_DEADLINE
  470. ,uint64_t tx_deadline ///< Transmission deadline, microseconds
  471. #endif
  472. #if CANARD_MULTI_IFACE
  473. ,uint8_t iface_mask ///< Bitmask of interfaces to transmit on
  474. #endif
  475. #if CANARD_ENABLE_CANFD
  476. ,bool canfd ///< Is the frame canfd
  477. #endif
  478. );
  479. /**
  480. * Sends a request or a response transfer.
  481. * Fails if the node is in passive mode.
  482. *
  483. * Please refer to the specification for more details about data type signatures (CanardTxTransfer::data_type_signature). Signature for
  484. * any data type can be obtained in many ways; for example, using the generated code generated using dronecan_dsdlc (see the repository).
  485. *
  486. * Pointer to the Transfer ID (CanardTxTransfer::inout_transfer_id) should point to a persistent variable
  487. * (e.g. static or heap allocated, not on the stack); it will be updated by the library after every request.
  488. * The Transfer ID value cannot be shared between requests that have different descriptors!
  489. * More on this in the transport layer specification.
  490. *
  491. * For Response transfers, the pointer to the Transfer ID(CanardTxTransfer::inout_transfer_id) will be treated as const (i.e. read-only),
  492. * and normally it should point to the transfer_id field of the structure CanardRxTransfer.
  493. *
  494. * Returns the number of frames enqueued, or negative error code.
  495. */
  496. int16_t canardRequestOrRespondObj(CanardInstance* ins, ///< Library instance
  497. uint8_t destination_node_id, ///< Node ID of the server/client
  498. CanardTxTransfer* transfer ///< Transfer object
  499. );
  500. // Legacy API, try to avoid using it, as this will not be extended with new features
  501. int16_t canardRequestOrRespond(CanardInstance* ins, ///< Library instance
  502. uint8_t destination_node_id, ///< Node ID of the server/client
  503. uint64_t data_type_signature, ///< See above
  504. uint8_t data_type_id, ///< Refer to the specification
  505. uint8_t* inout_transfer_id, ///< Pointer to a persistent variable with transfer ID
  506. uint8_t priority, ///< Refer to definitions CANARD_TRANSFER_PRIORITY_*
  507. CanardRequestResponse kind, ///< Refer to CanardRequestResponse
  508. const void* payload, ///< Transfer payload
  509. uint16_t payload_len ///< Length of the above, in bytes
  510. #if CANARD_ENABLE_DEADLINE
  511. ,uint64_t tx_deadline ///< Transmission deadline, microseconds
  512. #endif
  513. #if CANARD_MULTI_IFACE
  514. ,uint8_t iface_mask ///< Bitmask of interfaces to transmit on
  515. #endif
  516. #if CANARD_ENABLE_CANFD
  517. ,bool canfd ///< Is the frame canfd
  518. #endif
  519. );
  520. /**
  521. * Returns a pointer to the top priority frame in the TX queue.
  522. * Returns NULL if the TX queue is empty.
  523. * The application will call this function after canardBroadcast() or canardRequestOrRespond() to transmit generated
  524. * frames over the CAN bus.
  525. */
  526. CanardCANFrame* canardPeekTxQueue(const CanardInstance* ins);
  527. /**
  528. * Returns the timeout for the frame on top of TX queue.
  529. * Returns zero if the TX queue is empty.
  530. * The application will call this function after canardPeekTxQueue() to determine when to call canardPopTxQueue(), if
  531. * the frame is not transmitted.
  532. */
  533. #if CANARD_ENABLE_DEADLINE
  534. uint64_t canardPeekTxQueueDeadline(const CanardInstance* ins);
  535. #endif
  536. /**
  537. * Removes the top priority frame from the TX queue.
  538. * The application will call this function after canardPeekTxQueue() once the obtained frame has been processed.
  539. * Calling canardBroadcast() or canardRequestOrRespond() between canardPeekTxQueue() and canardPopTxQueue()
  540. * is NOT allowed, because it may change the frame at the top of the TX queue.
  541. */
  542. void canardPopTxQueue(CanardInstance* ins);
  543. /**
  544. * Processes a received CAN frame with a timestamp.
  545. * The application will call this function when it receives a new frame from the CAN bus.
  546. *
  547. * Return value will report any errors in decoding packets.
  548. */
  549. int16_t canardHandleRxFrame(CanardInstance* ins,
  550. const CanardCANFrame* frame,
  551. uint64_t timestamp_usec);
  552. /**
  553. * Traverses the list of transfers and removes those that were last updated more than timeout_usec microseconds ago.
  554. * This function must be invoked by the application periodically, about once a second.
  555. * Also refer to the constant CANARD_RECOMMENDED_STALE_TRANSFER_CLEANUP_INTERVAL_USEC.
  556. */
  557. void canardCleanupStaleTransfers(CanardInstance* ins,
  558. uint64_t current_time_usec);
  559. /**
  560. * This function can be used to extract values from received UAVCAN transfers. It decodes a scalar value -
  561. * boolean, integer, character, or floating point - from the specified bit position in the RX transfer buffer.
  562. * Simple single-frame transfers can also be parsed manually.
  563. *
  564. * Returns the number of bits successfully decoded, which may be less than requested if operation ran out of
  565. * buffer boundaries, or negated error code, such as invalid argument.
  566. *
  567. * Caveat: This function works correctly only on platforms that use two's complement signed integer representation.
  568. * I am not aware of any modern microarchitecture that uses anything else than two's complement, so it should
  569. * not affect portability in any way.
  570. *
  571. * The type of value pointed to by 'out_value' is defined as follows:
  572. *
  573. * | bit_length | value_is_signed | out_value points to |
  574. * |------------|-----------------|------------------------------------------|
  575. * | 1 | false | bool (may be incompatible with uint8_t!) |
  576. * | 1 | true | N/A |
  577. * | [2, 8] | false | uint8_t, or char |
  578. * | [2, 8] | true | int8_t, or char |
  579. * | [9, 16] | false | uint16_t |
  580. * | [9, 16] | true | int16_t |
  581. * | [17, 32] | false | uint32_t |
  582. * | [17, 32] | true | int32_t, or 32-bit float |
  583. * | [33, 64] | false | uint64_t |
  584. * | [33, 64] | true | int64_t, or 64-bit float |
  585. */
  586. int16_t canardDecodeScalar(const CanardRxTransfer* transfer, ///< The RX transfer where the data will be copied from
  587. uint32_t bit_offset, ///< Offset, in bits, from the beginning of the transfer
  588. uint8_t bit_length, ///< Length of the value, in bits; see the table
  589. bool value_is_signed, ///< True if the value can be negative; see the table
  590. void* out_value); ///< Pointer to the output storage; see the table
  591. /**
  592. * This function can be used to encode values for later transmission in a UAVCAN transfer. It encodes a scalar value -
  593. * boolean, integer, character, or floating point - and puts it to the specified bit position in the specified
  594. * contiguous buffer.
  595. * Simple single-frame transfers can also be encoded manually.
  596. *
  597. * Caveat: This function works correctly only on platforms that use two's complement signed integer representation.
  598. * I am not aware of any modern microarchitecture that uses anything else than two's complement, so it should
  599. * not affect portability in any way.
  600. *
  601. * The type of value pointed to by 'value' is defined as follows:
  602. *
  603. * | bit_length | value points to |
  604. * |------------|------------------------------------------|
  605. * | 1 | bool (may be incompatible with uint8_t!) |
  606. * | [2, 8] | uint8_t, int8_t, or char |
  607. * | [9, 16] | uint16_t, int16_t |
  608. * | [17, 32] | uint32_t, int32_t, or 32-bit float |
  609. * | [33, 64] | uint64_t, int64_t, or 64-bit float |
  610. */
  611. void canardEncodeScalar(void* destination, ///< Destination buffer where the result will be stored
  612. uint32_t bit_offset, ///< Offset, in bits, from the beginning of the destination buffer
  613. uint8_t bit_length, ///< Length of the value, in bits; see the table
  614. const void* value); ///< Pointer to the value; see the table
  615. /**
  616. * This function can be invoked by the application to release pool blocks that are used
  617. * to store the payload of the transfer.
  618. *
  619. * If the application needs to send new transfers from the transfer reception callback, this function should be
  620. * invoked right before calling canardBroadcast() or canardRequestOrRespond(). Not releasing the buffers before
  621. * transmission may cause higher peak usage of the memory pool.
  622. *
  623. * If the application didn't call this function before returning from the callback, the library will do that,
  624. * so it is guaranteed that the memory will not leak.
  625. */
  626. void canardReleaseRxTransferPayload(CanardInstance* ins,
  627. CanardRxTransfer* transfer);
  628. /**
  629. * Returns a copy of the pool allocator usage statistics.
  630. * Refer to the type CanardPoolAllocatorStatistics.
  631. * Use this function to determine worst case memory needs of your application.
  632. */
  633. CanardPoolAllocatorStatistics canardGetPoolAllocatorStatistics(CanardInstance* ins);
  634. /**
  635. * Float16 marshaling helpers.
  636. * These functions convert between the native float and 16-bit float.
  637. * It is assumed that the native float is IEEE 754 single precision float, otherwise results will be unpredictable.
  638. * Vast majority of modern computers and microcontrollers use IEEE 754, so this limitation should not affect
  639. * portability.
  640. */
  641. uint16_t canardConvertNativeFloatToFloat16(float value);
  642. float canardConvertFloat16ToNativeFloat(uint16_t value);
  643. uint16_t extractDataType(uint32_t id);
  644. CanardTransferType extractTransferType(uint32_t id);
  645. /// Abort the build if the current platform is not supported.
  646. #if CANARD_ENABLE_CANFD
  647. CANARD_STATIC_ASSERT(((uint32_t)CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE) < 128,
  648. "Please define CANARD_64_BIT=1 for 64 bit builds");
  649. #else
  650. CANARD_STATIC_ASSERT(((uint32_t)CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE) < 32,
  651. "Please define CANARD_64_BIT=1 for 64 bit builds");
  652. #endif
  653. #if CANARD_ALLOCATE_SEM
  654. // user implemented functions for taking and freeing semaphores
  655. void canard_allocate_sem_take(CanardPoolAllocator *allocator);
  656. void canard_allocate_sem_give(CanardPoolAllocator *allocator);
  657. #endif
  658. #ifdef __cplusplus
  659. }
  660. #endif
  661. #endif