Hello. I use Libcanard with STM32F4. And I compiled my own custom message. GUI looks it fine.
I have no troubles when I send messages less than 7 bytes, but when I try to send more bytes per 1 message, bus monitor print this:
“CRC mismatch: expected 697d, got 57b5…”
In canard core I see that crc calculated using ‘signature’-field (if size > 7 bytes). It seems, that calculated signature (through dsdl) is wrong. How can I calculate it correct (manually)?? So GUI tool still send errors.
Thanks
The most likely reason is that the message definition used by the GUI tool differs from the one used by your libcanard-based system. Please ensure that the definitions are exactly identical.
Also, you can’t define vendor-specific messages inside the UAVCAN namespace. You should use a separate root namespace for your custom data types (although this is not directly related to your question).
Thanks. But this works fine in another board with Nuttx and libuavcan. That says that signature-field is correct. And we able to include own message to uavcan-namespace… Hm… As for libcanard, troubles are still not solved.
Let’s have a look at your code.
Ok. I hava a message template, described as:
uint8 id
void5
UvrValue value
where UveValue is:
@union # Tag is 3 bit long, so outer structure has 5-bit prefix to ensure proper alignment
uint8 bool_value
int8 byte_value # 8-bit value is used for alignment reasons
int16 short_value
int32 integer_value
int64 long_value
And function, where I try to send int64 value (tag=4 from union above)
uint8_t n = 0;
uint8_t tag=4;
int offset = 0;
uint8_t buffer[32];
static uint8_t transferId = 0;
uint8_t id=1;
int64_t abs= 0x0000FF55;
memset(buffer,0x00,32);
canardEncodeScalar(buffer, offset, 8, &id); //id
offset += 8;
canardEncodeScalar(buffer, offset, 5, &n); //void5 offset
offset += 5;
canardEncodeScalar(buffer, offset, 3, &tag); //tag to union member
offset += 3;
canardEncodeScalar(buffer, offset, 64, &abs); //int64 value
canardBroadcast(&g_canard,
UVR_ARRAY_SIGNATURE,
UVR_ARRAY_ID,
&transferId,
CANARD_TRANSFER_PRIORITY_HIGH,
buffer,
10);
I have doubts for last argument of canardBroadcast (length of packet), but I see - 8+5(void)+3+64=80 (10 bytes). But CRC is calculated with fail.
If i try send for example int32 value (tag=3), length=6 (<7) than the transmission is OK
So, it seems that signature is wrong. In libuavcan i cannot find using of signature-field in ‘add_crc’-function (in contrast of libcanard). Libuavcan uses separate CRC-table (not Signature-field)
That’s why libuavcan works fine… I’m clearly sure, that signature is wrong. And CRC-value also returns with fail
if (payload_len > 7)
{
crc = crcAddSignature(crc, data_type_signature);
crc = crcAdd(crc, payload, payload_len);
}
Yes, indeed, the serialization code seems correct; you need to check the value of UVR_ARRAY_SIGNATURE
. You can use this script to compute and display the signature: https://github.com/UAVCAN/libcanard/blob/master/show_data_type_info.py
Good day!! O, great thanks.! I launched script and got a valid ‘signature’-field for my message. And now it works clearly fine.
I want specify this moment (from replies below):
“Also, you can’t define vendor-specific messages inside the UAVCAN namespace. You should use a separate root namespace for your custom data types.”
I little confused …how can I define my own namespace? I see extension of file like *.uavcan. Is it means that i need use another extension (as own namespace) for custom messages?
Nope, you still use the same *.uavcan
extension but you put your files into a separate root namespace. This tutorial here should clarify things (ignore the fact that it’s written for libuavcan; same principles apply for any implementation): https://uavcan.org/Implementations/Libuavcan/Tutorials/8._Custom_data_types/