mcsParser: reworks code to uses FlashDataSection
This commit is contained in:
parent
d7b9d58768
commit
f349377f5f
|
|
@ -3,6 +3,7 @@
|
||||||
* Copyright (C) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
|
* Copyright (C) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
@ -43,13 +44,16 @@ int McsParser::parse()
|
||||||
{
|
{
|
||||||
string str;
|
string str;
|
||||||
istringstream lineStream(_raw_data);
|
istringstream lineStream(_raw_data);
|
||||||
_bit_data.resize(_file_size);
|
|
||||||
|
|
||||||
while (std::getline(lineStream, str, '\n')) {
|
FlashDataSection *rec = nullptr;
|
||||||
char *ptr;
|
|
||||||
uint8_t sum = 0;
|
bool must_stop = false;
|
||||||
uint16_t tmp, byteLen, type, checksum;
|
std::array<uint8_t, 255> tmp_buf{}; // max size for one data line
|
||||||
uint32_t addr, loc_addr;
|
|
||||||
|
while (std::getline(lineStream, str, '\n') && !must_stop) {
|
||||||
|
uint8_t sum = 0, tmp, byteLen, type, checksum;
|
||||||
|
uint16_t addr;
|
||||||
|
uint32_t loc_addr;
|
||||||
|
|
||||||
/* if '\r' is present -> drop */
|
/* if '\r' is present -> drop */
|
||||||
if (str.back() == '\r')
|
if (str.back() == '\r')
|
||||||
|
|
@ -60,42 +64,45 @@ int McsParser::parse()
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
/* len */
|
/* len */
|
||||||
sscanf((char *)&str[LEN_BASE], "%2hx", &byteLen);
|
sscanf((char *)&str[LEN_BASE], "%2hhx", &byteLen);
|
||||||
/* address */
|
/* address */
|
||||||
sscanf((char *)&str[ADDR_BASE], "%4x", &addr);
|
sscanf((char *)&str[ADDR_BASE], "%4hx", &addr);
|
||||||
/* type */
|
/* type */
|
||||||
sscanf((char *)&str[TYPE_BASE], "%2hx", &type);
|
sscanf((char *)&str[TYPE_BASE], "%2hhx", &type);
|
||||||
/* checksum */
|
/* checksum */
|
||||||
sscanf((char *)&str[DATA_BASE + byteLen * 2], "%2hx", &checksum);
|
sscanf((char *)&str[DATA_BASE + byteLen * 2], "%2hhx", &checksum);
|
||||||
|
|
||||||
sum = byteLen + type + (addr & 0xff) + ((addr >> 8) & 0xff);
|
sum = byteLen + type + (addr & 0xff) + ((addr >> 8) & 0xff);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0:
|
case 0: { /* Data + addr */
|
||||||
loc_addr = _base_addr + addr;
|
loc_addr = _base_addr + addr;
|
||||||
ptr = (char *)&str[DATA_BASE];
|
|
||||||
if ((loc_addr + byteLen) > _bit_data.size())
|
|
||||||
_bit_data.resize(loc_addr + byteLen);
|
|
||||||
|
|
||||||
for (int i = 0; i < byteLen; i++, ptr += 2) {
|
/* Check current record:
|
||||||
sscanf(ptr, "%2hx", &tmp);
|
* Create if null
|
||||||
_bit_data[loc_addr + i] = (_reverseOrder)? reverseByte(tmp):tmp;
|
* Create when a jump in address range
|
||||||
|
*/
|
||||||
|
if (!rec || (rec->getLength() > 0 && rec->getCurrentAddr() != loc_addr)) {
|
||||||
|
_records.emplace_back(loc_addr);
|
||||||
|
rec = &_records.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *ptr = (char *)&str[DATA_BASE];
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < byteLen; i++, ptr += 2) {
|
||||||
|
sscanf(ptr, "%2hhx", &tmp);
|
||||||
|
tmp_buf[i] = _reverseOrder ? reverseByte(tmp) : tmp;
|
||||||
sum += tmp;
|
sum += tmp;
|
||||||
}
|
}
|
||||||
_bit_length += (byteLen * 8);
|
rec->append(tmp_buf.data(), byteLen);
|
||||||
break;
|
break;
|
||||||
case 1:
|
}
|
||||||
if (_bit_data.size() * 8 != (size_t)_bit_length)
|
case 1: /* End Of File */
|
||||||
_bit_length = _bit_data.size() * 8;
|
must_stop = true;
|
||||||
return EXIT_SUCCESS;
|
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4: /* Extended linear addr */
|
||||||
sscanf((char*)&str[DATA_BASE], "%4x", &loc_addr);
|
sscanf((char*)&str[DATA_BASE], "%4x", &loc_addr);
|
||||||
_base_addr = (loc_addr << 16);
|
_base_addr = (loc_addr << 16);
|
||||||
if (_base_addr * 8 > _bit_length)
|
|
||||||
_bit_length = _base_addr * 8;
|
|
||||||
if ((size_t)_bit_length > _bit_data.size() * 8)
|
|
||||||
_bit_data.resize(_bit_length / 8);
|
|
||||||
sum += (loc_addr & 0xff) + ((loc_addr >> 8) & 0xff);
|
sum += (loc_addr & 0xff) + ((loc_addr >> 8) & 0xff);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -103,11 +110,24 @@ int McsParser::parse()
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checksum != (0xff&((~sum)+1))) {
|
if (checksum != (0xff & ((~sum) + 1))) {
|
||||||
printError("Error: wrong checksum");
|
printError("Error: wrong checksum");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint32_t nbRecord = getRecordCount();
|
||||||
|
const uint32_t record_base = getRecordBaseAddr(nbRecord - 1);
|
||||||
|
const uint32_t record_length = getRecordLength(nbRecord - 1);
|
||||||
|
const uint32_t flash_size = record_base + record_length;
|
||||||
|
|
||||||
|
_bit_data.assign(flash_size, 0xff);
|
||||||
|
_bit_length = flash_size * 8;
|
||||||
|
for (uint32_t i = 0; i < nbRecord; i++) {
|
||||||
|
const uint32_t record_base = getRecordBaseAddr(i);
|
||||||
|
const std::vector<uint8_t> rec = getRecordData(i);
|
||||||
|
std::copy(rec.begin(), rec.end(), _bit_data.begin() + record_base);
|
||||||
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,34 @@
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
|
* Copyright (C) 2019-2025 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MCSPARSER_HPP
|
#ifndef MCSPARSER_HPP
|
||||||
#define MCSPARSER_HPP
|
#define MCSPARSER_HPP
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "configBitstreamParser.hpp"
|
#include "configBitstreamParser.hpp"
|
||||||
|
#include "spiFlash.hpp"
|
||||||
|
|
||||||
class McsParser: public ConfigBitstreamParser {
|
class McsParser: public ConfigBitstreamParser {
|
||||||
public:
|
public:
|
||||||
McsParser(const std::string &filename, bool reverseOrder, bool verbose);
|
McsParser(const std::string &filename, bool reverseOrder, bool verbose);
|
||||||
int parse() override;
|
int parse() override;
|
||||||
|
|
||||||
|
size_t getRecordCount() const noexcept { return _records.size(); }
|
||||||
|
const FlashDataSection &getRecord(size_t record_id) const { return _records.at(record_id); }
|
||||||
|
const std::vector<uint8_t> &getRecordData(size_t record_id) const { return _records.at(record_id).getRecord(); }
|
||||||
|
uint32_t getRecordBaseAddr(size_t record_id) const { return _records.at(record_id).getStartAddr(); }
|
||||||
|
size_t getRecordLength(size_t record_id) const { return _records.at(record_id).getLength(); }
|
||||||
|
const std::vector<FlashDataSection> &getRecords() const noexcept { return _records; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _base_addr;
|
int _base_addr;
|
||||||
bool _reverseOrder;
|
bool _reverseOrder;
|
||||||
|
std::vector<FlashDataSection> _records;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue