Let me start off by saying this is the first time I've tried using OpenOCD. Ultimately my goal is to debug an ATSAMD21G18, and what I have available is a RedBear's DAPLink V1.0 USB Interface.
The code I am trying to load is from an Arduino sketch made for SparkFun's "SAMD21 Dev Breakout" board using their SAMD boards package. I am compiling using Arduino and then using the resulting ELF file. The linker script leaves addresses 0x0000 through 0x2000 free for the bootloader. I also verified this using
arm-none-eabi-objdump, so I mention this mostly just for context.
The problem is that, when I try to flash the application code, the bootloader gets erased. This is the output from GDB:
$ gdb myfile.ino.elf [...] (gdb) target remote :3333 [...] (gdb) monitor reset init [...] (gdb) monitor flash write_image bootloaderfile.hex wrote 6604 bytes from file SparkFun_SAMD21_Dev.hex in 1.257946s (5.127 KiB/s) (gdb) p *0x04 $1 = 1613 # Okay (gdb) load Loading section .text, size 0xf370 lma 0x2000 Loading section .data, size 0x1a8 lma 0x11370 Start address 0xbda0, load size 62744 Transfer rate: 4 KB/sec, 12548 bytes/write. (gdb) p *0x04 $1 = -1 # Not okay!
After some research I gathered that OpenOCD was using sectors of size 0x4000, and (probably) the bootloader was being erased because the entire 0x0000 - 0x3FFF sector was being erased before the application was being flashed:
(gdb) monitor flash info 0 0 : at91samd at 0x00000000, size 0x00040000, buswidth 1, chipwidth 1 # 0: 0x00000000 (0x4000 16kB) not protected # 1: 0x00004000 (0x4000 16kB) not protected [...]
I also found that the chip's flash uses 4096 pages of 64 bytes each (from table 10-2 on the datasheet). The datasheet says nothing about 16 KiB sectors, so is that just an OpenOCD construct? I would expect it to be possible to erase smaller blocks, down to the flash memory's page size, unless there's some kind of limitation on the debugging interface.
So, I guess my question is: am I right in thinking this is the problem? If so, why does OpenOCD have to erase in such big chunks of memory? And, most importantly, how can I fix or get around the problem?