From 94c037416577d196d7396a3365f8ff88ffac6e37 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 19 May 2018 17:39:26 +0300 Subject: [PATCH 1/3] Fixed the union code generation: if the union contained a power of two number of items, the tag bit length was one higher than needed, causing incorrect serialization. --- .../libuavcan_dsdl_compiler/data_type_template.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/data_type_template.tmpl b/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/data_type_template.tmpl index 2b0acbf8e9..3107426bf0 100644 --- a/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/data_type_template.tmpl +++ b/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/data_type_template.tmpl @@ -70,7 +70,7 @@ struct UAVCAN_EXPORT ${t.cpp_type_name} }; }; - typedef ::uavcan::IntegerSpec< ::uavcan::IntegerBitLen< ${len(fields)} >::Result, + typedef ::uavcan::IntegerSpec< ::uavcan::IntegerBitLen< ${len(fields)}U - 1U >::Result, ::uavcan::SignednessUnsigned, ::uavcan::CastModeTruncate > TagType; #! enum_name, enum_comparator From 53e33d01f7f39a16048d04fe23d131bc6419d3b8 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 19 May 2018 17:52:07 +0300 Subject: [PATCH 2/3] Unit test for the previous commit --- .../dsdl_test/dsdl_uavcan_compilability.cpp | 33 +++++++++++++++++++ .../dsdl_test/root_ns_a/UnionTest4.uavcan | 6 ++++ 2 files changed, 39 insertions(+) create mode 100644 libuavcan/test/dsdl_test/root_ns_a/UnionTest4.uavcan diff --git a/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp b/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp index 8fc57ac7fb..5643ade02d 100644 --- a/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp +++ b/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp @@ -22,6 +22,7 @@ #include #include +#include template static bool validateYaml(const T& obj, const std::string& reference) @@ -200,6 +201,38 @@ TEST(Dsdl, Union) } + +TEST(Dsdl, UnionTagWidth) +{ + using root_ns_a::UnionTest4; + + ASSERT_EQ(2, UnionTest4::MinBitLen); + ASSERT_EQ(8, UnionTest4::MaxBitLen); + + UnionTest4 s; + + { + uavcan::StaticTransferBuffer<100> buf; + uavcan::BitStream bs_wr(buf); + uavcan::ScalarCodec sc_wr(bs_wr); + + ASSERT_EQ(1, UnionTest4::encode(s, sc_wr)); + ASSERT_EQ("00000000", bs_wr.toString()); + } + + { + uavcan::StaticTransferBuffer<100> buf; + uavcan::BitStream bs_wr(buf); + uavcan::ScalarCodec sc_wr(bs_wr); + + s.to() = 1U << 5U; // 32, 0b100000 + + ASSERT_EQ(1, UnionTest4::encode(s, sc_wr)); + ASSERT_EQ("10100000", bs_wr.toString()); + } +} + + TEST(Dsdl, ParamGetSetRequestUnion) { uavcan::protocol::param::GetSet::Request req; diff --git a/libuavcan/test/dsdl_test/root_ns_a/UnionTest4.uavcan b/libuavcan/test/dsdl_test/root_ns_a/UnionTest4.uavcan new file mode 100644 index 0000000000..05bfb5c98c --- /dev/null +++ b/libuavcan/test/dsdl_test/root_ns_a/UnionTest4.uavcan @@ -0,0 +1,6 @@ +# A union of four items; tag 2 bits wide, total length 1 byte +@union # 2 bits +Empty first # Tag value 0 +uint5 second # Tag value 1 +uint6 third # Tag value 2 +int2 fourth # Tag value 3 From e096e33bb61d18b7f0adeefb6cd1f0b6a82ce385 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 19 May 2018 17:57:40 +0300 Subject: [PATCH 3/3] Formatting fix --- libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp b/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp index 5643ade02d..079ab96e29 100644 --- a/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp +++ b/libuavcan/test/dsdl_test/dsdl_uavcan_compilability.cpp @@ -201,7 +201,6 @@ TEST(Dsdl, Union) } - TEST(Dsdl, UnionTagWidth) { using root_ns_a::UnionTest4;