- reworked image handling to support multiple sections (tested with ihex file contain...
authordrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Wed, 30 May 2007 15:47:18 +0000 (15:47 +0000)
committerdrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Wed, 30 May 2007 15:47:18 +0000 (15:47 +0000)
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

src/flash/flash.c
src/flash/nand.c
src/openocd.c
src/target/etm.h
src/target/image.c
src/target/image.h
src/target/target.c

index 6af29825ca293b17b85e9c1a465551e54df720b1..58a467d2b30b66e53186d2dc658e7abb8473f67d 100644 (file)
@@ -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)
 {
        u32 offset;
-       u32 binary_size;
        u8 *buffer;
        u32 buf_cnt;
+       u32 image_size;
+       int i;
 
        image_t image;
        
@@ -531,51 +532,62 @@ int handle_flash_write_command(struct command_context_s *cmd_ctx, char *cmd, cha
                return ERROR_OK;
        }
        
-       binary_size = image.size;
-       buffer = malloc(binary_size);
-
-       image_read(&image, binary_size, buffer, &buf_cnt);
-       
-       if ((retval = p->driver->write(p, buffer, offset, buf_cnt)) != ERROR_OK)
+       image_size = 0x0;
+       for (i = 0; i < image.num_sections; i++)
        {
-               command_print(cmd_ctx, "failed writing file %s to flash bank %i at offset 0x%8.8x",
-                       args[1], strtoul(args[0], NULL, 0), strtoul(args[2], NULL, 0));
-               switch (retval)
+               buffer = malloc(image.sections[i].size);
+               if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
                {
-                       case ERROR_TARGET_NOT_HALTED:
-                               command_print(cmd_ctx, "can't work with this flash while target is running");
-                               break;
-                       case ERROR_INVALID_ARGUMENTS:
-                               command_print(cmd_ctx, "usage: flash write <bank> <file> <offset>");
-                               break;
-                       case ERROR_FLASH_BANK_INVALID:
-                               command_print(cmd_ctx, "no '%s' flash found at 0x%8.8x", p->driver->name, p->base);
-                               break;
-                       case ERROR_FLASH_OPERATION_FAILED:
-                               command_print(cmd_ctx, "flash program error");
-                               break;
-                       case ERROR_FLASH_DST_BREAKS_ALIGNMENT:
-                               command_print(cmd_ctx, "offset breaks required alignment");
-                               break;
-                       case ERROR_FLASH_DST_OUT_OF_BANK:
-                               command_print(cmd_ctx, "destination is out of flash bank (offset and/or file too large)");
-                               break;
-                       case ERROR_FLASH_SECTOR_NOT_ERASED:
-                               command_print(cmd_ctx, "destination sector(s) not erased");
-                               break;
-                       default:
-                               command_print(cmd_ctx, "unknown error");
+                       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)
+               {
+                       command_print(cmd_ctx, "failed writing file %s to flash bank %i at offset 0x%8.8x",
+                               args[1], strtoul(args[0], NULL, 0), strtoul(args[2], NULL, 0));
+                       switch (retval)
+                       {
+                               case ERROR_TARGET_NOT_HALTED:
+                                       command_print(cmd_ctx, "can't work with this flash while target is running");
+                                       break;
+                               case ERROR_INVALID_ARGUMENTS:
+                                       command_print(cmd_ctx, "usage: flash write <bank> <file> <offset>");
+                                       break;
+                               case ERROR_FLASH_BANK_INVALID:
+                                       command_print(cmd_ctx, "no '%s' flash found at 0x%8.8x", p->driver->name, p->base);
+                                       break;
+                               case ERROR_FLASH_OPERATION_FAILED:
+                                       command_print(cmd_ctx, "flash program error");
+                                       break;
+                               case ERROR_FLASH_DST_BREAKS_ALIGNMENT:
+                                       command_print(cmd_ctx, "offset breaks required alignment");
+                                       break;
+                               case ERROR_FLASH_DST_OUT_OF_BANK:
+                                       command_print(cmd_ctx, "destination is out of flash bank (offset and/or file too large)");
+                                       break;
+                               case ERROR_FLASH_SECTOR_NOT_ERASED:
+                                       command_print(cmd_ctx, "destination sector(s) not erased");
+                                       break;
+                               default:
+                                       command_print(cmd_ctx, "unknown error");
+                       }
+               }
+               image_size += buf_cnt;
+
+               free(buffer);
        }
-       else
-       {
-               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);
+       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);
        
        return ERROR_OK;
