I'm thinking that the lpc flash drivers calc_checksum should be retired. In it's place a warning/info should be printed with the expected checksum so that the user can manually write a checksum or somehow arrange the developer host PC tools to come up with the right checksum.
The LPC flash driver has the ability to calculate a checksum that should be stored in a specific location in the flash (0x14). (calc_checksum option) However, this is a very awkward feature with surprising and confusing effects. Consider what happens when you write an image and try to verify: - an image is passed to the lpc driver - the lpc flash driver writes the image, except that it calculates a checksum - verification in the higher layers now fails because the flash driver didn't write what the flash write_image command thought it was going to write It gets a bit worse: the flash driver modifies the memory passed in to the flash write fn. Typical for C function prototypes, const isn't used here in the API to make it clear that really that argument is a write only argument. The attached patch modifies the lpc flash driver not to modify the input buffer, such that "flash fillX" exhibits the verify error. -- Øyvind Harboe Embedded software and hardware consulting services http://consulting.zylin.com
### Eclipse Workspace Patch 1.0 #P openocd Index: src/flash/lpc2000.c =================================================================== --- src/flash/lpc2000.c (revision 1576) +++ src/flash/lpc2000.c (working copy) @@ -2,6 +2,9 @@ * Copyright (C) 2005 by Dominic Rath * * dominic.r...@gmx.de * * * + * Copyright (C) 2009 by Ųyvind Harboe * + * oyvind.har...@zylin.com * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -17,7 +20,6 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -518,21 +520,6 @@ LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector); - /* check if exception vectors should be flashed */ - if ((offset == 0) && (count >= 0x20) && lpc2000_info->calc_checksum) - { - u32 checksum = 0; - int i = 0; - for (i = 0; i < 8; i++) - { - LOG_DEBUG("0x%2.2x: 0x%8.8x", i * 4, buf_get_u32(buffer + (i * 4), 0, 32)); - if (i != 5) - checksum += buf_get_u32(buffer + (i * 4), 0, 32); - } - checksum = 0 - checksum; - LOG_DEBUG("checksum: 0x%8.8x", checksum); - buf_set_u32(buffer + 0x14, 0, 32, checksum); - } /* allocate a working area */ if (target_alloc_working_area(target, lpc2000_info->cmd51_max_buffer, &download_area) != ERROR_OK) @@ -577,25 +564,31 @@ if (retval != ERROR_OK) break; - if (bytes_remaining >= thisrun_bytes) + u8 *last_buffer = malloc(thisrun_bytes); + + /* check if exception vectors should be flashed */ + if ((offset+bytes_written == 0) && (thisrun_bytes >= 0x20) && lpc2000_info->calc_checksum) { - if ((retval = target_write_buffer(bank->target, download_area->address, thisrun_bytes, buffer + bytes_written)) != ERROR_OK) + u32 checksum = 0; + int i = 0; + for (i = 0; i < 8; i++) { - retval = ERROR_FLASH_OPERATION_FAILED; - break; + LOG_DEBUG("0x%2.2x: 0x%8.8x", i * 4, buf_get_u32(buffer + (i * 4), 0, 32)); + if (i != 5) + checksum += buf_get_u32(buffer + (i * 4), 0, 32); } - } - else - { - u8 *last_buffer = malloc(thisrun_bytes); - u32 i; - memcpy(last_buffer, buffer + bytes_written, bytes_remaining); - for (i = bytes_remaining; i < thisrun_bytes; i++) - last_buffer[i] = 0xff; - target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer); - free(last_buffer); + checksum = 0 - checksum; + LOG_DEBUG("checksum: 0x%8.8x", checksum); + buf_set_u32(last_buffer + 0x14, 0, 32, checksum); } + u32 i; + memcpy(last_buffer, buffer + bytes_written, bytes_remaining); + for (i = bytes_remaining; i < thisrun_bytes; i++) + last_buffer[i] = 0xff; + target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer); + free(last_buffer); + LOG_DEBUG("writing 0x%x bytes to address 0x%x", thisrun_bytes, bank->base + offset + bytes_written); /* Write data */
_______________________________________________ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development