- reworked image handling to support multiple sections (tested with ihex file containing gaps)
This checkin is still experimental, not recommended for general use git-svn-id: svn://svn.berlios.de/openocd/trunk@159 b42882b7-edfa-0310-969c-e2dbd0fdcd60__archive__
parent
cf013d2e13
commit
f94d66d7c5
|
@ -490,9 +490,10 @@ int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, c
|
||||||
int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||||
{
|
{
|
||||||
u32 offset;
|
u32 offset;
|
||||||
u32 binary_size;
|
|
||||||
u8 *buffer;
|
u8 *buffer;
|
||||||
u32 buf_cnt;
|
u32 buf_cnt;
|
||||||
|
u32 image_size;
|
||||||
|
int i;
|
||||||
|
|
||||||
image_t image;
|
image_t image;
|
||||||
|
|
||||||
|
@ -531,10 +532,18 @@ int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, cha
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
binary_size = image.size;
|
image_size = 0x0;
|
||||||
buffer = malloc(binary_size);
|
for (i = 0; i < image.num_sections; i++)
|
||||||
|
{
|
||||||
image_read(&image, binary_size, buffer, &buf_cnt);
|
buffer = malloc(image.sections[i].size);
|
||||||
|
if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
|
||||||
|
{
|
||||||
|
ERROR("image_read_section failed with error code: %i", retval);
|
||||||
|
command_print(cmd_ctx, "image reading failed, flash write aborted");
|
||||||
|
free(buffer);
|
||||||
|
image_close(&image);
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if ((retval = p->driver->write(p, buffer, offset, buf_cnt)) != ERROR_OK)
|
if ((retval = p->driver->write(p, buffer, offset, buf_cnt)) != ERROR_OK)
|
||||||
{
|
{
|
||||||
|
@ -567,15 +576,18 @@ int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, cha
|
||||||
command_print(cmd_ctx, "unknown error");
|
command_print(cmd_ctx, "unknown error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
image_size += buf_cnt;
|
||||||
{
|
|
||||||
duration_stop_measure(&duration, &duration_text);
|
|
||||||
command_print(cmd_ctx, "wrote file %s to flash bank %i at offset 0x%8.8x in %s",
|
|
||||||
args[1], strtoul(args[0], NULL, 0), offset, duration_text);
|
|
||||||
free(duration_text);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
duration_stop_measure(&duration, &duration_text);
|
||||||
|
command_print(cmd_ctx, "wrote %u byte from file %s to flash bank %i at offset 0x%8.8x in %s (%f kb/s)",
|
||||||
|
image_size, args[1], strtoul(args[0], NULL, 0), offset, duration_text,
|
||||||
|
(float)image_size / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
|
||||||
|
free(duration_text);
|
||||||
|
|
||||||
image_close(&image);
|
image_close(&image);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
|
|
|
@ -1164,8 +1164,7 @@ int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
u32 buf_cnt;
|
u32 buf_cnt;
|
||||||
enum oob_formats oob_format = NAND_OOB_NONE;
|
enum oob_formats oob_format = NAND_OOB_NONE;
|
||||||
|
|
||||||
image_t image;
|
fileio_t fileio;
|
||||||
int image_type_identified = 0;
|
|
||||||
|
|
||||||
duration_t duration;
|
duration_t duration;
|
||||||
char *duration_text;
|
char *duration_text;
|
||||||
|
@ -1187,7 +1186,7 @@ int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
u32 oob_size = 0;
|
u32 oob_size = 0;
|
||||||
|
|
||||||
duration_start_measure(&duration);
|
duration_start_measure(&duration);
|
||||||
strtoul(args[2], NULL, 0);
|
offset = strtoul(args[2], NULL, 0);
|
||||||
|
|
||||||
if (argc > 3)
|
if (argc > 3)
|
||||||
{
|
{
|
||||||
|
@ -1199,41 +1198,19 @@ int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
else if (!strcmp(args[i], "oob_only"))
|
else if (!strcmp(args[i], "oob_only"))
|
||||||
oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY;
|
oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY;
|
||||||
else
|
else
|
||||||
{
|
|
||||||
if (identify_image_type(&image.type, args[i]) == ERROR_OK)
|
|
||||||
{
|
|
||||||
image_type_identified = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
command_print(cmd_ctx, "unknown option: %s", args[i]);
|
command_print(cmd_ctx, "unknown option: %s", args[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* if no image type option was encountered, set the default */
|
if (fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
|
||||||
if (!image_type_identified)
|
|
||||||
{
|
{
|
||||||
|
command_print(cmd_ctx, "file open error: %s", fileio.error_str);
|
||||||
identify_image_type(&image.type, NULL);
|
|
||||||
image_type_identified = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
image.base_address_set = 1;
|
|
||||||
image.base_address = strtoul(args[2], NULL, 0);
|
|
||||||
image.start_address_set = 0;
|
|
||||||
|
|
||||||
if (image_open(&image, args[1], FILEIO_READ) != ERROR_OK)
|
|
||||||
{
|
|
||||||
command_print(cmd_ctx, "flash write error: %s", image.error_str);
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the offset might have been overwritten by the image base address */
|
buf_cnt = binary_size = fileio.size;
|
||||||
offset = image.base_address;
|
|
||||||
|
|
||||||
buf_cnt = binary_size = image.size;
|
|
||||||
|
|
||||||
if (!(oob_format & NAND_OOB_ONLY))
|
if (!(oob_format & NAND_OOB_ONLY))
|
||||||
{
|
{
|
||||||
|
@ -1262,7 +1239,7 @@ int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
|
|
||||||
if (page)
|
if (page)
|
||||||
{
|
{
|
||||||
image_read(&image, page_size, page, &size_read);
|
fileio_read(&fileio, page_size, page, &size_read);
|
||||||
buf_cnt -= size_read;
|
buf_cnt -= size_read;
|
||||||
if (size_read < page_size)
|
if (size_read < page_size)
|
||||||
{
|
{
|
||||||
|
@ -1272,7 +1249,7 @@ int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
|
|
||||||
if (oob)
|
if (oob)
|
||||||
{
|
{
|
||||||
image_read(&image, oob_size, oob, &size_read);
|
fileio_read(&fileio, oob_size, oob, &size_read);
|
||||||
buf_cnt -= size_read;
|
buf_cnt -= size_read;
|
||||||
if (size_read < oob_size)
|
if (size_read < oob_size)
|
||||||
{
|
{
|
||||||
|
@ -1289,9 +1266,11 @@ int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
offset += page_size;
|
offset += page_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileio_close(&fileio);
|
||||||
|
|
||||||
duration_stop_measure(&duration, &duration_text);
|
duration_stop_measure(&duration, &duration_text);
|
||||||
command_print(cmd_ctx, "wrote file %s to NAND flash %s at offset 0x%8.8x in %s",
|
command_print(cmd_ctx, "wrote file %s to NAND flash %s at offset 0x%8.8x in %s",
|
||||||
args[1], args[0], image.base_address, duration_text);
|
args[1], args[0], offset, duration_text);
|
||||||
free(duration_text);
|
free(duration_text);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#define OPENOCD_VERSION "Open On-Chip Debugger (2007-05-29 13:15 CEST)"
|
#define OPENOCD_VERSION "Open On-Chip Debugger (2007-05-30 17:45 CEST)"
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#ifndef ETM_H
|
#ifndef ETM_H
|
||||||
#define ETM_H
|
#define ETM_H
|
||||||
|
|
||||||
|
#include "image.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "register.h"
|
#include "register.h"
|
||||||
|
@ -142,7 +143,7 @@ typedef struct etm_context_s
|
||||||
etm_portmode_t portmode; /* normal, multiplexed or demultiplexed */
|
etm_portmode_t portmode; /* normal, multiplexed or demultiplexed */
|
||||||
etmv1_tracemode_t tracemode; /* type of information the trace contains (data, addres, contextID, ...) */
|
etmv1_tracemode_t tracemode; /* type of information the trace contains (data, addres, contextID, ...) */
|
||||||
armv4_5_state_t core_state; /* current core state (ARM, Thumb, Jazelle) */
|
armv4_5_state_t core_state; /* current core state (ARM, Thumb, Jazelle) */
|
||||||
// trace_image_provider_t image_provider; /* source for target opcodes */
|
image_t image; /* source for target opcodes */
|
||||||
u32 pipe_index; /* current trace cycle */
|
u32 pipe_index; /* current trace cycle */
|
||||||
u32 data_index; /* cycle holding next data packet */
|
u32 data_index; /* cycle holding next data packet */
|
||||||
u32 current_pc; /* current program counter */
|
u32 current_pc; /* current program counter */
|
||||||
|
|
|
@ -39,29 +39,38 @@ int image_ihex_buffer_complete(image_t *image)
|
||||||
fileio_t *fileio = &ihex->fileio;
|
fileio_t *fileio = &ihex->fileio;
|
||||||
u32 raw_bytes_read, raw_bytes;
|
u32 raw_bytes_read, raw_bytes;
|
||||||
int retval;
|
int retval;
|
||||||
u32 full_address = image->base_address;
|
u32 full_address = 0x0;
|
||||||
char *buffer = malloc(ihex->raw_size);
|
char *buffer = malloc(fileio->size);
|
||||||
u32 cooked_bytes = 0x0;
|
u32 cooked_bytes;
|
||||||
|
int i;
|
||||||
|
|
||||||
ihex->raw_size = fileio->size;
|
/* we can't determine the number of sections that we'll have to create ahead of time,
|
||||||
ihex->buffer = malloc(ihex->raw_size >> 1);
|
* so we locally hold them until parsing is finished */
|
||||||
|
image_section_t section[IMAGE_MAX_SECTIONS];
|
||||||
|
u8 *section_pointer[IMAGE_MAX_SECTIONS];
|
||||||
|
|
||||||
if ((retval = fileio_read(fileio, ihex->raw_size, (u8*)buffer, &raw_bytes_read)) != ERROR_OK)
|
if ((retval = fileio_read(fileio, fileio->size, (u8*)buffer, &raw_bytes_read)) != ERROR_OK)
|
||||||
{
|
{
|
||||||
free(buffer);
|
free(buffer);
|
||||||
ERROR("failed buffering IHEX file, read failed");
|
ERROR("failed buffering IHEX file, read failed");
|
||||||
return ERROR_FILEIO_OPERATION_FAILED;
|
return ERROR_FILEIO_OPERATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (raw_bytes_read != ihex->raw_size)
|
if (raw_bytes_read != fileio->size)
|
||||||
{
|
{
|
||||||
free(buffer);
|
free(buffer);
|
||||||
ERROR("failed buffering complete IHEX file, only partially read");
|
ERROR("failed buffering complete IHEX file, only partially read");
|
||||||
return ERROR_FILEIO_OPERATION_FAILED;
|
return ERROR_FILEIO_OPERATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
image->size = 0x0;
|
ihex->buffer = malloc(fileio->size >> 1);
|
||||||
raw_bytes = 0x0;
|
raw_bytes = 0x0;
|
||||||
|
cooked_bytes = 0x0;
|
||||||
|
image->num_sections = 0;
|
||||||
|
section_pointer[image->num_sections] = &ihex->buffer[cooked_bytes];
|
||||||
|
section[image->num_sections].base_address = 0x0;
|
||||||
|
section[image->num_sections].size = 0x0;
|
||||||
|
section[image->num_sections].flags = 0;
|
||||||
while (raw_bytes < raw_bytes_read)
|
while (raw_bytes < raw_bytes_read)
|
||||||
{
|
{
|
||||||
u32 count;
|
u32 count;
|
||||||
|
@ -75,13 +84,24 @@ int image_ihex_buffer_complete(image_t *image)
|
||||||
}
|
}
|
||||||
raw_bytes += 9;
|
raw_bytes += 9;
|
||||||
|
|
||||||
if (record_type == 0)
|
if (record_type == 0) /* Data Record */
|
||||||
{
|
{
|
||||||
if ((full_address & 0xffff) != address)
|
if ((full_address & 0xffff) != address)
|
||||||
{
|
{
|
||||||
free(buffer);
|
/* we encountered a nonconsecutive location, create a new section,
|
||||||
ERROR("can't handle non-linear IHEX file");
|
* unless the current section has zero size, in which case this specifies
|
||||||
return ERROR_IMAGE_FORMAT_ERROR;
|
* the current section's base address
|
||||||
|
*/
|
||||||
|
if (section[image->num_sections].size != 0)
|
||||||
|
{
|
||||||
|
image->num_sections++;
|
||||||
|
section[image->num_sections].size = 0x0;
|
||||||
|
section[image->num_sections].flags = 0;
|
||||||
|
section_pointer[image->num_sections] = &ihex->buffer[cooked_bytes];
|
||||||
|
}
|
||||||
|
section[image->num_sections].base_address =
|
||||||
|
(full_address & 0xffff0000) | address;
|
||||||
|
full_address = (full_address & 0xffff0000) | address;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (count-- > 0)
|
while (count-- > 0)
|
||||||
|
@ -89,16 +109,31 @@ int image_ihex_buffer_complete(image_t *image)
|
||||||
sscanf(&buffer[raw_bytes], "%2hhx", &ihex->buffer[cooked_bytes]);
|
sscanf(&buffer[raw_bytes], "%2hhx", &ihex->buffer[cooked_bytes]);
|
||||||
raw_bytes += 2;
|
raw_bytes += 2;
|
||||||
cooked_bytes += 1;
|
cooked_bytes += 1;
|
||||||
|
section[image->num_sections].size += 1;
|
||||||
full_address++;
|
full_address++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (record_type == 1)
|
else if (record_type == 1) /* End of File Record */
|
||||||
{
|
{
|
||||||
|
/* finish the current section */
|
||||||
|
image->num_sections++;
|
||||||
|
|
||||||
|
/* copy section information */
|
||||||
|
ihex->section_pointer = malloc(sizeof(u8*) * image->num_sections);
|
||||||
|
image->sections = malloc(sizeof(image_section_t) * image->num_sections);
|
||||||
|
for (i = 0; i < image->num_sections; i++)
|
||||||
|
{
|
||||||
|
ihex->section_pointer[i] = section_pointer[i];
|
||||||
|
image->sections[i].base_address = section[i].base_address +
|
||||||
|
((image->base_address_set) ? image->base_address : 0);
|
||||||
|
image->sections[i].size = section[i].size;
|
||||||
|
image->sections[i].flags = section[i].flags;
|
||||||
|
}
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
image->size = cooked_bytes;
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
else if (record_type == 4)
|
else if (record_type == 4) /* Extended Linear Address Record */
|
||||||
{
|
{
|
||||||
u16 upper_address;
|
u16 upper_address;
|
||||||
|
|
||||||
|
@ -107,12 +142,23 @@ int image_ihex_buffer_complete(image_t *image)
|
||||||
|
|
||||||
if ((full_address >> 16) != upper_address)
|
if ((full_address >> 16) != upper_address)
|
||||||
{
|
{
|
||||||
free(buffer);
|
/* we encountered a nonconsecutive location, create a new section,
|
||||||
ERROR("can't handle non-linear IHEX file");
|
* unless the current section has zero size, in which case this specifies
|
||||||
return ERROR_IMAGE_FORMAT_ERROR;
|
* the current section's base address
|
||||||
|
*/
|
||||||
|
if (section[image->num_sections].size != 0)
|
||||||
|
{
|
||||||
|
image->num_sections++;
|
||||||
|
section[image->num_sections].size = 0x0;
|
||||||
|
section[image->num_sections].flags = 0;
|
||||||
|
section_pointer[image->num_sections] = &ihex->buffer[cooked_bytes];
|
||||||
|
}
|
||||||
|
section[image->num_sections].base_address =
|
||||||
|
(full_address & 0xffff) | (upper_address << 16);
|
||||||
|
full_address = (full_address & 0xffff) | (upper_address << 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (record_type == 5)
|
else if (record_type == 5) /* Start Linear Address Record */
|
||||||
{
|
{
|
||||||
u32 start_address;
|
u32 start_address;
|
||||||
|
|
||||||
|
@ -163,10 +209,14 @@ int image_open(image_t *image, void *source, enum fileio_access access)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (access == FILEIO_WRITE)
|
image->num_sections = 1;
|
||||||
image->size = 0;
|
image->sections = malloc(sizeof(image_section_t));
|
||||||
else
|
image->sections[0].base_address = 0x0;
|
||||||
image->size = image_binary->fileio.size;
|
image->sections[0].size = image_binary->fileio.size;
|
||||||
|
image->sections[0].flags = 0;
|
||||||
|
|
||||||
|
if (image->base_address_set == 1)
|
||||||
|
image->sections[0].base_address = image->base_address;
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
@ -192,9 +242,6 @@ int image_open(image_t *image, void *source, enum fileio_access access)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
image_ihex->position = 0;
|
|
||||||
image_ihex->raw_size = image_ihex->fileio.size;
|
|
||||||
|
|
||||||
if ((retval = image_ihex_buffer_complete(image)) != ERROR_OK)
|
if ((retval = image_ihex_buffer_complete(image)) != ERROR_OK)
|
||||||
{
|
{
|
||||||
snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
|
snprintf(image->error_str, IMAGE_MAX_ERROR_STRING,
|
||||||
|
@ -217,7 +264,7 @@ int image_open(image_t *image, void *source, enum fileio_access access)
|
||||||
return retval;
|
return retval;
|
||||||
};
|
};
|
||||||
|
|
||||||
int image_read(image_t *image, u32 size, u8 *buffer, u32 *size_read)
|
int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
@ -225,6 +272,21 @@ int image_read(image_t *image, u32 size, u8 *buffer, u32 *size_read)
|
||||||
{
|
{
|
||||||
image_binary_t *image_binary = image->type_private;
|
image_binary_t *image_binary = image->type_private;
|
||||||
|
|
||||||
|
/* only one section in a plain binary */
|
||||||
|
if (section != 0)
|
||||||
|
return ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
|
if ((offset > image->sections[0].size) || (offset + size > image->sections[0].size))
|
||||||
|
return ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
|
/* seek to offset */
|
||||||
|
if ((retval = fileio_seek(&image_binary->fileio, offset)) != ERROR_OK)
|
||||||
|
{
|
||||||
|
strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return requested bytes */
|
||||||
if ((retval = fileio_read(&image_binary->fileio, size, buffer, size_read)) != ERROR_OK)
|
if ((retval = fileio_read(&image_binary->fileio, size, buffer, size_read)) != ERROR_OK)
|
||||||
{
|
{
|
||||||
strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
|
strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
|
||||||
|
@ -235,14 +297,7 @@ int image_read(image_t *image, u32 size, u8 *buffer, u32 *size_read)
|
||||||
{
|
{
|
||||||
image_ihex_t *image_ihex = image->type_private;
|
image_ihex_t *image_ihex = image->type_private;
|
||||||
|
|
||||||
if ((image_ihex->position + size) > image->size)
|
memcpy(buffer, image_ihex->section_pointer[section] + offset, size);
|
||||||
{
|
|
||||||
/* don't read past the end of the file */
|
|
||||||
size = (image->size - image_ihex->position);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(buffer, image_ihex->buffer + image_ihex->position, size);
|
|
||||||
image_ihex->position += size;
|
|
||||||
*size_read = size;
|
*size_read = size;
|
||||||
image->error_str[0] = '\0';
|
image->error_str[0] = '\0';
|
||||||
|
|
||||||
|
@ -256,37 +311,6 @@ int image_read(image_t *image, u32 size, u8 *buffer, u32 *size_read)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int image_write(image_t *image, u32 size, u8 *buffer, u32 *size_written)
|
|
||||||
{
|
|
||||||
int retval = ERROR_FILEIO_OPERATION_NOT_SUPPORTED;
|
|
||||||
|
|
||||||
if (image->type == IMAGE_BINARY)
|
|
||||||
{
|
|
||||||
image_binary_t *image_binary = image->type_private;
|
|
||||||
|
|
||||||
if ((retval = fileio_write(&image_binary->fileio, size, buffer, size_written)) != ERROR_OK)
|
|
||||||
{
|
|
||||||
strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (image->type == IMAGE_IHEX)
|
|
||||||
{
|
|
||||||
return ERROR_FILEIO_OPERATION_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
else if (image->type == IMAGE_MEMORY)
|
|
||||||
{
|
|
||||||
/* TODO: handle target memory pseudo image */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retval != ERROR_OK)
|
|
||||||
return retval;
|
|
||||||
|
|
||||||
image->size += size;
|
|
||||||
|
|
||||||
return ERROR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int image_close(image_t *image)
|
int image_close(image_t *image)
|
||||||
{
|
{
|
||||||
if (image->type == IMAGE_BINARY)
|
if (image->type == IMAGE_BINARY)
|
||||||
|
@ -301,6 +325,9 @@ int image_close(image_t *image)
|
||||||
|
|
||||||
fileio_close(&image_ihex->fileio);
|
fileio_close(&image_ihex->fileio);
|
||||||
|
|
||||||
|
if (image_ihex->section_pointer)
|
||||||
|
free(image_ihex->section_pointer);
|
||||||
|
|
||||||
if (image_ihex->buffer)
|
if (image_ihex->buffer)
|
||||||
free(image_ihex->buffer);
|
free(image_ihex->buffer);
|
||||||
}
|
}
|
||||||
|
@ -309,8 +336,12 @@ int image_close(image_t *image)
|
||||||
/* do nothing for now */
|
/* do nothing for now */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (image->type_private)
|
||||||
free(image->type_private);
|
free(image->type_private);
|
||||||
|
|
||||||
|
if (image->sections)
|
||||||
|
free(image->sections);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
|
||||||
#define IMAGE_MAX_ERROR_STRING (128)
|
#define IMAGE_MAX_ERROR_STRING (128)
|
||||||
|
#define IMAGE_MAX_SECTIONS (128)
|
||||||
|
|
||||||
typedef enum image_type
|
typedef enum image_type
|
||||||
{
|
{
|
||||||
|
@ -37,15 +38,23 @@ typedef enum image_type
|
||||||
*/
|
*/
|
||||||
} image_type_t;
|
} image_type_t;
|
||||||
|
|
||||||
|
typedef struct image_section_s
|
||||||
|
{
|
||||||
|
u32 base_address;
|
||||||
|
u32 size;
|
||||||
|
int flags;
|
||||||
|
} image_section_t;
|
||||||
|
|
||||||
typedef struct image_s
|
typedef struct image_s
|
||||||
{
|
{
|
||||||
image_type_t type; /* image type (plain, ihex, ...) */
|
image_type_t type; /* image type (plain, ihex, ...) */
|
||||||
void *type_private; /* type private data */
|
void *type_private; /* type private data */
|
||||||
int base_address_set; /* whether the image start address has been set */
|
int num_sections; /* number of sections contained in the image */
|
||||||
u32 base_address; /* base address of image in target memory */
|
image_section_t *sections; /* array of sections */
|
||||||
|
int base_address_set; /* whether the image has a base address set (for relocation purposes) */
|
||||||
|
int base_address; /* base address, if one is set */
|
||||||
int start_address_set; /* whether the image has a start address (entry point) associated */
|
int start_address_set; /* whether the image has a start address (entry point) associated */
|
||||||
u32 start_address; /* start address, if one is set */
|
u32 start_address; /* start address, if one is set */
|
||||||
u32 size; /* image size in byte */
|
|
||||||
char error_str[IMAGE_MAX_ERROR_STRING];
|
char error_str[IMAGE_MAX_ERROR_STRING];
|
||||||
} image_t;
|
} image_t;
|
||||||
|
|
||||||
|
@ -57,9 +66,8 @@ typedef struct image_binary_s
|
||||||
typedef struct image_ihex_s
|
typedef struct image_ihex_s
|
||||||
{
|
{
|
||||||
fileio_t fileio;
|
fileio_t fileio;
|
||||||
u32 position;
|
|
||||||
u32 raw_size;
|
|
||||||
u8 *buffer;
|
u8 *buffer;
|
||||||
|
u8 **section_pointer;
|
||||||
} image_ihex_t;
|
} image_ihex_t;
|
||||||
|
|
||||||
typedef struct image_memory_s
|
typedef struct image_memory_s
|
||||||
|
@ -68,8 +76,7 @@ typedef struct image_memory_s
|
||||||
} image_memory_t;
|
} image_memory_t;
|
||||||
|
|
||||||
extern int image_open(image_t *image, void *source, enum fileio_access access);
|
extern int image_open(image_t *image, void *source, enum fileio_access access);
|
||||||
extern int image_read(image_t *image, u32 size, u8 *buffer, u32 *size_written);
|
extern int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read);
|
||||||
extern int image_write(image_t *image, u32 size, u8 *buffer, u32 *size_written);
|
|
||||||
extern int image_close(image_t *image);
|
extern int image_close(image_t *image);
|
||||||
extern int identify_image_type(image_type_t *type, char *type_string);
|
extern int identify_image_type(image_type_t *type, char *type_string);
|
||||||
|
|
||||||
|
|
|
@ -1658,6 +1658,8 @@ int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
u8 *buffer;
|
u8 *buffer;
|
||||||
u32 buf_cnt;
|
u32 buf_cnt;
|
||||||
u32 image_size;
|
u32 image_size;
|
||||||
|
int i;
|
||||||
|
int retval;
|
||||||
|
|
||||||
image_t image;
|
image_t image;
|
||||||
|
|
||||||
|
@ -1679,8 +1681,6 @@ int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
|
|
||||||
image.start_address_set = 0;
|
image.start_address_set = 0;
|
||||||
|
|
||||||
buffer = malloc(128 * 1024);
|
|
||||||
|
|
||||||
duration_start_measure(&duration);
|
duration_start_measure(&duration);
|
||||||
|
|
||||||
if (image_open(&image, args[0], FILEIO_READ) != ERROR_OK)
|
if (image_open(&image, args[0], FILEIO_READ) != ERROR_OK)
|
||||||
|
@ -1689,21 +1689,27 @@ int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
image_size = image.size;
|
image_size = 0x0;
|
||||||
address = image.base_address;
|
for (i = 0; i < image.num_sections; i++)
|
||||||
|
|
||||||
while ((image_size > 0) &&
|
|
||||||
(image_read(&image, 128 * 1024, buffer, &buf_cnt) == ERROR_OK))
|
|
||||||
{
|
{
|
||||||
target_write_buffer(target, address, buf_cnt, buffer);
|
buffer = malloc(image.sections[i].size);
|
||||||
address += buf_cnt;
|
if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
|
||||||
image_size -= buf_cnt;
|
{
|
||||||
|
ERROR("image_read_section failed with error code: %i", retval);
|
||||||
|
command_print(cmd_ctx, "image reading failed, download aborted");
|
||||||
|
free(buffer);
|
||||||
|
image_close(&image);
|
||||||
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
target_write_buffer(target, image.sections[i].base_address, buf_cnt, buffer);
|
||||||
|
image_size += buf_cnt;
|
||||||
|
command_print(cmd_ctx, "%u byte written at address 0x%8.8x", buf_cnt, image.sections[i].base_address);
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
duration_stop_measure(&duration, &duration_text);
|
duration_stop_measure(&duration, &duration_text);
|
||||||
command_print(cmd_ctx, "downloaded %u byte in %s", image.size, duration_text);
|
command_print(cmd_ctx, "downloaded %u byte in %s", image_size, duration_text);
|
||||||
free(duration_text);
|
free(duration_text);
|
||||||
|
|
||||||
image_close(&image);
|
image_close(&image);
|
||||||
|
|
Loading…
Reference in New Issue