Added derived peripherals, fixed line endings, fixed display()

This commit is contained in:
Łukasz Czyż 2019-11-15 12:42:48 +01:00
parent 5fa14dbc99
commit f2f00aad77
4 changed files with 307 additions and 289 deletions

View file

@ -22,12 +22,12 @@ struct Field : public IDisplay{
unsigned int bitWidth; unsigned int bitWidth;
EAccess fieldAccess; EAccess fieldAccess;
void display() final{ void display() final{
std::cout << std::endl std::cout << "\t\tname: " << name << std::endl
<< "\t\tname: " << name << std::endl
<< "\t\tdescription: " << description << std::endl << "\t\tdescription: " << description << std::endl
<< "\t\tbitOffset: " << bitOffset << std::endl << "\t\tbitOffset: " << bitOffset << std::endl
<< "\t\tbitWidth: " << bitWidth << std::endl << "\t\tbitWidth: " << bitWidth << std::endl
<< "\t\tfieldAccess: " << (int)fieldAccess << std::endl; << "\t\tfieldAccess: " << (int)fieldAccess << std::endl
<< std::endl;
} }
}; };
@ -41,15 +41,14 @@ struct Register : public IDisplay{
std::vector<Field> fields; std::vector<Field> fields;
void display() final{ void display() final{
std::cout << std::endl std::cout << "\tname: " << name << std::endl
<< "\tname: " << name << std::endl
<< "\tdescription: " << description << std::endl << "\tdescription: " << description << std::endl
<< "\taddressOffset: " << addressOffset << std::endl << "\taddressOffset: " << addressOffset << std::endl
<< "\tsize: " << size << std::endl << "\tsize: " << size << std::endl
<< "\tregisterAccess: " << (int)registerAccess << std::endl << "\tregisterAccess: " << (int)registerAccess << std::endl
<< "\tresetValue: " << resetValue << std::endl; << "\tresetValue: " << resetValue << std::endl;
std::cout << std::endl << "\tfields: " << std::endl; std::cout << "\tfields: " << std::endl;
for(auto& i : fields){ for(auto& i : fields){
i.display(); i.display();
} }
@ -81,7 +80,7 @@ struct Peripheral : public IDisplay{
<< "baseAddress: " << baseAddress << std::endl << "baseAddress: " << baseAddress << std::endl
<< "addressBlock: "; << "addressBlock: ";
addressBlock.display(); addressBlock.display();
std::cout << std::endl << "registers: " << std::endl; std::cout << "registers: " << std::endl;
for(auto& i : registers){ for(auto& i : registers){
i.display(); i.display();
} }

View file

@ -1,6 +1,6 @@
#include <XmlParser.hpp> #include <XmlParser.hpp>
#include <iostream> #include <iostream>
#include <algorithm>
XmlParser::XmlParser(const std::string& inputFile){ XmlParser::XmlParser(const std::string& inputFile){
xmlDocument.LoadFile(inputFile.c_str()); xmlDocument.LoadFile(inputFile.c_str());
@ -39,16 +39,16 @@ void XmlParser::parseXml(){
} }
} }
void XmlParser::setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char* name, std::string &field){ void XmlParser::setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char* name, std::string &field) const{
tinyxml2::XMLElement* deviceEntry = deviceRoot->FirstChildElement(name); tinyxml2::XMLElement* deviceEntry = deviceRoot->FirstChildElement(name);
field = deviceEntry != nullptr ? deviceEntry->GetText() : noValue; field = deviceEntry != nullptr ? deviceEntry->GetText() : noValue;
} }
void XmlParser::setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char* name, unsigned int &field){ void XmlParser::setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char* name, unsigned int &field) const{
tinyxml2::XMLElement* deviceEntry = deviceRoot->FirstChildElement(name); tinyxml2::XMLElement* deviceEntry = deviceRoot->FirstChildElement(name);
field = deviceEntry != nullptr ? std::stol(deviceEntry->GetText(), 0, 16) : 0; field = deviceEntry != nullptr ? std::stol(deviceEntry->GetText(), 0, 16) : 0;
} }
void XmlParser::setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char* name, EAccess &field){ void XmlParser::setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char* name, EAccess &field) const{
tinyxml2::XMLElement* deviceEntry = deviceRoot->FirstChildElement(name); tinyxml2::XMLElement* deviceEntry = deviceRoot->FirstChildElement(name);
if(deviceEntry == nullptr){ if(deviceEntry == nullptr){
field = EAccess::Read_Write; field = EAccess::Read_Write;
@ -68,14 +68,32 @@ void XmlParser::setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char
std::cout << "Wrong field for access: " << text << std::endl; std::cout << "Wrong field for access: " << text << std::endl;
} }
} }
unsigned int peripheralCount = 0; unsigned int peripheralCount = 0; //Debug
Peripheral XmlParser::parsePeripheral(tinyxml2::XMLElement* peripheralRoot){ Peripheral XmlParser::parsePeripheral(tinyxml2::XMLElement* peripheralRoot) const{
std::cout << "Peripheral: " << peripheralCount++ << std::endl; std::cout << "Peripheral: " << peripheralCount++ << std::endl; //Debug
//Check if peripheral is derived from previous one
const char* attribute = peripheralRoot->Attribute("derivedFrom");
const bool isDerived = attribute != nullptr;
const std::string derivedFrom = isDerived ? attribute : "";
Peripheral peripheral; Peripheral peripheral;
if(isDerived == true){
std::cout << "Derived from " << derivedFrom << std::endl;
//Find the base peripheral and copy it to the new one
auto crit = [&](auto &periph) { return periph.name == derivedFrom; };
auto resultIt = std::find_if(peripherals.begin(), peripherals.end(), crit);
if(resultIt < peripherals.end()){
peripheral = *resultIt;
}
else{
std::cout << "Couldn't find peripheral " << derivedFrom << std::endl;
}
}
setDeviceInfoAttrib(peripheralRoot, "name", peripheral.name); setDeviceInfoAttrib(peripheralRoot, "name", peripheral.name);
setDeviceInfoAttrib(peripheralRoot, "baseAddress", peripheral.baseAddress);
if(isDerived == false){
setDeviceInfoAttrib(peripheralRoot, "description", peripheral.description); setDeviceInfoAttrib(peripheralRoot, "description", peripheral.description);
setDeviceInfoAttrib(peripheralRoot, "groupName", peripheral.groupName); setDeviceInfoAttrib(peripheralRoot, "groupName", peripheral.groupName);
setDeviceInfoAttrib(peripheralRoot, "baseAddress", peripheral.baseAddress);
peripheral.addressBlock = parseAddressBlock(peripheralRoot->FirstChildElement("addressBlock")); peripheral.addressBlock = parseAddressBlock(peripheralRoot->FirstChildElement("addressBlock"));
//Iterate over all registers and append them to peripheral //Iterate over all registers and append them to peripheral
@ -92,23 +110,24 @@ Peripheral XmlParser::parsePeripheral(tinyxml2::XMLElement* peripheralRoot){
peripheral.registers.push_back(parseRegister(registerRoot->ToElement())); peripheral.registers.push_back(parseRegister(registerRoot->ToElement()));
} }
} }
}
peripheral.display(); peripheral.display();
return peripheral; return peripheral;
} }
AddressBlock XmlParser::parseAddressBlock(tinyxml2::XMLElement* addressBlockRoot){ AddressBlock XmlParser::parseAddressBlock(tinyxml2::XMLElement* addressBlockRoot) const{
AddressBlock addressBlock; AddressBlock addressBlock;
if(addressBlockRoot){ if(addressBlockRoot != nullptr){
setDeviceInfoAttrib(addressBlockRoot, "offset", addressBlock.offset); setDeviceInfoAttrib(addressBlockRoot, "offset", addressBlock.offset);
setDeviceInfoAttrib(addressBlockRoot, "size", addressBlock.size); setDeviceInfoAttrib(addressBlockRoot, "size", addressBlock.size);
} }
else else{
std::cout << "parseAddressBlock is nullptr!" << std::endl; std::cout << "addressBlockRoot is nullptr" << std::endl;
1 / 0; }
return addressBlock; return addressBlock;
} }
Register XmlParser::parseRegister(tinyxml2::XMLElement* registerRoot){ Register XmlParser::parseRegister(tinyxml2::XMLElement* registerRoot) const{
Register registe; Register registe;
setDeviceInfoAttrib(registerRoot, "name", registe.name); setDeviceInfoAttrib(registerRoot, "name", registe.name);
setDeviceInfoAttrib(registerRoot, "description", registe.description); setDeviceInfoAttrib(registerRoot, "description", registe.description);
@ -133,7 +152,7 @@ Register XmlParser::parseRegister(tinyxml2::XMLElement* registerRoot){
} }
return registe; return registe;
} }
Field XmlParser::parseField(tinyxml2::XMLElement* fieldRoot){ Field XmlParser::parseField(tinyxml2::XMLElement* fieldRoot) const{
Field field; Field field;
setDeviceInfoAttrib(fieldRoot, "name", field.name); setDeviceInfoAttrib(fieldRoot, "name", field.name);
setDeviceInfoAttrib(fieldRoot, "description", field.description); setDeviceInfoAttrib(fieldRoot, "description", field.description);

View file

@ -16,14 +16,14 @@ struct XmlParser{
private: private:
// tinyxml2::XMLElement* getDevice // tinyxml2::XMLElement* getDevice
void setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char* name, std::string &field); void setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char* name, std::string &field) const;
void setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char* name, unsigned int &field); void setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char* name, unsigned int &field) const;
void setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char* name, EAccess &field); void setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char* name, EAccess &field) const;
Peripheral parsePeripheral(tinyxml2::XMLElement* peripheralRoot); Peripheral parsePeripheral(tinyxml2::XMLElement* peripheralRoot) const;
AddressBlock parseAddressBlock(tinyxml2::XMLElement* addressBlockRoot); AddressBlock parseAddressBlock(tinyxml2::XMLElement* addressBlockRoot) const;
Register parseRegister(tinyxml2::XMLElement* registerRoot); Register parseRegister(tinyxml2::XMLElement* registerRoot) const;
Field parseField(tinyxml2::XMLElement* fieldRoot); Field parseField(tinyxml2::XMLElement* fieldRoot) const;
private: private:
tinyxml2::XMLDocument xmlDocument; tinyxml2::XMLDocument xmlDocument;