Homepage GitHub

Custom message signature fail

(Sergey Frolov) #1

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.


(Pavel Kirienko) #2

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).

(Sergey Frolov) #3

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.

(Pavel Kirienko) #4

Let’s have a look at your code.

(Sergey Frolov) #5

Ok. I hava a message template, described as:

uint8 id

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;


	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

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

(Sergey Frolov) #6

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);

(Pavel Kirienko) #7

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

(Sergey Frolov) #8

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?

(Pavel Kirienko) #9

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/