Skip to content

Commit

Permalink
Fix: OD generator: addEntry type size is not enforced, leading to siz…
Browse files Browse the repository at this point in the history
…e mismatch.
  • Loading branch information
Philippe Leduc committed Dec 11, 2024
1 parent 748477f commit 4e5aeaf
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 68 deletions.
133 changes: 131 additions & 2 deletions examples/slave/nuttx/xmc4800/boards/wdc_foot/foot.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
</Info>
<GroupType>XMC4800 Wandercraft</GroupType>
<Profile>
<ProfileNo>402</ProfileNo>
<!-- Profile custom -->
<ProfileNo>0</ProfileNo>
<!-- Dictionnary -->
<Dictionary>

Expand Down Expand Up @@ -157,6 +158,79 @@
</SubItem>
</DataType>

<DataType>
<Name>DT1C12</Name>
<BitSize>32</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Subindex 000</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access WriteRestrictions="PreOP">rw</Access>
<Category>o</Category>
<Backup>0</Backup>
<Setting>0</Setting>
</Flags>
</SubItem>
<SubItem>
<Name>Elements</Name>
<Type>DT1C12ARR</Type>
<BitSize>16</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access WriteRestrictions="PreOP">rw</Access>
<Category>o</Category>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1C12ARR</Name>
<BaseType>UINT</BaseType>
<BitSize>16</BitSize>
<ArrayInfo>
<LBound>1</LBound>
<Elements>1</Elements>
</ArrayInfo>
</DataType>
<DataType>
<Name>DT1C13</Name>
<BitSize>32</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Subindex 000</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access WriteRestrictions="PreOP">rw</Access>
<Category>o</Category>
<Backup>0</Backup>
<Setting>0</Setting>
</Flags>
</SubItem>
<SubItem>
<Name>Elements</Name>
<Type>DT1C13ARR</Type>
<BitSize>16</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access WriteRestrictions="PreOP">rw</Access>
<Category>o</Category>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1C13ARR</Name>
<BaseType>UINT</BaseType>
<BitSize>16</BitSize>
<ArrayInfo>
<LBound>1</LBound>
<Elements>1</Elements>
</ArrayInfo>
</DataType>

<DataType>
<Name>DT2000</Name> <!-- Value ?-->
<BitSize>80</BitSize>
Expand Down Expand Up @@ -204,7 +278,21 @@

<!-- Objects -->
<Objects>

<Object>
<Index>#x1000</Index>
<Name>Device Type</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<Info>
<DefaultData>00000000</DefaultData>
</Info>
<Flags>
<Access>ro</Access>
<Category>m</Category>
<Backup>0</Backup>
<Setting>0</Setting>
</Flags>
</Object>
<Object>
<Index>#x1018</Index>
<Name>Identity Object</Name>
Expand Down Expand Up @@ -244,6 +332,47 @@
</Info>
</Object>

<Object>
<Index>#x1c12</Index>
<Name>RxPDO assign</Name>
<Type>DT1C12</Type>
<BitSize>32</BitSize>
<Info>
<SubItem>
<Name>Subindex 000</Name>
<Info>
<DefaultData>01</DefaultData>
</Info>
</SubItem>
<SubItem>
<Name>RxPDO assign Element 1</Name>
<Info>
<DefaultData>0016</DefaultData>
</Info>
</SubItem>
</Info>
</Object>
<Object>
<Index>#x1c13</Index>
<Name>TxPDO assign</Name>
<Type>DT1C13</Type>
<BitSize>32</BitSize>
<Info>
<SubItem>
<Name>Subindex 000</Name>
<Info>
<DefaultData>01</DefaultData>
</Info>
</SubItem>
<SubItem>
<Name>TxPDO assign Element 1</Name>
<Info>
<DefaultData>001a</DefaultData>
</Info>
</SubItem>
</Info>
</Object>

