Skip to content

Commit

Permalink
pic boot algorithm rewritten
Browse files Browse the repository at this point in the history
  • Loading branch information
grodansparadis committed Apr 25, 2024
1 parent 9aa5fd4 commit f77814a
Show file tree
Hide file tree
Showing 9 changed files with 408 additions and 401 deletions.
1 change: 1 addition & 0 deletions src/vscp/common/mdf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1752,6 +1752,7 @@ CMDF::downLoadMDF(const std::string &url, const std::string &tempFileName)
if (curl) {
fp = fopen(tempFileName.c_str(), "wb");
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
Expand Down
2 changes: 1 addition & 1 deletion src/vscp/common/mdf.h
Original file line number Diff line number Diff line change
Expand Up @@ -4119,7 +4119,7 @@ class CMDF : public CMDF_Object {
@return Return CURLE_OK if a valid file is downloaded, else a
curl error code.
*/
CURLcode downLoadMDF(const std::string &remoteFile, const std::string &tempFile);
static CURLcode downLoadMDF(const std::string &remoteFile, const std::string &tempFile);

/*!
Load MDF from local or remote storage and parse it into
Expand Down
16 changes: 8 additions & 8 deletions src/vscp/common/vscp.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,14 +292,14 @@ typedef VSCPChannelInfo *PVSCPCHANNELINFO;

/* Interface types */
#define VSCP_INTERFACE_TYPE_UNKNOWN 0
#define VSCP_INTERFACE_TYPE_INTERNAL 1
#define VSCP_INTERFACE_TYPE_LEVEL1DRV 2
#define VSCP_INTERFACE_TYPE_LEVEL2DRV 3
#define VSCP_INTERFACE_TYPE_CLIENT_TCPIP 4
#define VSCP_INTERFACE_TYPE_CLIENT_UDP 5
#define VSCP_INTERFACE_TYPE_CLIENT_WEB 6
#define VSCP_INTERFACE_TYPE_CLIENT_WEBSOCK 7
#define VSCP_INTERFACE_TYPE_CLIENT_REST 8
#define VSCP_INTERFACE_TYPE_INTERNAL 1 // Internal to daemon/server
#define VSCP_INTERFACE_TYPE_LEVEL1DRV 2 // Level I driver
#define VSCP_INTERFACE_TYPE_LEVEL2DRV 3 // Level II driver
#define VSCP_INTERFACE_TYPE_CLIENT_TCPIP 4 // TCP/IP client
#define VSCP_INTERFACE_TYPE_CLIENT_UDP 5 // UDP client
#define VSCP_INTERFACE_TYPE_CLIENT_WEB 6 // Web server
#define VSCP_INTERFACE_TYPE_CLIENT_WEBSOCK 7 // Websocket client
#define VSCP_INTERFACE_TYPE_CLIENT_REST 8 // REST client

/* VSCP Encryption types */
#define VSCP_ENCRYPTION_NONE 0
Expand Down
63 changes: 44 additions & 19 deletions src/vscp/common/vscp_bootdevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,39 +90,47 @@ CBootMemBlock::~CBootMemBlock(void)

CBootDevice::CBootDevice(CVscpClient *pclient,
uint16_t nodeid,
std::function<void(int)> statusCallback,
std::function<void(int, const char *)> statusCallback,
uint32_t timeout)
{
m_pclient = pclient;
m_nodeid = nodeid;
m_guid.clear();
m_guid.setNicknameID(nodeid);
m_guidif.clear();
m_timeout = timeout;
m_statusCallback = statusCallback;
m_startAddr = 0; // Boot start
}

CBootDevice::CBootDevice(CVscpClient *pclient,
uint16_t nodeid,
cguid &guidif,
std::function<void(int)> statusCallback,
std::function<void(int, const char *)> statusCallback,
uint32_t timeout)
{
m_pclient = pclient;
m_nodeid = nodeid;
m_guid.clear();
m_guid.setNicknameID(nodeid);
m_guidif = guidif;
m_timeout = timeout;
m_statusCallback = statusCallback;
m_startAddr = 0; // Boot start
}

CBootDevice::CBootDevice(CVscpClient *pclient, cguid &guid, std::function<void(int)> statusCallback, uint32_t timeout)
CBootDevice::CBootDevice(CVscpClient *pclient,
cguid &guid,
std::function<void(int, const char *)> statusCallback,
uint32_t timeout)
{
m_pclient = pclient;
m_nodeid = 0;
m_guid = guid;
m_guidif.clear();
m_timeout = timeout;
m_statusCallback = statusCallback;
m_startAddr = 0; // Boot start
}

///////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -150,21 +158,25 @@ CBootDevice::loadIntelHexFile(const std::string &path)
char buf[16];
char *endptr;
std::ifstream hexfile;
uint16_t lowAddr = 0; // Low part of address
uint16_t highAddr = 0; // High part if address
uint32_t segmentAddr = 0; // Extended segment address (type=2)
uint16_t lowaddr = 0; // Low part of address
uint16_t highaddr = 0; // High part if address
uint32_t segmentaddr = 0; // Extended segment address (type=2)
uint8_t cnt = 0;
uint8_t recType = 0;
uint8_t rectype = 0;

try {
hexfile.open(path);
}
catch (...) {
spdlog::error("Load intel hex: Unable to open file {%0} error={%1} '{%2}'", path, errno, strerror(errno));
return VSCP_ERROR_OPERATION_FAILED;
}

bool bRun = true;
while (bRun && hexfile.getline(szline, sizeof(szline))) {
bool bRun = true; // (is.rdstate() & std::ifstream::failbit ) != 0
while (bRun && !hexfile.eof()) {

hexfile.getline(szline, sizeof(szline));
spdlog::trace("input: {0}", szline);

// We ignore all lines that does not contain
// ':'
Expand All @@ -191,14 +203,21 @@ CBootDevice::loadIntelHexFile(const std::string &path)
}

cnt = linebuf[0];
lowAddr = (uint32_t) linebuf[1] << 16 + linebuf[2];
recType = linebuf[3];
lowaddr = (((uint16_t) linebuf[1]) << 8) + linebuf[2];
rectype = linebuf[3];

// Construct fulladdress
uint32_t fulladdr = (highAddr << 16) + lowAddr + segmentAddr;
uint32_t fulladdr = (((uint32_t) highaddr) << 16) + lowaddr + segmentaddr;
spdlog::trace("cnt: {0} rectype:{1} lowaddr: {2} highaddr: {3} fulladdr: {4} segment: {5}",
cnt,
rectype,
lowaddr,
highaddr,
fulladdr,
segmentaddr);

// Handle row as of record type
switch (recType) {
switch (rectype) {

case CBootDevice::INTELHEX_LINETYPE_DATA: {
uint8_t mem[256];
Expand All @@ -225,7 +244,7 @@ CBootDevice::loadIntelHexFile(const std::string &path)
hexfile.close();
return VSCP_ERROR_PARAMETER;
}
segmentAddr = (((uint16_t) linebuf[4]) << 8 + linebuf[5]) * 16;
segmentaddr = ((((uint16_t) linebuf[4]) << 8) + linebuf[5]) * 16;
break;

case CBootDevice::INTELHEX_LINETYPE_EXTENDED_LINEAR:
Expand All @@ -235,7 +254,7 @@ CBootDevice::loadIntelHexFile(const std::string &path)
hexfile.close();
return VSCP_ERROR_PARAMETER;
}
highAddr = (((uint16_t) linebuf[4]) << 8 + linebuf[5]);
highaddr = ((((uint16_t) linebuf[4]) << 8) + linebuf[5]);
break;

case CBootDevice::INTELHEX_LINETYPE_START_SEGMENT:
Expand All @@ -262,14 +281,17 @@ int
CBootDevice::getMinMaxForRange(uint32_t start, uint32_t end, uint32_t *pmin, uint32_t *pmax)
{
if (nullptr == pmin) {
spdlog::error("getMinMaxForRange: pmin pointer is invalid (nullptr)");
return VSCP_ERROR_INVALID_POINTER;
}

if (nullptr == pmax) {
spdlog::error("getMinMaxForRange: pmax pointer is invalid (nullptr)");
return VSCP_ERROR_INVALID_POINTER;
}

if (end <= start) {
spdlog::error("getMinMaxForRange: end <= start");
return VSCP_ERROR_PARAMETER;
}

Expand All @@ -289,6 +311,13 @@ CBootDevice::getMinMaxForRange(uint32_t start, uint32_t end, uint32_t *pmin, uin
}
}

// Set both values to zero if noting found in
// the range
if ((*pmin == 0xffffffff) && (*pmax == 0)) {
*pmin = 0;
return VSCP_ERROR_SUCCESS; // nothing to program so we are done
}

return VSCP_ERROR_SUCCESS;
}

Expand All @@ -303,10 +332,6 @@ CBootDevice::fillBlock(uint8_t *pblock, uint32_t size, uint32_t start, uint8_t f
return VSCP_ERROR_INVALID_POINTER;
}

if (size > BOOT_MAX_BLOCK_SIZE) {
return VSCP_ERROR_SIZE;
}

// Fill block with void value (0xff for flash)
memset(pblock, fill, size);

Expand Down
24 changes: 16 additions & 8 deletions src/vscp/common/vscp_bootdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class CBootDevice {
*/
CBootDevice(CVscpClient *pclient,
uint16_t nodeid,
std::function<void(int)> statusCallback = nullptr,
std::function<void(int, const char*)> statusCallback = nullptr,
uint32_t timeout = REGISTER_DEFAULT_TIMEOUT);

/*!
Expand All @@ -140,7 +140,7 @@ class CBootDevice {
CBootDevice(CVscpClient *pclient,
uint16_t nodeid,
cguid &guidif,
std::function<void(int)> statusCallback = nullptr,
std::function<void(int, const char*)> statusCallback = nullptr,
uint32_t timeout = REGISTER_DEFAULT_TIMEOUT);

/*!
Expand All @@ -153,7 +153,7 @@ class CBootDevice {
*/
CBootDevice(CVscpClient *pclient,
cguid &guid,
std::function<void(int)> statusCallback = nullptr,
std::function<void(int, const char*)> statusCallback = nullptr,
uint32_t timeout = REGISTER_DEFAULT_TIMEOUT);

/*!
Expand Down Expand Up @@ -201,8 +201,11 @@ class CBootDevice {
@param end Stop address for memory range (inclusive - end is part of address space)
@param pmin Pointer to variable that will get min address
@param pmax Pointer to variable that will get max address
@return VSCP_ERROR_SUCCESS on success. VSCP_ERROR_ERROR if no memory
defined in the selected range.
@return VSCP_ERROR_SUCCESS on success.
VSCP_ERROR_INVALID_POINTER if ponters are invalid.
VSCP_ERROR_INVALID_PARAMETER if end <= start
VSCP_ERROR_ERROR if no memory defined in the selected range. value of
pmin/pmax is zero in this case.
*/
virtual int getMinMaxForRange(uint32_t start, uint32_t end, uint32_t *pmin, uint32_t *pmax);

Expand All @@ -224,9 +227,11 @@ class CBootDevice {

/*!
Set a device in bootmode
@param bAbortOnFirmwareCodeFail Set to true to fail if firmware code fetched from
MDF is not the same as the one read from the remote device.
@return VSCP_ERROR_SUCCESS on success.
*/
virtual int deviceInit(void) = 0;
virtual int deviceInit(bool bAbortOnFirmwareCodeFail = false) = 0;

/*!
Perform the actual firmware load process
Expand Down Expand Up @@ -255,11 +260,11 @@ class CBootDevice {

/*!
Status callback
xxxxx(int, std::string)
xxxxx(int, const char *)
int is percentage,
str is real text description
*/
std::function<void(int)> m_statusCallback;
std::function<void(int,const char*)> m_statusCallback;

/*!
The device code tell the type of hardware of the remote device
Expand All @@ -286,6 +291,9 @@ class CBootDevice {
/// Checksum for firmware
uint32_t m_checksum;

// This is the minimum code address (startvector)
uint32_t m_startAddr;

/// # data bytes in file
uint32_t m_totalCntData;

Expand Down
Loading

0 comments on commit f77814a

Please sign in to comment.