From f349377f5f16c81e1970ec8e3075a0798483c580 Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Wed, 17 Dec 2025 19:59:32 +0100 Subject: [PATCH] mcsParser: reworks code to uses FlashDataSection --- src/mcsParser.cpp | 76 ++++++++++++++++++++++++++++++----------------- src/mcsParser.hpp | 13 +++++++- 2 files changed, 60 insertions(+), 29 deletions(-) diff --git a/src/mcsParser.cpp b/src/mcsParser.cpp index c9f1c97..2c600f8 100644 --- a/src/mcsParser.cpp +++ b/src/mcsParser.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2019 Gwenhael Goavec-Merou */ +#include #include #include @@ -43,13 +44,16 @@ int McsParser::parse() { string str; istringstream lineStream(_raw_data); - _bit_data.resize(_file_size); - while (std::getline(lineStream, str, '\n')) { - char *ptr; - uint8_t sum = 0; - uint16_t tmp, byteLen, type, checksum; - uint32_t addr, loc_addr; + FlashDataSection *rec = nullptr; + + bool must_stop = false; + std::array tmp_buf{}; // max size for one data line + + 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 (str.back() == '\r') @@ -60,42 +64,45 @@ int McsParser::parse() return EXIT_FAILURE; } /* len */ - sscanf((char *)&str[LEN_BASE], "%2hx", &byteLen); + sscanf((char *)&str[LEN_BASE], "%2hhx", &byteLen); /* address */ - sscanf((char *)&str[ADDR_BASE], "%4x", &addr); + sscanf((char *)&str[ADDR_BASE], "%4hx", &addr); /* type */ - sscanf((char *)&str[TYPE_BASE], "%2hx", &type); + sscanf((char *)&str[TYPE_BASE], "%2hhx", &type); /* 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); switch (type) { - case 0: + case 0: { /* Data + 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) { - sscanf(ptr, "%2hx", &tmp); - _bit_data[loc_addr + i] = (_reverseOrder)? reverseByte(tmp):tmp; + /* Check current record: + * Create if null + * 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; } - _bit_length += (byteLen * 8); + rec->append(tmp_buf.data(), byteLen); break; - case 1: - if (_bit_data.size() * 8 != (size_t)_bit_length) - _bit_length = _bit_data.size() * 8; - return EXIT_SUCCESS; + } + case 1: /* End Of File */ + must_stop = true; break; - case 4: + case 4: /* Extended linear addr */ sscanf((char*)&str[DATA_BASE], "%4x", &loc_addr); _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); break; default: @@ -103,11 +110,24 @@ int McsParser::parse() return EXIT_FAILURE; } - if (checksum != (0xff&((~sum)+1))) { + if (checksum != (0xff & ((~sum) + 1))) { printError("Error: wrong checksum"); 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 rec = getRecordData(i); + std::copy(rec.begin(), rec.end(), _bit_data.begin() + record_base); + } + return EXIT_SUCCESS; } diff --git a/src/mcsParser.hpp b/src/mcsParser.hpp index 33c499f..1dffc3e 100644 --- a/src/mcsParser.hpp +++ b/src/mcsParser.hpp @@ -1,23 +1,34 @@ // SPDX-License-Identifier: Apache-2.0 /* - * Copyright (C) 2019 Gwenhael Goavec-Merou + * Copyright (C) 2019-2025 Gwenhael Goavec-Merou */ #ifndef MCSPARSER_HPP #define MCSPARSER_HPP #include +#include +#include #include "configBitstreamParser.hpp" +#include "spiFlash.hpp" class McsParser: public ConfigBitstreamParser { public: McsParser(const std::string &filename, bool reverseOrder, bool verbose); 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 &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 &getRecords() const noexcept { return _records; } + private: int _base_addr; bool _reverseOrder; + std::vector _records; }; #endif