STR7: Fix to have multiple 'flash write' functionnal

I’m using openocd very often to flash my STR7 developpement board. There is still at least one bug left: you can’t flash twice: you have to kill and restart openocd before using ‘flash write’ again, otherwise openocd fails with a ‘flash program error’.

The origin of the problem is the following:

  • str7x_info->write_algorithm is allocated only if it is NULL.

  • the program is flashed once, runs, and scraps RAM. So the algorithm is lost.

  • when one wants to flash write again, since str7x_info->write_algorithm is not NULL, RAM is not written again with algorithm data, and there is no more algorithm to run.

Fix, as a context diff to run in trunk/src/flash:

[bernard@linuxbf ~]$ cat /tmp/fix

*** str7x.c 2006-10-24 10:50:02.000000000 +0200

— /tmp/str7x.c 2006-10-24 10:47:17.000000000 +0200


*** 505,512 ****

if (buffer_size <= 256)

{

/* if we already allocated the writing code, but failed to get a buffer, free the algorithm */

! if (str7x_info->write_algorithm)

! target_free_working_area(target, str7x_info->wri te_algorithm);

WARNING(“no large enough working area available, can’t d o block memory writes”);

return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;

— 505,515 ----

if (buffer_size <= 256)

{

/* if we already allocated the writing code, but failed to get a buffer, free the algorithm */

! if (str7x_info->write_algorithm)

! {

! target_free_working_area(target, str7x_info->write_alg orithm);

! str7x_info->write_algorithm=NULL;

! }

WARNING(“no large enough working area available, can’t d o block memory writes”);

return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;


*** 558,563 ****

— 561,569 ----

destroy_reg_param(&reg_params[3]);

destroy_reg_param(&reg_params[4]);

  • target_free_working_area(target, str7x_info->write_algorithm);

  • str7x_info->write_algorithm=NULL;

return ERROR_OK;

}

[bernard@linuxbf ~]$

Even after the previous patch, one may run into flashing problems.

I think that it comes from the fact that the flash write routines do not totally reset the MCU before flashing: interrupts can occur according to how they were set by a previously running program.

For instance, If an interrupt points to code in flash, because of the STR7 restrictions on flash programming (never execute code in a bank being flashed and yet another special case when the MCU performs its first flash operation) then flash write will fail.

At the moment, I found that adding “soft reset halt” before any attempt to write the flash seems to handle the situation. I think that the best solution would be, for all targets, to automatically execute ‘soft reset halt’ before flashing, to avoid problems or corrupted flash (there is no read-verify done after flashing, at least on STR7 target). And I don’t see any good reason for one to execute flash write code in ‘working area’ with a MCU having some or all of its device registers set in a unknown state.

What is your opinion Dominic?

Bernard

Hello Bernard,

sorry I didn’t reply earlier to your proposed patch.

The OpenOCD /should/ keep the interrupts disabled during algorithm execution (e.g. STR7x flash write):

    /* deassert DBGACK and INTDIS */
    buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);
    /* INTDIS only when we really resume, not during debug execution */
    if (!debug_execution)
        buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 0);

I’ve ran into a problem with interrupts with the LPC microcontrollers, which is why this code was added. I’ll see if I can reproduce your problem with the STR7x I’ve got, but I’ll have to look for some interrupt example first.

Regards,

Dominic

P.S.: I’ve created a mailing list for OpenOCD development: http://developer.berlios.de/mail/?group_id=4148

You’re welcome to join, the mailinglist makes it easier for me to keep track of development issues.

Thanks for the mailing list, I just suscribed!

I still have problems even when using "soft reset halt’. I will try to make a binary file producing interrupts because of heavy UART’s traffic to give you a test case.

Bernard

Hello Bernard,

if the problems still occur after a soft_reset_halt it’s certainly not because of the interrupts. The reset sets bits I and F, inhibiting any interrupts, so even if the STR7 didn’t honor the INTDIS bit from the debug control register, interrupts wouldn’t trigger.

I’ll try the testcase you’ve sent me, and report back with my findings.

Regards,

Dominic

For the archives (I’ve replied to Bernard’s mails directly in the meantime):

There were several unrelated problems that made the flash writing fail. These issues should be fixed in the latest SVN version.

Regards,

Dominic