STM32x Flash programming issues - ARM-USB-OSD, STM32x10xxB

Hello,

I am working with IAR EWARM and OpenOCD from SVN rev.1379M (see environment description at the end). Despite of several minor issues I try to live with, I came to a full stop:

while debugging mysterious BusFaults and HardFaults, I found that, when downloading compiled image from within EWARM IDE to FLASH, random runs of 16-byte sized blocks gets corrupted:

Tue Mar 03 01:23:16 2009: Loaded macro file: C:\Program Files\IAR Systems\Embedded Workbench 5.4\arm\config\flashloader\ST\FlashSTM32F10xxx.mac 
Tue Mar 03 01:23:17 2009: -I- execUserFlashInit! 
Tue Mar 03 01:23:17 2009: 456 bytes downloaded and verified (0.98 Kbytes/sec) 
Tue Mar 03 01:23:17 2009: Loaded debugee: C:\Program Files\IAR Systems\Embedded Workbench 5.4\arm\config\flashloader\ST\FlashSTM32F10xxxRAM16K.out 
Tue Mar 03 01:23:17 2009: Target reset 
Tue Mar 03 01:23:20 2009: Software reset was performed 
Tue Mar 03 01:23:21 2009: 8164 bytes downloaded into FLASH and verified (1.91 Kbytes/sec) 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001D0, target byte: 0x90, byte in file: 0x01 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001D1, target byte: 0x3D, byte in file: 0xD2 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001D2, target byte: 0x00, byte in file: 0x01 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001D3, target byte: 0x20, byte in file: 0xF0 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001D4, target byte: 0x90, byte in file: 0x3F 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001D5, target byte: 0x04, byte in file: 0xFB 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001D6, target byte: 0x00, byte in file: 0x20 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001D7, target byte: 0x08, byte in file: 0x46 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001D8, target byte: 0x10, byte in file: 0xBD 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001D9, target byte: 0x2E, byte in file: 0xE8 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001DA, target byte: 0x00, byte in file: 0xF0 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001DB, target byte: 0x20, byte in file: 0x87 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001DC, target byte: 0x31, byte in file: 0xF8 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001DD, target byte: 0x01, byte in file: 0xB5 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001DE, target byte: 0x00, byte in file: 0x05 
Tue Mar 03 01:23:21 2009: Warning:  
Verify error at address 0x080001DF, target byte: 0x20, byte in file: 0x46 
Tue Mar 03 01:23:21 2009: Warning: There were warnings during download, see Log Window 
Tue Mar 03 01:23:23 2009: Loaded debugee: D:\PROJECTS\TEST\Firmware\Debug\Exe\Firmware.out 
Tue Mar 03 01:23:23 2009: Software reset was performed 
Tue Mar 03 01:23:23 2009: Target reset

Data in 16-byte runs seem to be corrupted in random way - differs from download to download, although the offset is more-or-less constant. Furthermore, I tried to test my chips to ensure they were not damaged by issuing on telnet:

Open On-Chip Debugger
> reset halt
JTAG tap: stm32.cpu tap/device found: 0x3ba00477 (Manufacturer: 0x23b, Part: 0xba00, Version: 0x3)
JTAG Tap/device matched
JTAG tap: stm32.bs tap/device found: 0x16410041 (Manufacturer: 0x020, Part: 0x6410, Version: 0x1)
JTAG Tap/device matched
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08001ec4

> stm32x mass_erase 0
device id = 0x20006410
flash size = 128kbytes
stm32x mass erase complete

> flash erase_check 0
successfully checked erase state
        #  0: 0x00000000 (0x400 1kB) erased
        #  1: 0x00000400 (0x400 1kB) erased
        #  2: 0x00000800 (0x400 1kB) erased
...
...
...
        #125: 0x0001f400 (0x400 1kB) erased
        #126: 0x0001f800 (0x400 1kB) erased
        #127: 0x0001fc00 (0x400 1kB) erased

> flash fillw 0x08000000 0x12345678 32768
wrote 131072 bytes to 0x08000000 in 52.703125s (2.428699 kb/s)

> flash erase_check 0
successfully checked erase state
        #  0: 0x00000000 (0x400 1kB) not erased
        #  1: 0x00000400 (0x400 1kB) erased
        #  2: 0x00000800 (0x400 1kB) not erased
        #  3: 0x00000c00 (0x400 1kB) erased
        #  4: 0x00001000 (0x400 1kB) not erased
        #  5: 0x00001400 (0x400 1kB) erased
        #  6: 0x00001800 (0x400 1kB) not erased
        #  7: 0x00001c00 (0x400 1kB) erased
        #  8: 0x00002000 (0x400 1kB) not erased
        #  9: 0x00002400 (0x400 1kB) erased
        # 10: 0x00002800 (0x400 1kB) not erased
        # 11: 0x00002c00 (0x400 1kB) erased
        # 12: 0x00003000 (0x400 1kB) not erased
        # 13: 0x00003400 (0x400 1kB) erased
        # 14: 0x00003800 (0x400 1kB) not erased
        # 15: 0x00003c00 (0x400 1kB) erased
...
...
...
        #122: 0x0001e800 (0x400 1kB) not erased
        #123: 0x0001ec00 (0x400 1kB) erased
        #124: 0x0001f000 (0x400 1kB) not erased
        #125: 0x0001f400 (0x400 1kB) erased
        #126: 0x0001f800 (0x400 1kB) not erased
        #127: 0x0001fc00 (0x400 1kB) erased