<Object>
<Index>#x2000</Index>
<Name>FreezeValue</Name>
Expand Down
58 changes: 35 additions & 23 deletions examples/slave/nuttx/xmc4800/od_populator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,31 @@ namespace kickcat::CoE
{
CoE::Dictionary dictionary;

{
CoE::Object object
{
0x1000,
CoE::ObjectCode::VAR,
"Device Type",
{}
};
CoE::addEntry<uint32_t>(object,0,32,0,7,static_cast<CoE::DataType>(7),"",0x0);
dictionary.push_back(std::move(object));
}

{
CoE::Object object
{
0x1018,
CoE::ObjectCode::ARRAY,
CoE::ObjectCode::RECORD,
"Identity Object",
{}
};
CoE::addEntry(object,0,8,0,7,static_cast<CoE::DataType>(5),"Subindex 000",0x4);
CoE::addEntry(object,1,32,16,7,static_cast<CoE::DataType>(7),"Vendor ID",0x6a5);
CoE::addEntry(object,2,32,48,7,static_cast<CoE::DataType>(7),"Product code",0xb0cad0);
CoE::addEntry(object,3,32,80,7,static_cast<CoE::DataType>(7),"Revision number",0x0);
CoE::addEntry(object,4,32,112,7,static_cast<CoE::DataType>(7),"Serial number",0xcafedeca);
CoE::addEntry<uint8_t>(object,0,8,0,7,static_cast<CoE::DataType>(5),"Subindex 000",0x4);
CoE::addEntry<uint32_t>(object,1,32,16,7,static_cast<CoE::DataType>(7),"Vendor ID",0x6a5);
CoE::addEntry<uint32_t>(object,2,32,48,7,static_cast<CoE::DataType>(7),"Product code",0xb0cad0);
CoE::addEntry<uint32_t>(object,3,32,80,7,static_cast<CoE::DataType>(7),"Revision number",0x0);
CoE::addEntry<uint32_t>(object,4,32,112,7,static_cast<CoE::DataType>(7),"Serial number",0xcafedeca);
dictionary.push_back(std::move(object));
}

Expand All @@ -32,8 +44,8 @@ namespace kickcat::CoE
"RxPDO Map 1",
{}
};
CoE::addEntry(object,0,8,0,15,static_cast<CoE::DataType>(5),"Subindex 000",0x1);
CoE::addEntry(object,1,32,16,15,static_cast<CoE::DataType>(7),"RxPDO Map 1 Element 1",0x10);
CoE::addEntry<uint8_t>(object,0,8,0,15,static_cast<CoE::DataType>(5),"Subindex 000",0x1);
CoE::addEntry<uint32_t>(object,1,32,16,15,static_cast<CoE::DataType>(7),"RxPDO Map 1 Element 1",0x10);
dictionary.push_back(std::move(object));
}

Expand All @@ -45,8 +57,8 @@ namespace kickcat::CoE
"TxPDO Map 1",
{}
};
CoE::addEntry(object,0,8,0,15,static_cast<CoE::DataType>(5),"Subindex 000",0x1);
CoE::addEntry(object,1,32,16,15,static_cast<CoE::DataType>(7),"TxPDO Map 1 Element 1",0xe0);
CoE::addEntry<uint8_t>(object,0,8,0,15,static_cast<CoE::DataType>(5),"Subindex 000",0x1);
CoE::addEntry<uint32_t>(object,1,32,16,15,static_cast<CoE::DataType>(7),"TxPDO Map 1 Element 1",0xe0);
dictionary.push_back(std::move(object));
}

Expand All @@ -58,11 +70,11 @@ namespace kickcat::CoE
"Sync manager type",
{}
};
CoE::addEntry(object,0,8,0,7,static_cast<CoE::DataType>(5),"Subindex 0",0x4);
CoE::addEntry(object,1,8,16,7,static_cast<CoE::DataType>(5),"Subindex 1",0x1);
CoE::addEntry(object,2,8,24,7,static_cast<CoE::DataType>(5),"Subindex 2",0x2);
CoE::addEntry(object,3,8,32,7,static_cast<CoE::DataType>(5),"Subindex 3",0x3);
CoE::addEntry(object,4,8,40,7,static_cast<CoE::DataType>(5),"Subindex 4",0x4);
CoE::addEntry<uint8_t>(object,0,8,0,7,static_cast<CoE::DataType>(5),"Subindex 0",0x4);
CoE::addEntry<uint32_t>(object,1,8,16,7,static_cast<CoE::DataType>(5),"Subindex 1",0x1);
CoE::addEntry<uint32_t>(object,2,8,24,7,static_cast<CoE::DataType>(5),"Subindex 2",0x2);
CoE::addEntry<uint32_t>(object,3,8,32,7,static_cast<CoE::DataType>(5),"Subindex 3",0x3);
CoE::addEntry<uint32_t>(object,4,8,40,7,static_cast<CoE::DataType>(5),"Subindex 4",0x4);
dictionary.push_back(std::move(object));
}

Expand All @@ -74,8 +86,8 @@ namespace kickcat::CoE
"RxPDO assign",
{}
};
CoE::addEntry(object,0,8,0,15,static_cast<CoE::DataType>(5),"Subindex 000",0x1);
CoE::addEntry(object,1,32,16,15,static_cast<CoE::DataType>(7),"RxPDO assign Element 1",0x1600);
CoE::addEntry<uint8_t>(object,0,8,0,15,static_cast<CoE::DataType>(5),"Subindex 000",0x1);
CoE::addEntry<uint16_t>(object,1,16,16,15,static_cast<CoE::DataType>(6),"RxPDO assign Element 1",0x1600);
dictionary.push_back(std::move(object));
}

