aqhome: added lib for hexfiles and flash records.
This commit is contained in:
@@ -61,6 +61,7 @@
|
|||||||
ipc
|
ipc
|
||||||
nodes
|
nodes
|
||||||
mqtt
|
mqtt
|
||||||
|
hexfile
|
||||||
</subdirs>
|
</subdirs>
|
||||||
|
|
||||||
|
|
||||||
@@ -69,6 +70,7 @@
|
|||||||
aqhipc
|
aqhipc
|
||||||
aqhnodes
|
aqhnodes
|
||||||
aqhmqtt
|
aqhmqtt
|
||||||
|
aqhhexfile
|
||||||
</useTargets>
|
</useTargets>
|
||||||
|
|
||||||
<libraries>
|
<libraries>
|
||||||
|
|||||||
85
aqhome/hexfile/0BUILD
Normal file
85
aqhome/hexfile/0BUILD
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<?xml?>
|
||||||
|
|
||||||
|
<gwbuild>
|
||||||
|
|
||||||
|
<target type="ConvenienceLibrary" name="aqhhexfile" >
|
||||||
|
|
||||||
|
<includes type="c" >
|
||||||
|
$(gwenhywfar_cflags)
|
||||||
|
-I$(topsrcdir)
|
||||||
|
-I$(topbuilddir)
|
||||||
|
</includes>
|
||||||
|
|
||||||
|
<includes type="tm2" >
|
||||||
|
--include=$(builddir)
|
||||||
|
--include=$(srcdir)
|
||||||
|
</includes>
|
||||||
|
|
||||||
|
|
||||||
|
<define name="BUILDING_AQHOME" />
|
||||||
|
|
||||||
|
<setVar name="local/cflags">$(visibility_cflags)</setVar>
|
||||||
|
|
||||||
|
|
||||||
|
<setVar name="tm2flags" >
|
||||||
|
--api=AQHOME_API
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<setVar name="local/typefiles" >
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<setVar name="local/built_sources" >
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
<setVar name="local/built_headers_pub">
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
|
||||||
|
<setVar name="local/built_headers_priv" >
|
||||||
|
</setVar>
|
||||||
|
|
||||||
|
|
||||||
|
<headers dist="false" install="$(pkgincludedir)/hexfile" >
|
||||||
|
$(local/built_headers_pub)
|
||||||
|
</headers>
|
||||||
|
|
||||||
|
|
||||||
|
<headers dist="true" install="$(pkgincludedir)/hexfile" >
|
||||||
|
hexfilerecord.h
|
||||||
|
hexfilerecord_p.h
|
||||||
|
hexfile.h
|
||||||
|
hexfile_p.h
|
||||||
|
flashrecord.h
|
||||||
|
flashrecord_p.h
|
||||||
|
</headers>
|
||||||
|
|
||||||
|
|
||||||
|
<headers dist="true" >
|
||||||
|
</headers>
|
||||||
|
|
||||||
|
|
||||||
|
<sources>
|
||||||
|
$(local/typefiles)
|
||||||
|
|
||||||
|
hexfile.c
|
||||||
|
hexfilerecord.c
|
||||||
|
flashrecord.c
|
||||||
|
</sources>
|
||||||
|
|
||||||
|
|
||||||
|
<extradist>
|
||||||
|
</extradist>
|
||||||
|
|
||||||
|
|
||||||
|
<useTargets>
|
||||||
|
</useTargets>
|
||||||
|
|
||||||
|
<subdirs>
|
||||||
|
</subdirs>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</target>
|
||||||
|
|
||||||
|
</gwbuild>
|
||||||
215
aqhome/hexfile/flashrecord.c
Normal file
215
aqhome/hexfile/flashrecord.c
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "./flashrecord_p.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
#include <gwenhywfar/misc.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_LIST_FUNCTIONS(AQH_FLASHRECORD, AQH_FlashRecord)
|
||||||
|
|
||||||
|
|
||||||
|
AQH_HEXFILERECORD *_sampleAdjacentHexfileRecords(AQH_FLASHRECORD *fr, AQH_HEXFILERECORD *hrStart);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_FLASHRECORD *AQH_FlashRecord_new()
|
||||||
|
{
|
||||||
|
AQH_FLASHRECORD *fr;
|
||||||
|
|
||||||
|
GWEN_NEW_OBJECT(AQH_FLASHRECORD, fr);
|
||||||
|
GWEN_LIST_INIT(AQH_FLASHRECORD, fr);
|
||||||
|
return fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_FlashRecord_free(AQH_FLASHRECORD *fr)
|
||||||
|
{
|
||||||
|
if (fr) {
|
||||||
|
GWEN_LIST_FINI(AQH_FLASHRECORD, fr);
|
||||||
|
if (fr->dataPointer)
|
||||||
|
free(fr->dataPointer);
|
||||||
|
fr->dataPointer=NULL;
|
||||||
|
GWEN_FREE_OBJECT(fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_FlashRecord_GetAddress(const AQH_FLASHRECORD *fr)
|
||||||
|
{
|
||||||
|
if (fr)
|
||||||
|
return fr->address;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_FlashRecord_SetAddress(AQH_FLASHRECORD *fr, uint32_t a)
|
||||||
|
{
|
||||||
|
if (fr)
|
||||||
|
fr->address=a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_FlashRecord_GetDataLength(const AQH_FLASHRECORD *fr)
|
||||||
|
{
|
||||||
|
if (fr)
|
||||||
|
return fr->dataLength;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t *AQH_FlashRecord_GetDataPointer(const AQH_FLASHRECORD *fr)
|
||||||
|
{
|
||||||
|
if (fr)
|
||||||
|
return fr->dataPointer;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_FlashRecord_DirectlySetData(AQH_FLASHRECORD *fr, uint32_t dataLength, uint8_t *dataPtr)
|
||||||
|
{
|
||||||
|
if (fr->dataPointer)
|
||||||
|
free(fr->dataPointer);
|
||||||
|
fr->dataPointer=dataPtr;
|
||||||
|
fr->dataLength=dataLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_FlashRecord_CopyAndSetData(AQH_FLASHRECORD *fr, uint32_t dataLength, const uint8_t *dataPtr)
|
||||||
|
{
|
||||||
|
if (fr) {
|
||||||
|
if (fr->dataPointer)
|
||||||
|
free(fr->dataPointer);
|
||||||
|
if (dataLength) {
|
||||||
|
fr->dataPointer=(uint8_t*) malloc(dataLength);
|
||||||
|
if (fr->dataPointer) {
|
||||||
|
if (dataPtr)
|
||||||
|
memmove(fr->dataPointer, dataPtr, dataLength);
|
||||||
|
else
|
||||||
|
memset(fr->dataPointer, 0, dataLength);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fr->dataPointer=NULL;
|
||||||
|
fr->dataLength=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fr->dataPointer=NULL;
|
||||||
|
fr->dataLength=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_FLASHRECORD_LIST *AQH_FlashRecord_fromHexfileRecords(AQH_HEXFILERECORD_LIST *hexFileRecordList)
|
||||||
|
{
|
||||||
|
AQH_FLASHRECORD_LIST *flashRecordList;
|
||||||
|
AQH_HEXFILERECORD *hr;
|
||||||
|
uint32_t currentOffset=0;
|
||||||
|
|
||||||
|
flashRecordList=AQH_FlashRecord_List_new();
|
||||||
|
hr=AQH_HexfileRecord_List_First(hexFileRecordList);
|
||||||
|
while(hr) {
|
||||||
|
uint8_t t;
|
||||||
|
|
||||||
|
t=AQH_HexfileRecord_GetRecordType(hr);
|
||||||
|
if (t==AQH_HEXFILERECORD_TYPE_DATA) {
|
||||||
|
AQH_FLASHRECORD *fr;
|
||||||
|
|
||||||
|
fr=AQH_FlashRecord_new();
|
||||||
|
AQH_FlashRecord_SetAddress(fr, currentOffset+AQH_HexfileRecord_GetAddress(hr));
|
||||||
|
hr=_sampleAdjacentHexfileRecords(fr, hr);
|
||||||
|
AQH_FlashRecord_List_Add(fr, flashRecordList);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (t==AQH_HEXFILERECORD_TYPE_EXTSEG) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
|
||||||
|
if (AQH_HexfileRecord_GetByteCount(hr)<2) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Invalid EXTSEG record (02) in file (too few data bytes)");
|
||||||
|
AQH_FlashRecord_List_free(flashRecordList);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ptr=AQH_HexfileRecord_GetDataPointer(hr);
|
||||||
|
currentOffset=((ptr[0]<<8)+ptr[1])<<4;
|
||||||
|
}
|
||||||
|
else if (t==AQH_HEXFILERECORD_TYPE_EOF) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr=AQH_HexfileRecord_List_Next(hr);
|
||||||
|
}
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
if (AQH_FlashRecord_List_GetCount(flashRecordList)<1) {
|
||||||
|
AQH_FlashRecord_List_free(flashRecordList);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return flashRecordList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_HEXFILERECORD *_sampleAdjacentHexfileRecords(AQH_FLASHRECORD *fr, AQH_HEXFILERECORD *hrStart)
|
||||||
|
{
|
||||||
|
AQH_HEXFILERECORD *hrNext;
|
||||||
|
AQH_HEXFILERECORD *hr;
|
||||||
|
uint32_t len=0;
|
||||||
|
|
||||||
|
hrNext=AQH_HexfileRecord_List_FindNonAdjacentDataRecord(hrStart);
|
||||||
|
/* sample number of contiguous bytes */
|
||||||
|
hr=hrStart;
|
||||||
|
while(hr && hr!=hrNext) {
|
||||||
|
len+=AQH_HexfileRecord_GetByteCount(hr);
|
||||||
|
hr=AQH_HexfileRecord_List_Next(hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len) {
|
||||||
|
uint8_t *ptr;
|
||||||
|
uint32_t offs=0;
|
||||||
|
|
||||||
|
ptr=(uint8_t*) malloc(len);
|
||||||
|
hr=hrStart;
|
||||||
|
while(hr && hr!=hrNext) {
|
||||||
|
memmove(ptr+offs, AQH_HexfileRecord_GetDataPointer(hr), AQH_HexfileRecord_GetByteCount(hr));
|
||||||
|
offs+=AQH_HexfileRecord_GetByteCount(hr);
|
||||||
|
hr=AQH_HexfileRecord_List_Next(hr);
|
||||||
|
}
|
||||||
|
AQH_FlashRecord_DirectlySetData(fr, len, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hrNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
42
aqhome/hexfile/flashrecord.h
Normal file
42
aqhome/hexfile/flashrecord.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_FLASHRECORD_H
|
||||||
|
#define AQH_FLASHRECORD_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
#include <aqhome/hexfile/hexfilerecord.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AQH_FLASHRECORD AQH_FLASHRECORD;
|
||||||
|
GWEN_LIST_FUNCTION_LIB_DEFS(AQH_FLASHRECORD, AQH_FlashRecord, AQHOME_API)
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API AQH_FLASHRECORD *AQH_FlashRecord_new();
|
||||||
|
AQHOME_API AQH_FLASHRECORD_LIST *AQH_FlashRecord_fromHexfileRecords(AQH_HEXFILERECORD_LIST *hexFileRecordList);
|
||||||
|
|
||||||
|
AQHOME_API void AQH_FlashRecord_free(AQH_FLASHRECORD *fr);
|
||||||
|
|
||||||
|
AQHOME_API uint32_t AQH_FlashRecord_GetAddress(const AQH_FLASHRECORD *fr);
|
||||||
|
AQHOME_API void AQH_FlashRecord_SetAddress(AQH_FLASHRECORD *fr, uint32_t a);
|
||||||
|
|
||||||
|
AQHOME_API uint32_t AQH_FlashRecord_GetDataLength(const AQH_FLASHRECORD *fr);
|
||||||
|
AQHOME_API uint8_t *AQH_FlashRecord_GetDataPointer(const AQH_FLASHRECORD *fr);
|
||||||
|
AQHOME_API void AQH_FlashRecord_DirectlySetData(AQH_FLASHRECORD *fr, uint32_t dataLength, uint8_t *dataPtr);
|
||||||
|
AQHOME_API void AQH_FlashRecord_CopyAndSetData(AQH_FLASHRECORD *fr, uint32_t dataLength, const uint8_t *dataPtr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
30
aqhome/hexfile/flashrecord_p.h
Normal file
30
aqhome/hexfile/flashrecord_p.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_FLASHRECORD_P_H
|
||||||
|
#define AQH_FLASHRECORD_P_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "./flashrecord.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct AQH_FLASHRECORD
|
||||||
|
{
|
||||||
|
GWEN_LIST_ELEMENT(AQH_FLASHRECORD)
|
||||||
|
|
||||||
|
uint32_t address;
|
||||||
|
uint32_t dataLength;
|
||||||
|
uint8_t *dataPointer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
318
aqhome/hexfile/hexfile.c
Normal file
318
aqhome/hexfile/hexfile.c
Normal file
@@ -0,0 +1,318 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "aqhome/hexfile/hexfile_p.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/syncio.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const char *_readRecord(AQH_HEXFILERECORD *hr, const char *s);
|
||||||
|
static void _writeRecord(AQH_HEXFILERECORD *hr, GWEN_BUFFER *buffer);
|
||||||
|
static int _sumValuesForChecksum(const AQH_HEXFILERECORD *hr);
|
||||||
|
static int _readWord(const char *s);
|
||||||
|
static int _readByte(const char *s);
|
||||||
|
static int _readNibble(const char *s);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_HEXFILE *AQH_Hexfile_new()
|
||||||
|
{
|
||||||
|
AQH_HEXFILE *h;
|
||||||
|
|
||||||
|
GWEN_NEW_OBJECT(AQH_HEXFILE, h);
|
||||||
|
h->recordList=AQH_HexfileRecord_List_new();
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_HEXFILE *AQH_Hexfile_fromString(const char *s)
|
||||||
|
{
|
||||||
|
AQH_HEXFILE *h;
|
||||||
|
AQH_HEXFILERECORD_LIST *recordList;
|
||||||
|
|
||||||
|
h=AQH_Hexfile_new();
|
||||||
|
recordList=AQH_Hexfile_GetRecordList(h);
|
||||||
|
while(s && *s) {
|
||||||
|
AQH_HEXFILERECORD *hr;
|
||||||
|
uint8_t rt;
|
||||||
|
|
||||||
|
while(s && *s && *s!=':')
|
||||||
|
s++;
|
||||||
|
hr=AQH_HexfileRecord_new();
|
||||||
|
s=_readRecord(hr, s);
|
||||||
|
if (s==NULL) {
|
||||||
|
AQH_HexfileRecord_free(hr);
|
||||||
|
AQH_Hexfile_free(h);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rt=AQH_HexfileRecord_GetRecordType(hr);
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "Adding record %02x", rt);
|
||||||
|
AQH_HexfileRecord_List_Add(hr, recordList);
|
||||||
|
if ((rt==AQH_HEXFILERECORD_TYPE_EOF) ||
|
||||||
|
(rt==AQH_HEXFILERECORD_TYPE_DATA && AQH_HexfileRecord_GetByteCount(hr)==0)) {
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "End record found");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_HEXFILE *AQH_Hexfile_fromFile(const char *filename)
|
||||||
|
{
|
||||||
|
GWEN_BUFFER *buffer;
|
||||||
|
int rv;
|
||||||
|
AQH_HEXFILE *h;
|
||||||
|
|
||||||
|
buffer=GWEN_Buffer_new(0, 1024, 0, 1);
|
||||||
|
rv=GWEN_SyncIo_Helper_ReadFile(filename, buffer);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||||
|
GWEN_Buffer_free(buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
h=AQH_Hexfile_fromString(GWEN_Buffer_GetStart(buffer));
|
||||||
|
GWEN_Buffer_free(buffer);
|
||||||
|
if (h==NULL) {
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "here");
|
||||||
|
}
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Hexfile_toBuffer(const AQH_HEXFILE *h, GWEN_BUFFER *buffer)
|
||||||
|
{
|
||||||
|
if (h && h->recordList) {
|
||||||
|
AQH_HEXFILERECORD *hr;
|
||||||
|
|
||||||
|
hr=AQH_HexfileRecord_List_First(h->recordList);
|
||||||
|
while(hr) {
|
||||||
|
_writeRecord(hr, buffer);
|
||||||
|
GWEN_Buffer_AppendString(buffer, "\r\n");
|
||||||
|
hr=AQH_HexfileRecord_List_Next(hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Hexfile_free(AQH_HEXFILE *h)
|
||||||
|
{
|
||||||
|
if (h) {
|
||||||
|
AQH_HexfileRecord_List_free(h->recordList);
|
||||||
|
GWEN_FREE_OBJECT(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_HEXFILERECORD_LIST *AQH_Hexfile_GetRecordList(const AQH_HEXFILE *h)
|
||||||
|
{
|
||||||
|
if (h)
|
||||||
|
return h->recordList;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char *_readRecord(AQH_HEXFILERECORD *hr, const char *s)
|
||||||
|
{
|
||||||
|
int v;
|
||||||
|
int dataLen;
|
||||||
|
|
||||||
|
/* find ":" */
|
||||||
|
s=strchr(s, ':');
|
||||||
|
if (s==NULL)
|
||||||
|
return NULL;
|
||||||
|
s++;
|
||||||
|
|
||||||
|
v=_readByte(s);
|
||||||
|
if (v<0)
|
||||||
|
return NULL;
|
||||||
|
AQH_HexfileRecord_SetByteCount(hr, (uint8_t) v);
|
||||||
|
dataLen=v;
|
||||||
|
s+=2;
|
||||||
|
|
||||||
|
v=_readWord(s);
|
||||||
|
if (v<0)
|
||||||
|
return NULL;
|
||||||
|
AQH_HexfileRecord_SetAddress(hr, (uint16_t) v);
|
||||||
|
s+=4;
|
||||||
|
|
||||||
|
v=_readByte(s);
|
||||||
|
if (v<0)
|
||||||
|
return NULL;
|
||||||
|
AQH_HexfileRecord_SetRecordType(hr, (uint8_t) v);
|
||||||
|
s+=2;
|
||||||
|
|
||||||
|
if (dataLen) {
|
||||||
|
uint8_t *ptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ptr=(uint8_t*) malloc(dataLen);
|
||||||
|
if (ptr==NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
AQH_HexfileRecord_SetDataPointer(hr, ptr);
|
||||||
|
|
||||||
|
for (i=0; i<dataLen; i++) {
|
||||||
|
v=_readByte(s);
|
||||||
|
if (v<0)
|
||||||
|
return NULL;
|
||||||
|
ptr[i]=(uint8_t) v;
|
||||||
|
s+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* checksum */
|
||||||
|
v=_readByte(s);
|
||||||
|
if (v<0)
|
||||||
|
return NULL;
|
||||||
|
s+=2;
|
||||||
|
|
||||||
|
v+=_sumValuesForChecksum(hr);
|
||||||
|
if (v & 0xff) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Invalid checksum (%d, %d)", (v & 0xff), -(v & 0xff));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _writeRecord(AQH_HEXFILERECORD *hr, GWEN_BUFFER *buffer)
|
||||||
|
{
|
||||||
|
uint8_t len;
|
||||||
|
int v;
|
||||||
|
|
||||||
|
len=AQH_HexfileRecord_GetByteCount(hr);
|
||||||
|
GWEN_Buffer_AppendArgs(buffer, ":%02X%04X%02X",
|
||||||
|
AQH_HexfileRecord_GetByteCount(hr),
|
||||||
|
AQH_HexfileRecord_GetAddress(hr),
|
||||||
|
AQH_HexfileRecord_GetRecordType(hr));
|
||||||
|
if (len) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ptr=AQH_HexfileRecord_GetDataPointer(hr);
|
||||||
|
for(i=0; i<len; i++)
|
||||||
|
GWEN_Buffer_AppendArgs(buffer, "%02X", ptr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
v=_sumValuesForChecksum(hr);
|
||||||
|
GWEN_Buffer_AppendArgs(buffer, "%02X", (-v) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _sumValuesForChecksum(const AQH_HEXFILERECORD *hr)
|
||||||
|
{
|
||||||
|
int v;
|
||||||
|
int dataLen;
|
||||||
|
|
||||||
|
dataLen=AQH_HexfileRecord_GetByteCount(hr);
|
||||||
|
v=AQH_HexfileRecord_GetByteCount(hr)+
|
||||||
|
((AQH_HexfileRecord_GetAddress(hr)>>8) & 0xff)+(AQH_HexfileRecord_GetAddress(hr) & 0xff)+
|
||||||
|
AQH_HexfileRecord_GetRecordType(hr);
|
||||||
|
if (dataLen) {
|
||||||
|
const uint8_t *ptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ptr=AQH_HexfileRecord_GetDataPointer(hr);
|
||||||
|
for(i=0; i<dataLen; i++)
|
||||||
|
v+=ptr[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _readWord(const char *s)
|
||||||
|
{
|
||||||
|
uint16_t result;
|
||||||
|
int b;
|
||||||
|
|
||||||
|
b=_readByte(s);
|
||||||
|
if (b<0)
|
||||||
|
return -1;
|
||||||
|
result=(uint16_t)(b & 0xff);
|
||||||
|
s+=2;
|
||||||
|
|
||||||
|
b=_readByte(s++);
|
||||||
|
if (b<0)
|
||||||
|
return -1;
|
||||||
|
result<<=8;
|
||||||
|
result|=(uint16_t)(b & 0xff);
|
||||||
|
return (int) result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _readByte(const char *s)
|
||||||
|
{
|
||||||
|
uint8_t result;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
c=_readNibble(s++);
|
||||||
|
if (c<0)
|
||||||
|
return -1;
|
||||||
|
result=(uint8_t) (c & 0xf);
|
||||||
|
c=_readNibble(s);
|
||||||
|
if (c<0)
|
||||||
|
return -1;
|
||||||
|
result<<=4;
|
||||||
|
result|=(uint8_t) (c & 0xf);
|
||||||
|
return (int) result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _readNibble(const char *s)
|
||||||
|
{
|
||||||
|
uint8_t c;
|
||||||
|
|
||||||
|
c=*s;
|
||||||
|
if (c==0)
|
||||||
|
return -1;
|
||||||
|
if (c>='0' && c<='9')
|
||||||
|
c-='0';
|
||||||
|
else if (c>='A' && c<='F')
|
||||||
|
c-='A'-10;
|
||||||
|
else if (c>='a' && c<='f')
|
||||||
|
c-='a'-10;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
41
aqhome/hexfile/hexfile.h
Normal file
41
aqhome/hexfile/hexfile.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_HEXFILE_H
|
||||||
|
#define AQH_HEXFILE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
#include <aqhome/hexfile/hexfilerecord.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
#include <gwenhywfar/buffer.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AQH_HEXFILE AQH_HEXFILE;
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API AQH_HEXFILE *AQH_Hexfile_new();
|
||||||
|
AQHOME_API AQH_HEXFILE *AQH_Hexfile_fromString(const char *s);
|
||||||
|
AQHOME_API AQH_HEXFILE *AQH_Hexfile_fromFile(const char *filename);
|
||||||
|
|
||||||
|
AQHOME_API void AQH_Hexfile_toBuffer(const AQH_HEXFILE *h, GWEN_BUFFER *buffer);
|
||||||
|
|
||||||
|
AQHOME_API void AQH_Hexfile_free(AQH_HEXFILE *h);
|
||||||
|
|
||||||
|
AQHOME_API AQH_HEXFILERECORD_LIST *AQH_Hexfile_GetRecordList(const AQH_HEXFILE *h);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
27
aqhome/hexfile/hexfile_p.h
Normal file
27
aqhome/hexfile/hexfile_p.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_HEXFILE_P_H
|
||||||
|
#define AQH_HEXFILE_P_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "aqhome/hexfile/hexfile.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct AQH_HEXFILE {
|
||||||
|
AQH_HEXFILERECORD_LIST *recordList;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
175
aqhome/hexfile/hexfilerecord.c
Normal file
175
aqhome/hexfile/hexfilerecord.c
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "./hexfilerecord_p.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
#include <gwenhywfar/misc.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_LIST_FUNCTIONS(AQH_HEXFILERECORD, AQH_HexfileRecord)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_HEXFILERECORD *AQH_HexfileRecord_new()
|
||||||
|
{
|
||||||
|
AQH_HEXFILERECORD *hr;
|
||||||
|
|
||||||
|
GWEN_NEW_OBJECT(AQH_HEXFILERECORD, hr);
|
||||||
|
GWEN_LIST_INIT(AQH_HEXFILERECORD, hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_HexfileRecord_free(AQH_HEXFILERECORD *hr)
|
||||||
|
{
|
||||||
|
if (hr) {
|
||||||
|
GWEN_LIST_FINI(AQH_HEXFILERECORD, hr);
|
||||||
|
if (hr->dataPointer)
|
||||||
|
free(hr->dataPointer);
|
||||||
|
GWEN_FREE_OBJECT(hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t AQH_HexfileRecord_GetByteCount(const AQH_HEXFILERECORD *hr)
|
||||||
|
{
|
||||||
|
if (hr)
|
||||||
|
return hr->byteCount;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_HexfileRecord_SetByteCount(AQH_HEXFILERECORD *hr, uint8_t b)
|
||||||
|
{
|
||||||
|
if (hr)
|
||||||
|
hr->byteCount=b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t AQH_HexfileRecord_GetAddress(const AQH_HEXFILERECORD *hr)
|
||||||
|
{
|
||||||
|
if (hr)
|
||||||
|
return hr->address;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_HexfileRecord_SetAddress(AQH_HEXFILERECORD *hr, uint16_t a)
|
||||||
|
{
|
||||||
|
if (hr)
|
||||||
|
hr->address=a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t AQH_HexfileRecord_GetRecordType(const AQH_HEXFILERECORD *hr)
|
||||||
|
{
|
||||||
|
if (hr)
|
||||||
|
return hr->recordType;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_HexfileRecord_SetRecordType(AQH_HEXFILERECORD *hr, uint8_t t)
|
||||||
|
{
|
||||||
|
if (hr)
|
||||||
|
hr->recordType=t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const uint8_t *AQH_HexfileRecord_GetDataPointer(const AQH_HEXFILERECORD *hr)
|
||||||
|
{
|
||||||
|
if (hr)
|
||||||
|
return hr->dataPointer;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_HexfileRecord_SetDataPointer(AQH_HEXFILERECORD *hr, uint8_t *ptr)
|
||||||
|
{
|
||||||
|
if (hr) {
|
||||||
|
if (hr->dataPointer)
|
||||||
|
free(hr->dataPointer);
|
||||||
|
hr->dataPointer=ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_HexfileRecord_SetData(AQH_HEXFILERECORD *hr, const uint8_t *ptr, uint8_t len)
|
||||||
|
{
|
||||||
|
if (hr) {
|
||||||
|
if (hr->dataPointer)
|
||||||
|
free(hr->dataPointer);
|
||||||
|
if (ptr && len) {
|
||||||
|
hr->dataPointer=(uint8_t*) malloc(len);
|
||||||
|
if (hr->dataPointer) {
|
||||||
|
memmove(hr->dataPointer, ptr, len);
|
||||||
|
hr->byteCount=len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hr->dataPointer=NULL;
|
||||||
|
hr->byteCount=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hr->dataPointer=NULL;
|
||||||
|
hr->byteCount=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_HEXFILERECORD *AQH_HexfileRecord_List_FindNonAdjacentDataRecord(AQH_HEXFILERECORD *hr)
|
||||||
|
{
|
||||||
|
uint16_t expectedAddr;
|
||||||
|
int cnt=0;
|
||||||
|
|
||||||
|
expectedAddr=AQH_HexfileRecord_GetAddress(hr)+AQH_HexfileRecord_GetByteCount(hr);
|
||||||
|
hr=AQH_HexfileRecord_List_Next(hr);
|
||||||
|
while(hr && AQH_HexfileRecord_GetRecordType(hr)==AQH_HEXFILERECORD_TYPE_DATA) {
|
||||||
|
uint16_t addr;
|
||||||
|
|
||||||
|
addr=AQH_HexfileRecord_GetAddress(hr);
|
||||||
|
if (addr!=expectedAddr)
|
||||||
|
break;
|
||||||
|
expectedAddr=addr+AQH_HexfileRecord_GetByteCount(hr);
|
||||||
|
cnt++;
|
||||||
|
hr=AQH_HexfileRecord_List_Next(hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "- num of continuous records: %d", cnt);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
65
aqhome/hexfile/hexfilerecord.h
Normal file
65
aqhome/hexfile/hexfilerecord.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_HEXFILERECORD_H
|
||||||
|
#define AQH_HEXFILERECORD_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <aqhome/api.h>
|
||||||
|
|
||||||
|
#include <gwenhywfar/list.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_HEXFILERECORD_TYPE_DATA 0x00
|
||||||
|
#define AQH_HEXFILERECORD_TYPE_EOF 0x01
|
||||||
|
#define AQH_HEXFILERECORD_TYPE_EXTSEG 0x02
|
||||||
|
#define AQH_HEXFILERECORD_TYPE_STARTSEGADDR 0x03
|
||||||
|
#define AQH_HEXFILERECORD_TYPE_EXTLINEARADDR 0x04
|
||||||
|
#define AQH_HEXFILERECORD_TYPE_STARTLINEARADDR 0x05
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AQH_HEXFILERECORD AQH_HEXFILERECORD;
|
||||||
|
GWEN_LIST_FUNCTION_LIB_DEFS(AQH_HEXFILERECORD, AQH_HexfileRecord, AQHOME_API)
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API AQH_HEXFILERECORD *AQH_HexfileRecord_new();
|
||||||
|
AQHOME_API void AQH_HexfileRecord_free(AQH_HEXFILERECORD *hr);
|
||||||
|
|
||||||
|
|
||||||
|
AQHOME_API uint8_t AQH_HexfileRecord_GetByteCount(const AQH_HEXFILERECORD *hr);
|
||||||
|
AQHOME_API void AQH_HexfileRecord_SetByteCount(AQH_HEXFILERECORD *hr, uint8_t b);
|
||||||
|
|
||||||
|
AQHOME_API uint16_t AQH_HexfileRecord_GetAddress(const AQH_HEXFILERECORD *hr);
|
||||||
|
AQHOME_API void AQH_HexfileRecord_SetAddress(AQH_HEXFILERECORD *hr, uint16_t a);
|
||||||
|
|
||||||
|
AQHOME_API uint8_t AQH_HexfileRecord_GetRecordType(const AQH_HEXFILERECORD *hr);
|
||||||
|
AQHOME_API void AQH_HexfileRecord_SetRecordType(AQH_HEXFILERECORD *hr, uint8_t t);
|
||||||
|
|
||||||
|
AQHOME_API const uint8_t *AQH_HexfileRecord_GetDataPointer(const AQH_HEXFILERECORD *hr);
|
||||||
|
AQHOME_API void AQH_HexfileRecord_SetDataPointer(AQH_HEXFILERECORD *hr, uint8_t *ptr);
|
||||||
|
|
||||||
|
AQHOME_API void AQH_HexfileRecord_SetData(AQH_HEXFILERECORD *hr, const uint8_t *ptr, uint8_t len);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the first record whose address is non-contiguous with the given record.
|
||||||
|
* This can be used to reduce the number of data records.
|
||||||
|
* This function stops at the next record whose address is non-continuous or whose type is not 00.
|
||||||
|
*
|
||||||
|
* @return next non-contiguous or non-data record (NULL if none)
|
||||||
|
* @param hr record to start with (i.e. whose successor are checked for continuity)
|
||||||
|
*/
|
||||||
|
AQHOME_API AQH_HEXFILERECORD *AQH_HexfileRecord_List_FindNonAdjacentDataRecord(AQH_HEXFILERECORD *hr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
31
aqhome/hexfile/hexfilerecord_p.h
Normal file
31
aqhome/hexfile/hexfilerecord_p.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQH_HEXFILERECORD_P_H
|
||||||
|
#define AQH_HEXFILERECORD_P_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "./hexfilerecord.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct AQH_HEXFILERECORD
|
||||||
|
{
|
||||||
|
GWEN_LIST_ELEMENT(AQH_HEXFILERECORD)
|
||||||
|
|
||||||
|
uint8_t byteCount;
|
||||||
|
uint16_t address;
|
||||||
|
uint8_t recordType;
|
||||||
|
uint8_t *dataPointer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
106
aqhome/libtest.c
106
aqhome/libtest.c
@@ -19,6 +19,8 @@
|
|||||||
#include "aqhome/mqtt/msg_mqtt_publish.h"
|
#include "aqhome/mqtt/msg_mqtt_publish.h"
|
||||||
#include "aqhome/mqtt/msg_mqtt_pubresponse.h"
|
#include "aqhome/mqtt/msg_mqtt_pubresponse.h"
|
||||||
#include "aqhome/msgmanager.h"
|
#include "aqhome/msgmanager.h"
|
||||||
|
#include "aqhome/hexfile/hexfile.h"
|
||||||
|
#include "aqhome/hexfile/flashrecord.h"
|
||||||
|
|
||||||
#include "aqhome/aqhome.h"
|
#include "aqhome/aqhome.h"
|
||||||
|
|
||||||
@@ -342,6 +344,105 @@ int testIpcConnection()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int testHexfile(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *inFilename;
|
||||||
|
const char *outFilename;
|
||||||
|
AQH_HEXFILE *h;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if (argc<3) {
|
||||||
|
fprintf(stderr, "Missing filenames (in, out)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv=AQH_Init();
|
||||||
|
if (rv<0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inFilename=argv[1];
|
||||||
|
outFilename=argv[2];
|
||||||
|
h=AQH_Hexfile_fromFile(inFilename);
|
||||||
|
if (h==NULL) {
|
||||||
|
fprintf(stderr, "Error reading hexfile \"%s\".\n", inFilename);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AQH_HEXFILERECORD_LIST *recordList;
|
||||||
|
GWEN_BUFFER *buffer;
|
||||||
|
|
||||||
|
recordList=AQH_Hexfile_GetRecordList(h);
|
||||||
|
fprintf(stdout, "INTEL Hexfile read with %d records\n", AQH_HexfileRecord_List_GetCount(recordList));
|
||||||
|
|
||||||
|
buffer=GWEN_Buffer_new(0, 1024, 0, 1);
|
||||||
|
AQH_Hexfile_toBuffer(h, buffer);
|
||||||
|
rv=GWEN_SyncIo_Helper_WriteFile(outFilename, (const uint8_t*) GWEN_Buffer_GetStart(buffer), GWEN_Buffer_GetUsedBytes(buffer));
|
||||||
|
GWEN_Buffer_free(buffer);
|
||||||
|
if (rv<0) {
|
||||||
|
fprintf(stderr, "ERROR writing outfile \"%s\": %d", outFilename, rv);
|
||||||
|
AQH_Hexfile_free(h);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
AQH_Hexfile_free(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int testFlashRecords(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *inFilename;
|
||||||
|
AQH_HEXFILE *h;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if (argc<2) {
|
||||||
|
fprintf(stderr, "Missing filename\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv=AQH_Init();
|
||||||
|
if (rv<0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inFilename=argv[1];
|
||||||
|
h=AQH_Hexfile_fromFile(inFilename);
|
||||||
|
if (h==NULL) {
|
||||||
|
fprintf(stderr, "Error reading hexfile \"%s\".\n", inFilename);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AQH_HEXFILERECORD_LIST *recordList;
|
||||||
|
AQH_FLASHRECORD_LIST *flashRecordList;
|
||||||
|
|
||||||
|
recordList=AQH_Hexfile_GetRecordList(h);
|
||||||
|
fprintf(stdout, "INTEL Hexfile read with %d records\n", AQH_HexfileRecord_List_GetCount(recordList));
|
||||||
|
|
||||||
|
flashRecordList=AQH_FlashRecord_fromHexfileRecords(recordList);
|
||||||
|
if (flashRecordList==NULL) {
|
||||||
|
fprintf(stderr, "ERROR creating flash record list\n");
|
||||||
|
AQH_Hexfile_free(h);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AQH_FLASHRECORD *fr;
|
||||||
|
|
||||||
|
fprintf(stdout, "Flash record list created with %d records\n", AQH_FlashRecord_List_GetCount(flashRecordList));
|
||||||
|
fr=AQH_FlashRecord_List_First(flashRecordList);
|
||||||
|
while(fr) {
|
||||||
|
fprintf(stdout, "- %08x (%d bytes)\n", AQH_FlashRecord_GetAddress(fr), AQH_FlashRecord_GetDataLength(fr));
|
||||||
|
fr=AQH_FlashRecord_List_Next(fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AQH_Hexfile_free(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@@ -349,7 +450,10 @@ int main(int argc, char **argv)
|
|||||||
//return testEndpoints();
|
//return testEndpoints();
|
||||||
//return testMsgMqttConnect();
|
//return testMsgMqttConnect();
|
||||||
//return testMqttConnection();
|
//return testMqttConnection();
|
||||||
return testIpcConnection();
|
|
||||||
|
//return testIpcConnection();
|
||||||
|
//return testHexfile(argc, argv);
|
||||||
|
return testFlashRecords(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user