> dump_image flash_contents.dmp 0x08000000 131072
dumped 131072 byte in 7.875000s

>_

flash fillw filled consistently every second 1kb segment of FLASH. The file flash_contents.dmp confirms this. I can successfully fill the gaps with flash fillw 0x08000400 0x87654321 32512, and I get 1kb-blocks of 0x12345678 interleaved with same sized 0x87654321-filled blocks.

My environment is:

IAR EWARM 5.30.1 set up to use GDB debugger, XP Pro with latest FT2232 drivers (from ftdichip.com), oocd from SVN 1379M (modified not to #define ARMV7_GDB_HACKS), compiled with -mno_cygwin and ftd2xx.

config: arm-usb-ocd.cfg from SVN (tried jtag_khz 100 with no imrpvements), stm32x.cfg from SVN, with adjusted set _BSTAPID to suit my MCU.

HW: ARM-USB-OCD, 2x devel boards STM32-P103 from Olimex (STM32F103RBT6, rev.B), with separate TRST and SRST. Exactly the same issue is with my 3 other own boards with STM32F103CBT6, rev. Z.

I am keen on helping with testing to improve the quality of OpenOCD, so if I need to provide some additional info - just ask, I will do so. Unfortunately, I have had all kinds of problems with openocd already for about a year. I am updating OpenOCD constantly from SVN - some things improve, some things gets broken; sadly there is no working alternative to openocd, not necessarily free, but with sane price tag :frowning:

Kind regards to all.[/code]

Hi,

Quick-checked through the code and found that flash fill* does not work correctly when count>1024. Below is a diff to fix this:

Index: flash.c
===================================================================
--- flash.c	(revision 1396)
+++ flash.c	(working copy)
@@ -727,6 +727,7 @@
 	u32 count;
 	u8 chunk[1024];
 	u32 wrote = 0;
+	u32 cur_size = 0;
 	int chunk_count;
 	char *duration_text;
 	duration_t duration;
@@ -786,9 +787,9 @@
 
 	duration_start_measure(&duration);
 
-	for (wrote=0; wrote<(count*wordsize); wrote+=sizeof(chunk))
+	for (wrote=0; wrote<(count*wordsize); wrote += cur_size)
 	{
-		int cur_size = MIN( (count*wordsize - wrote) , 1024 );
+		cur_size = MIN( (count*wordsize - wrote), sizeof(chunk) );
 		flash_bank_t *bank;
 		bank = get_flash_bank_by_addr(target, address);
 		if(bank == NULL)
@@ -798,7 +799,6 @@
 		err = flash_driver_write(bank, chunk, address - bank->base + wrote, cur_size);
 		if (err!=ERROR_OK)
 			return err;
-		wrote += cur_size;
 	}
 
 	if ((retval = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)

However, this does not resolve the corrupt download from IAR problem.

Also the erratic flash writing behaviour persists - is seems that any FLASH writing operations (flash fill* in particular) succeeds every once out of several attempts, even if reset halt is executed immediately before flash write operations. In most cases, it spits out this:

> reset halt
JTAG tap: stm32.cpu tap/device found: 0x3ba00477 (Manufacturer: 0x23b, Part: 0xba00, Version: 0x3)
JTAG Tap/device matched
JTAG tap: stm32.bs tap/device found: 0x16410041 (Manufacturer: 0x020, Part: 0x6410, Version: 0x1)
JTAG Tap/device matched
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0xfffffffe

> flash fillw 0x08000040 0x33445566 11
flash writing failed with error code: 0xfffffc7a
error writing to flash at address 0x08000000 at offset 0x00000040 (-902)

called at file "command.c", line 456
called at file "embedded:startup.tcl", line 89
called at file "embedded:startup.tcl", line 93

>_

How can I help troubleshooting this?

We saw a very similar problem on our STM32, running on one of the demo boards. Depending on the build, sometimes the flash loader would complain about a corrupted 16-bit word in flash. It was always the same offset (flash = 0x228) but the values were different each time.

It seems that it has something to do with the code that is running on the STM32 at the time the flash is updated.

I’ve installed OpenOCD to be able to a full chip erase and see if we can reproduce this problem. But the problem doesn’t appear to be with OpenOCD, since I get the same problem with IAR EWARM 5.30.1.

I also suspect the flash loader of IAR EWARM. I had a bad experience (corrupted 16-byte blocks at fixed offset) with IAR EWARM 5.30 loader, and I suspect some interrupt routine or on-chip hardware is interferencing with FLASH programming process.

Because of very random success I downgraded to IAR EWARM 5.11, which works OK, and the project has been finished succesfully.

With EWARM 5.11 and 5.20 (don’t know/remember about 5.30), full chip erase introduces its own issues - right after reset the STM32 enters fault (=handler) mode since it tries to execute instruction at 0xFFFFFFFE. This i not a problem by itself, but IAR’s boot loader does not seem to be able to recover from Fault Mode (or, probably, fails due to invalid stack location). I workaround this by flashing a smallish “do-nothing” image from a command prompt of OpenOCD, mainly to initialize interrupt vectors, then use EWARM to upload/debug etc., and this approach works steadily.