Getting around an openocd bug

I’ve been back working with the SAMD20 microcontroller family again for an RS485 network project. While writing code for the device I noticed that it would crash quite often. Further investigations revealed that sections of the code were not being written to flash memory. This device has a 64 byte flash page size and it will only accept writes of 64 byte blocks. If you try to write a smaller amount the write is ignored. This causes a problem when you want to write a flash image that is not an integer multiple of 64 bytes in size – the last few bytes will not be written out. The version of openocd I’m using came from here https://sourceforge.net/p/openocd/code/ci/master/tree/ . I reported the issue but while I’m waiting for a response I’ve managed to workaround the problem by adding some padding to the flash image in the linker file as shown here.

MEMORY
{
    flash : org = 0x00000000, len = 128k
    ram : org = 0x20000000, len = 16k
}
  
SECTIONS
{
        
	. = ORIGIN(flash);
        .text : {
		  *(.vectors); /* The interrupt vectors */
		  *(.text);		  
		  *(.rodata);		  

        } >flash
	. = ORIGIN(ram);
        .data : {
	  INIT_DATA_VALUES = LOADADDR(.data);
	  INIT_DATA_START = .;
	    *(.data);
	  INIT_DATA_END = .;
	  . = ALIGN(4);
        } >ram AT>flash
     
	BSS_START = .;
	.bss : {	  
	    *(.bss);
	    . = ALIGN(4);
	} > ram
	BSS_END = .;
	
	.padding : {
		  /* This is a 64 byte block of 0xff's to ensure that the last */
		  /* page of the program is written to the MCU */
		  /* The openocd SAMD driver does not seem to flush the last partial */
		  /* page out properly */

          LONG(0xffffffff);LONG(0xffffffff);LONG(0xffffffff);LONG(0xffffffff);
		  LONG(0xffffffff);LONG(0xffffffff);LONG(0xffffffff);LONG(0xffffffff);
		  LONG(0xffffffff);LONG(0xffffffff);LONG(0xffffffff);LONG(0xffffffff);
		  LONG(0xffffffff);LONG(0xffffffff);LONG(0xffffffff);LONG(0xffffffff);
	} >flash
}


This linker script is for the SAMD20E17 MCU. The value chose for the padding data is important as the erased state of flash is logic ‘1’. By using 0xffffffff as a padding value (which may or may not be written to the flash) read-back verification will report a success.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s