danny wang a136536ff5 watchrobot first commit | 2 rokov pred | |
---|---|---|
.. | ||
libcanard_dsdl_compiler | 2 rokov pred | |
pyuavcan | 2 rokov pred | |
README.md | 2 rokov pred | |
libcanard_dsdlc | 2 rokov pred |
Libcanard_dsdlc is a tool for converting UAVCAN DSDL definitions into libcanard-compatible C source files or headers.
Modules have: defines, enums, unions, structs, and encoding/decoding functions as defined in UAVCAN DSDL. Encoding and decoding functions use the encode and decode functions of libcanard for bit packing/unpacking.
In C there is no namespace, so all the generated #define
and function names are long having full folder path included.
This is made to prevent collisions with each other and with the rest of the system.
To get libcanard from git, make sure all the submodules are fetched too.
git submodules update --init --recursive
python3 libcanard_dsdlc --outdir <outdir> <dsdl-definition-uavcan-folder>
Add all or only selected message C-files to your build script (e.g. Makefile).
Add <dsdl-generate-output-folder>
to your include paths.
python3 libcanard_dsdlc --header_only --outdir <outdir> <dsdl-definition-uavcan-folder>
Include wanted message header(s) into your code.
Add <dsdl-generate-output-folder>
to your include paths.
Generated structs use the native float
type for float16
.
The native float
is converted to float16
using libcanard's canardConvertNativeFloatToFloat16()
when encoding.
Calling decode function after reception will convert float16
to the native float
using the libcanard's
canardConvertFloat16ToNativeFloat()
function.
Libcanard conversion functions can be replaced to compiler casting if wanted,
e.g. #define CANARD_USE_FLOAT16_CAST __fp16
.
#include "uavcan/protocol/NodeStatus.h"
/* Reserve memory and struct for messages */
uint8_t packed_uavcan_msg_buf[UAVCAN_PROTOCOL_NODESTATUS_MAX_SIZE];
/* MAX_SIZE comes from module header as pre-calculated */
uavcan_protocol_NodeStatus msg;
msg.uptime_sec = getUptime();
msg.health = UAVCAN_PROTOCOL_NODESTATUS_HEALTH_OK;
msg.mode = UAVCAN_PROTOCOL_NODESTATUS_MODE_OPERATIONAL;
msg.sub_mode = sub_mode;
msg.vendor_specific_status_code = vendor_status_code;
/* Encode the filled struct into packed_uavcan_msg_buf, ready to be sent */
const uint32_t len_of_packed_msg = uavcan_protocol_NodeStatus_encode(&msg, packed_uavcan_msg_buf);
(void) canardBroadcast(&g_canard,
UAVCAN_PROTOCOL_NODESTATUS_SIGNATURE,
UAVCAN_PROTOCOL_NODESTATUS_ID,
&g_bc_node_status_transfer_id,
CANARD_TRANSFER_PRIORITY_MEDIUM,
packed_uavcan_msg_buf,
len_of_packed_msg);
Dynamic arrays also have the _len
field,
which specifies how many data items are accessible via the dynamic array pointer.
/* include header */
#include "uavcan/protocol/param/GetSet.h"
#define GETSETREQ_NAME_MAX_SIZE 96 // max size needed for the dynamic arrays
/* Reserve some memory for the dynamic arrays from the stack */
uint8_t buff[GETSETREQ_NAME_MAX_SIZE];
uint8_t* dyn_buf_ptr = buff;
/* Reserve struct */
uavcan_protocol_param_GetSetRequest get_set_req;
/* NOTE get_set_req struct will be cleared in the Decode function first */
(void) uavcan_protocol_param_GetSetRequest_decode(transfer,
(uint16_t)transfer->payload_len,
&get_set_req,
&dyn_buf_ptr);
/* Now the struct get_set_req "object" is ready to be used */
dyn_buf_ptr
is a way to give allocated memory to the Decode function,
to use that space to store dynamic arrays into it, and store the pointer to struct pointer.
NOTE: There is no check whether dynamic memory allocation is sufficient.
Released under the MIT license, check the file LICENSE.