Expand All @@ -87,22 +99,22 @@ namespace kickcat::CoE
"TxPDO assign",
{}
};
CoE::addEntry(object,0,8,0,15,static_cast<CoE::DataType>(5),"Subindex 000",0x1);
CoE::addEntry(object,1,32,16,15,static_cast<CoE::DataType>(7),"TxPDO assign Element 1",0x1a00);
CoE::addEntry<uint8_t>(object,0,8,0,15,static_cast<CoE::DataType>(5),"Subindex 000",0x1);
CoE::addEntry<uint16_t>(object,1,16,16,15,static_cast<CoE::DataType>(6),"TxPDO assign Element 1",0x1a00);
dictionary.push_back(std::move(object));
}

{
CoE::Object object
{
0x2000,
CoE::ObjectCode::ARRAY,
CoE::ObjectCode::RECORD,
"FreezeValue",
{}
};
CoE::addEntry(object,0,8,0,7,static_cast<CoE::DataType>(5),"Subindex 000",0x2);
CoE::addEntry(object,1,32,16,63,static_cast<CoE::DataType>(7),"ForceSensor0",0x2);
CoE::addEntry(object,2,32,48,63,static_cast<CoE::DataType>(7),"IMU",0x2);
CoE::addEntry<uint8_t>(object,0,8,0,7,static_cast<CoE::DataType>(5),"Subindex 000",0x2);
CoE::addEntry<uint32_t>(object,1,32,16,63,static_cast<CoE::DataType>(7),"ForceSensor0",0x2);
CoE::addEntry<uint32_t>(object,2,32,48,63,static_cast<CoE::DataType>(7),"IMU",0x2);
dictionary.push_back(std::move(object));
}

Expand Down
12 changes: 8 additions & 4 deletions lib/include/kickcat/CoE/OD.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ namespace kickcat::CoE

std::string dataToString() const;
};
std::string toString(Entry const& entry);

struct Object // ETG1000.5 6.1.4.2.1 Formal model
{
Expand All @@ -223,16 +224,19 @@ namespace kickcat::CoE
uint16_t access, DataType type, std::string const& description, T data)
{
object.entries.emplace_back(subindex, bitlen, bitoff, access, type, description);
auto& alloc = object.entries.back().data;
std::size_t size = bitlen / 8;
alloc = std::malloc(size);

if constexpr(std::is_same_v<const char*, T>)
{
object.entries.back().data = malloc(bitlen/8);
memcpy(object.entries.back().data, data, bitlen/8);
std::memcpy(alloc, data, size);
}
else
{
T* dataAlloc = new T(data);
object.entries.back().data = dataAlloc;
std::memcpy(alloc, &data, size);
}

}

Dictionary createOD();
Expand Down
14 changes: 9 additions & 5 deletions lib/src/CoE/EsiParser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -271,13 +271,12 @@ namespace kickcat::CoE
auto it = BASIC_TYPES.find(node_type->GetText());
if (it != BASIC_TYPES.end())
{
uint16_t bitlen = atoi(node->FirstChildElement("BitSize")->GetText());

uint16_t bitlen = toNumber<uint16_t>(node->FirstChildElement("BitSize"));
uint16_t bitoff = 0;
auto node_bitoff = node->FirstChildElement("BitOffs");
if (node_bitoff)
{
bitoff = atoi(node->FirstChildElement("BitOffs")->GetText());
bitoff = toNumber<uint16_t>(node_bitoff);
}

return {it->second, bitlen, bitoff};
Expand Down Expand Up @@ -385,9 +384,14 @@ namespace kickcat::CoE
{
// array entries are the subindex starting from 1, 0 is the array size
uint8_t elements = toNumber<uint8_t>(node_array_info->FirstChildElement("Elements"));
for (uint8_t i = 0; i < elements; ++i)
uint16_t element_bitlen = toNumber<uint16_t>(node_subitem->FirstChildElement("BitSize"));
uint16_t element_bitoff = toNumber<uint16_t>(node_subitem->FirstChildElement("BitOffs"));

for (uint8_t i = 1; i <= elements; ++i)
{
entry.subindex = i + 1;
entry.bitlen = element_bitlen;
entry.bitoff = element_bitoff * i;
entry.subindex = i;
object.entries.push_back(std::move(entry));
}
}
Expand Down
Loading

0 comments on commit 4e5aeaf

Please sign in to comment.