index 38a70749a4f2553662df8a352cdcc53b30e04026..7ff73512d922a529c266997bd131309f92ca2739 100644 (file)
@@ -1164,8 +1164,7 @@ int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char
        u32 buf_cnt;
        enum oob_formats oob_format = NAND_OOB_NONE;
        
-       image_t image;
-       int image_type_identified = 0;
+       fileio_t fileio;
        
        duration_t duration;
        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;
                        
                duration_start_measure(&duration);
-               strtoul(args[2], NULL, 0);
+               offset = strtoul(args[2], NULL, 0);
                
                if (argc > 3)
                {
@@ -1200,40 +1199,18 @@ int handle_nand_write_command(struct command_context_s *cmd_ctx, char *cmd, char
                                        oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY;
                                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 (!image_type_identified)
-               {
-                       
-                       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)
+               if (fileio_open(&fileio, args[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
                {
-                       command_print(cmd_ctx, "flash write error: %s", image.error_str);
+                       command_print(cmd_ctx, "file open error: %s", fileio.error_str);
                        return ERROR_OK;
                }
        
-               /* the offset might have been overwritten by the image base address */
-               offset = image.base_address;
-               
-               buf_cnt = binary_size = image.size;
+               buf_cnt = binary_size = fileio.size;
                
                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)
                        {
-                               image_read(&image, page_size, page, &size_read);
+                               fileio_read(&fileio, page_size, page, &size_read);
                                buf_cnt -= size_read;
                                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)
                        {
-                               image_read(&image, oob_size, oob, &size_read);
+                               fileio_read(&fileio, oob_size, oob, &size_read);
                                buf_cnt -= size_read;
                                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;
                }
 
+               fileio_close(&fileio);
+               
                duration_stop_measure(&duration, &duration_text);
                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);
        }
        else
index 10a4cfd28e4eb889c4422266cd93c21209f1c29f..9601b9ef1baf96969f39310d34e61a3b6709a3e1 100644 (file)
@@ -18,7 +18,7 @@
  *   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
 #include "config.h"
index 595917885a56dcd93518a42dc81def870c62a410..65fd757c8d3971b117f11150d7250162d5cfefcd 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef ETM_H\r
 #define ETM_H\r
 \r
+#include "image.h"\r
 #include "trace.h"\r
 #include "target.h"\r
 #include "register.h"\r
@@ -142,7 +143,7 @@ typedef struct etm_context_s
        etm_portmode_t portmode;                /* normal, multiplexed or demultiplexed */\r
        etmv1_tracemode_t tracemode;    /* type of information the trace contains (data, addres, contextID, ...) */ \r
        armv4_5_state_t core_state;             /* current core state (ARM, Thumb, Jazelle) */\r
-//     trace_image_provider_t image_provider;  /* source for target opcodes */\r
+       image_t image;                                  /* source for target opcodes */\r
        u32 pipe_index;                                 /* current trace cycle */\r
        u32 data_index;                                 /* cycle holding next data packet */\r
        u32 current_pc;                                 /* current program counter */\r
index 3cc9cc5b1d928e4449b6ba7621e7ff43786f3f56..7381440ed604942f75a7c22167ad70156425b4ff 100644 (file)
@@ -39,29 +39,38 @@ int image_ihex_buffer_complete(image_t *image)
        fileio_t *fileio = &ihex->fileio;
        u32 raw_bytes_read, raw_bytes;
        int retval;
-       u32 full_address = image->base_address;
-       char *buffer = malloc(ihex->raw_size);
-       u32 cooked_bytes = 0x0;
+       u32 full_address = 0x0;
+       char *buffer = malloc(fileio->size);
+       u32 cooked_bytes;
+       int i;
        
-       ihex->raw_size = fileio->size;
-       ihex->buffer = malloc(ihex->raw_size >> 1);
+       /* we can't determine the number of sections that we'll have to create ahead of time,
+        * 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);
                ERROR("failed buffering IHEX file, read failed");
                return ERROR_FILEIO_OPERATION_FAILED;
        }
        
-       if (raw_bytes_read != ihex->raw_size)
+       if (raw_bytes_read != fileio->size)
        {
                free(buffer);
                ERROR("failed buffering complete IHEX file, only partially read");
                return ERROR_FILEIO_OPERATION_FAILED;
        }
-       
-       image->size = 0x0;
+
+       ihex->buffer = malloc(fileio->size >> 1);
        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)
        {
                u32 count;
@@ -75,13 +84,24 @@ int image_ihex_buffer_complete(image_t *image)
                }
                raw_bytes += 9;
                
-               if (record_type == 0)
+               if (record_type == 0) /* Data Record */
                {
                        if ((full_address & 0xffff) != address)
                        {
-                               free(buffer);
-                               ERROR("can't handle non-linear IHEX file");
-                               return ERROR_IMAGE_FORMAT_ERROR;
+                               /* we encountered a nonconsecutive location, create a new section,
+                                * unless the current section has zero size, in which case this specifies
+                                * 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)
@@ -89,16 +109,31 @@ int image_ihex_buffer_complete(image_t *image)
                                sscanf(&buffer[raw_bytes], "%2hhx", &ihex->buffer[cooked_bytes]);
                                raw_bytes += 2;
                                cooked_bytes += 1;
+                               section[image->num_sections].size += 1;
                                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);
-                       image->size = cooked_bytes;
                        return ERROR_OK;
                }
-               else if (record_type == 4)
+               else if (record_type == 4) /* Extended Linear Address Record */
                {
                        u16 upper_address;
                        
@@ -107,12 +142,23 @@ int image_ihex_buffer_complete(image_t *image)
                        
                        if ((full_address >> 16) != upper_address)
                        {
-                               free(buffer);
-                               ERROR("can't handle non-linear IHEX file");
-                               return ERROR_IMAGE_FORMAT_ERROR;
+                               /* we encountered a nonconsecutive location, create a new section,
+                                * unless the current section has zero size, in which case this specifies
+                                * 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;
                        
@@ -163,10 +209,14 @@ int image_open(image_t *image, void *source, enum fileio_access access)
                        return retval;
                }
                
-               if (access == FILEIO_WRITE)
-                       image->size = 0;
-               else
-                       image->size = image_binary->fileio.size;
+               image->num_sections = 1;
+               image->sections = malloc(sizeof(image_section_t));
+               image->sections[0].base_address = 0x0;
+               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;
        }
@@ -192,9 +242,6 @@ int image_open(image_t *image, void *source, enum fileio_access access)
                        return retval;
                }
                
-               image_ihex->position = 0;
-               image_ihex->raw_size = image_ihex->fileio.size;
-               
                if ((retval = image_ihex_buffer_complete(image)) != ERROR_OK)
                {
                        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;
 };
 
-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;
        
@@ -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;
                
+               /* 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)
                {
                        strncpy(image->error_str, image_binary->fileio.error_str, IMAGE_MAX_ERROR_STRING);
@@ -234,15 +296,8 @@ int image_read(image_t *image, u32 size, u8 *buffer, u32 *size_read)
        else if (image->type == IMAGE_IHEX)
        {
                image_ihex_t *image_ihex = image->type_private;
-       
-               if ((image_ihex->position + size) > image->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;
+
+               memcpy(buffer, image_ihex->section_pointer[section] + offset, size);
                *size_read = size;
                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;
 }
 
-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)
 {
        if (image->type == IMAGE_BINARY)
@@ -301,6 +325,9 @@ int image_close(image_t *image)
                
                fileio_close(&image_ihex->fileio);
                
+               if (image_ihex->section_pointer)
+                       free(image_ihex->section_pointer);
+               
                if (image_ihex->buffer)
                        free(image_ihex->buffer);
        }
@@ -309,7 +336,11 @@ int image_close(image_t *image)
                /* do nothing for now */
        }
 
-       free(image->type_private);
+       if (image->type_private)
+               free(image->type_private);
+       
+       if (image->sections)
+               free(image->sections);
        
        return ERROR_OK;
 }
index 3df175a8d6c3ccd07737bee065b15a5fb08ce0ec..75288791a6394a6a2b8f5820c776a669cf86c824 100644 (file)
 #include "target.h"
 
 #define IMAGE_MAX_ERROR_STRING         (128)
+#define IMAGE_MAX_SECTIONS                     (128)
 
 typedef enum image_type
 {
     IMAGE_BINARY,      /* plain binary */
-    IMAGE_IHEX,        /* intel hex-record format */
+    IMAGE_IHEX,                /* intel hex-record format */
     IMAGE_MEMORY,      /* target-memory pseudo-image */
 /*
  * Possible future enhancements:
@@ -37,15 +38,23 @@ typedef enum image_type
  */
 } image_type_t;
 
+typedef struct image_section_s
+{
+       u32 base_address;
+       u32 size;
+       int flags;
+} image_section_t;
+
 typedef struct image_s
 {
        image_type_t type;              /* image type (plain, ihex, ...) */
        void *type_private;             /* type private data */
-       int base_address_set;   /* whether the image start address has been set */
-       u32 base_address;               /* base address of image in target memory */
+       int num_sections;               /* number of sections contained in the image */
+       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 */
        u32 start_address;              /* start address, if one is set */
-       u32 size;                               /* image size in byte */
        char error_str[IMAGE_MAX_ERROR_STRING];
 } image_t;
 
@@ -57,9 +66,8 @@ typedef struct image_binary_s
 typedef struct image_ihex_s
 {
        fileio_t fileio;
-       u32 position;
-       u32 raw_size;
        u8 *buffer;
+       u8 **section_pointer;
 } image_ihex_t;
 
 typedef struct image_memory_s
@@ -68,8 +76,7 @@ typedef struct image_memory_s
 } image_memory_t;
 
 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_write(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_close(image_t *image);
 extern int identify_image_type(image_type_t *type, char *type_string);
 
index e980ae4a147239143ccd80b1473ab4c0fb6127ca..b7f842e7b8f85e8641a00bc79a9e063774e64395 100644 (file)
@@ -1658,6 +1658,8 @@ int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char
        u8 *buffer;
        u32 buf_cnt;
        u32 image_size;
+       int i;
+       int retval;
 
        image_t image;  
        
@@ -1678,8 +1680,6 @@ int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char
        image.base_address = strtoul(args[1], NULL, 0);
        
        image.start_address_set = 0;
-       
-       buffer = malloc(128 * 1024);
 
        duration_start_measure(&duration);
        
@@ -1689,21 +1689,27 @@ int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char
                return ERROR_OK;
        }
        
-       image_size = image.size;
-       address = image.base_address;
-       
-       while ((image_size > 0) &&
-               (image_read(&image, 128 * 1024, buffer, &buf_cnt) == ERROR_OK))
+       image_size = 0x0;
+       for (i = 0; i < image.num_sections; i++)
        {
-               target_write_buffer(target, address, buf_cnt, buffer);
-               address += buf_cnt;
-               image_size -= 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, 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);
-       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);
        
        image_close(&image);

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)