Skip to content
Snippets Groups Projects
Commit 00cce2ee authored by Sergi Hernandez's avatar Sergi Hernandez
Browse files

Modified the hex file parser to accept discontinuous code segments.

parent 0b795bd5
No related branches found
No related tags found
No related merge requests found
......@@ -45,16 +45,16 @@ void show_help(char *name) {
int main(int argc,char *argv[])
{
unsigned int baudrate=57600,size,left,addr,start_addr=0x00000000,len;
unsigned int baudrate=57600,left,addr,start_addr=0x00000000,len,base,data_len;
unsigned short int erase_pages=0xFFFF,device_id;
unsigned char bootloader_ver,buffer[256];
flash_op operation=flash_none;
const stm32_dev *device_info;
bool verify=false,done=false;
bool start_exec=false;
std::string device="";
std::string filename;
stm32_cmd commands;
bool verify=false;
off_t offset = 0;
parser_err error;
hex_t *hex_file;
......@@ -160,14 +160,6 @@ int main(int argc,char *argv[])
}
else
std::cout << "Input file in Intel HEX format" << std::endl;
// write the data into the memory
size=hex_size(hex_file);
if (size > device_info->fl_end - device_info->fl_start)
{
std::cout << "File provided larger then available flash space" << std::endl;
hex_close(hex_file);
return 1;
}
std::cout << "erasing memory ...";
if(!stm32_erase_memory(0))
......@@ -175,33 +167,50 @@ int main(int argc,char *argv[])
else
std::cout << " done" << std::endl;
addr = device_info->fl_start;
std::cout << '\xd';
while(addr < device_info->fl_end && offset < size)
// write the data into the memory
done=hex_get_first_segment(hex_file,&base,&data_len);
while(!done)
{
left = device_info->fl_end - addr;
len = sizeof(buffer) > left ? left : sizeof(buffer);
len = len > size - offset ? size - offset : len;
if (hex_read(hex_file, buffer, &len) != PARSER_ERR_OK)
if(base<device_info->fl_start)
{
std::cout << "Error reading the hex file" << std::endl;
std::cout << "Start address not in FLASH" << std::endl;
hex_close(hex_file);
return 1;
return 1;
}
if (!stm32_write_memory(addr,len,buffer))
if((base+data_len)>device_info->fl_end)
{
std::cout << "Failed to write memory at address 0x" << std::hex << addr << std::endl;
std::cout << "End address not in FLASH" << std::endl;
hex_close(hex_file);
return 1;
}
addr += len;
offset += len;
return 1;
}
addr = base;
std::cout << '\xd';
std::cout.width(3);
std::cout << "write done: " << (int)((100.0f / size) * offset) << "%";
std::cout.flush();
while(offset < data_len)
{
left = data_len-offset;
len = sizeof(buffer) > left ? left : sizeof(buffer);
if (hex_read(hex_file, buffer, &len) != PARSER_ERR_OK)
{
std::cout << "Error reading the hex file" << std::endl;
hex_close(hex_file);
return 1;
}
if (!stm32_write_memory(addr,len,buffer))
{
std::cout << "Failed to write memory at address 0x" << std::hex << addr << std::endl;
hex_close(hex_file);
return 1;
}
addr += len;
offset += len;
std::cout << '\xd';
std::cout.width(3);
std::cout << "write done: " << (int)((100.0f / data_len) * offset) << "%";
std::cout.flush();
}
std::cout << std::endl;
offset=0;
done=hex_get_next_segment(hex_file,&base,&data_len);
}
hex_close(hex_file);
std::cout << std::endl;
......
......@@ -4,10 +4,11 @@ hex_t* hex_init()
{
hex_t *hex_file=new hex_t;
hex_file->data_len=0;
hex_file->offset=0;
hex_file->data=NULL;
hex_file->base=0;
hex_file->data_len.resize(1);
hex_file->offset.resize(1);
hex_file->data.resize(1);
hex_file->base.resize(1);
hex_file->current=0;
return hex_file;
}
......@@ -48,20 +49,31 @@ parser_err hex_open(hex_t *file,const char *filename)
/* data record */
case 0:
c = address - last_address;
tmp_data=new unsigned char[file->data_len + c + reclen];
memcpy(tmp_data,file->data,file->data_len);
delete[] file->data;
file->data=tmp_data;
/* if there is a gap, set it to 0xff and increment the length */
if (c > 0) {
memset(&file->data[file->data_len], 0xff, c);
file->data_len += c;
}
if(c>0)
{
// create a new data segment
file->data_len.resize(file->data_len.size()+1);
file->offset.resize(file->offset.size()+1);
file->data.resize(file->data.size()+1);
file->base.resize(file->base.size()+1);
file->current++;
file->data_len[file->current]=0;
file->offset[file->current]=0;
file->data[file->current]=NULL;
file->base[file->current]=(file->base[file->current-1]&0xFFFF0000)+address;
file->data[file->current]=new unsigned char[reclen];
}
else
{
tmp_data=new unsigned char[file->data_len[file->current] + reclen];
memcpy(tmp_data,file->data[file->current],file->data_len[file->current]);
delete[] file->data[file->current];
file->data[file->current]=tmp_data;
}
last_address = address + reclen;
record = &file->data[file->data_len];
file->data_len += reclen;
record = &((file->data[file->current])[file->data_len[file->current]]);
file->data_len[file->current] += reclen;
break;
/* extended segment address record */
......@@ -112,52 +124,60 @@ parser_err hex_open(hex_t *file,const char *filename)
/* EOF */
case 1:
close(fd);
file->current=0;
return PARSER_ERR_OK;
/* address record */
case 2: base = base << 4;
case 4: base = ((base & 0xFF000000) >> 24) | ((base & 0x00FF0000) >> 8) | ((base & 0x0000FF00) << 8) | ((base & 0x000000FF) << 24);
case 4: base = ((base & 0xFF000000) >> 24) | ((base & 0x00FF0000) >> 8) | ((base & 0x0000FF00) << 16) | ((base & 0x000000FF) << 16);
/* Reset last_address since our base changed */
last_address = 0;
if (file->base == 0)
if (file->base[file->current] == 0)
{
file->base = base;
file->base[file->current] = base;
break;
}
if((file->base[file->current]+file->data_len[file->current])==base)
break;
/* we cant cope with files out of order */
if (base < file->base)
if (base < file->base[file->current])
{
close(fd);
return PARSER_ERR_INVALID_FILE;
}
/* if there is a gap, enlarge and fill with zeros */
unsigned int len = base - file->base;
if (len > file->data_len)
{
tmp_data=new unsigned char[len];
memcpy(tmp_data,file->data,file->data_len);
memset(&tmp_data[file->data_len], 0, len - file->data_len);
file->data_len = len;
delete[] file->data;
file->data=tmp_data;
}
// create a new data segment
file->data_len.resize(file->data_len.size()+1);
file->offset.resize(file->offset.size()+1);
file->data.resize(file->data.size()+1);
file->base.resize(file->base.size()+1);
file->current++;
file->data_len[file->current]=0;
file->offset[file->current]=0;
file->data[file->current]=NULL;
file->base[file->current]=base;
break;
}
}
close(fd);
file->current=0;
return PARSER_ERR_OK;
}
parser_err hex_close(hex_t *file)
{
unsigned int i=0;
if(file)
{
if(file->data!=NULL)
delete[] file->data;
for(i=0;i<file->data.size();i++)
if(file->data[i]!=NULL)
delete[] file->data[i];
}
delete file;
......@@ -166,16 +186,39 @@ parser_err hex_close(hex_t *file)
unsigned int hex_size(hex_t *file)
{
return file->data_len;
return file->data_len[file->current];
}
bool hex_get_first_segment(hex_t *file,uint32_t *base,size_t *data_len)
{
file->current=0;
(*base)=file->base[file->current];
(*data_len)=file->data_len[file->current];
return false;
}
bool hex_get_next_segment(hex_t *file,uint32_t *base,size_t *data_len)
{
if(file->current<(file->data.size()-1))
file->current++;
else
return true;
(*base)=file->base[file->current];
(*data_len)=file->data_len[file->current];
return false;
}
parser_err hex_read(hex_t *file,unsigned char *data, unsigned int *len)
{
unsigned int left = file->data_len - file->offset;
unsigned int left = file->data_len[file->current] - file->offset[file->current];
unsigned int get = left > *len ? *len : left;
memcpy(data, &file->data[file->offset], get);
file->offset += get;
memcpy(data, &(file->data[file->current])[file->offset[file->current]], get);
file->offset[file->current] += get;
*len = get;
return PARSER_ERR_OK;
......
......@@ -8,13 +8,16 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include "parsers.h"
typedef struct {
size_t data_len, offset;
uint8_t *data;
uint8_t base;
std::vector<size_t> data_len;
std::vector<size_t> offset;
std::vector<uint8_t *> data;
std::vector<uint32_t> base;
int current;
} hex_t;
......@@ -22,6 +25,8 @@ hex_t* hex_init();
parser_err hex_open(hex_t *file,const char *filename);
parser_err hex_close(hex_t *file);
unsigned int hex_size(hex_t *file);
bool hex_get_first_segment(hex_t *file,uint32_t *base,size_t *data_len);
bool hex_get_next_segment(hex_t *file,uint32_t *base,size_t *data_len);
parser_err hex_read(hex_t *file,unsigned char *data, unsigned int *len);
parser_err hex_write(hex_t *file, unsigned char *data, unsigned int len);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment