aqhome: added lib for hexfiles and flash records.
This commit is contained in:
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user