I'm working on a project on a Silicon Labs Thunderboard React (RD0057) which has a EFR32BG1xxxF256 processor on it (Cortex M4).
Recently when I went to program the board and debug, the code immediately goes to a hard fault before entering main. (IACCVIOL and STKERR both set).
I've:
All to the same result
I then stepped through the code and saw that just after reset the code:
Tools: - Thunderboard React RD0057 - WSTK 4001A Rev A01 (Functioning as J-Link adapter) - Simplicity Studio - Bluetooth SDK 2.10.1
I need to work out a way to post my code later tonight, but does this issue sound familiar to anyone? I'm thinking it might not be code related because it's happened in known good versions of the project and in empty example projects. Any help is appreciated.
Update 1:
Pastebin of Start of Binary, excerpt first three entries:
007c 0020 4da0 0000 49a0 0000 49a0 0000
49a0 0000 49a0 0000 49a0 0000 49a0 0000
49a0 0000 49a0 0000 49a0 0000 49a0 0000
I checked the binary as suggested, and the first few entries appear to be a vector table (bunch of 0x49A0 which I believe translates to loading addresses into registers).
Then I used the J-link "J-Mem" to read out the memory of the chip. This showed all 0xFFFF's after programming the chip with the IDE (blank chip). I then used the J-Link command line utility to flash the binary file with the start address set to 0x00. Then read back the memory again, and this appears to be successful, with the contents matching the bin file. Executing this shows me getting past that first load and branch that caused the hard fault before, but now hitting another hard fault elsewhere.
If you have the gnu binutils built for arm/thumb, take this:
.thumb
.thumb_func
.global _start
_start:
.word 0x20001000
.word reset
.word hang
.word hang
.word hang
.thumb_func
reset:
nop
nop
nop
nop
nop
b reset
.thumb_func
hang: b .
build it:
arm-none-eabi-as flash.s -o flash.o
arm-none-eabi-ld -Ttext=0 flash.o -o flash.elf
arm-none-eabi-objdump -D flash.elf > flash.list
arm-none-eabi-objcopy flash.elf -O binary flash.bin
It doesn't have to be arm-none-eabi; it can be arm-linux-gnueabi or whatever arm-something-something.
Examine the list file; this is what you are looking for to boot a cortex-m.
00000000 <_start>:
0: 20001000 andcs r1, r0, r0
4: 00000015 andeq r0, r0, r5, lsl r0
8: 00000021 andeq r0, r0, r1, lsr #32
c: 00000021 andeq r0, r0, r1, lsr #32
10: 00000021 andeq r0, r0, r1, lsr #32
00000014 <reset>:
14: 46c0 nop ; (mov r8, r8)
16: 46c0 nop ; (mov r8, r8)
18: 46c0 nop ; (mov r8, r8)
1a: 46c0 nop ; (mov r8, r8)
1c: 46c0 nop ; (mov r8, r8)
1e: e7f9 b.n 14 <reset>
00000020 <hang>:
20: e7fe b.n 20 <hang>
First word in flash gets loaded into the stack pointer for you, you can change the stack pointer in your bootstrap code if you want, this just saves a step. The address for reset orred with a 1 is next, has to have the lsbit set. Reset is at 0x0014 above so the reset vector needs to have 0x0014|1 = 0x0015.
The rest of the vectors don't matter to get you booted. This one puts it in a simple infinite loop which you can halt and resume with your debugger and find it at different addresses hopefully as you repeat halt and resume.
It is probably easier to load the elf file than the bin file with a debugger, but at the same time the tool might not be writing to flash correctly. Use the tool to dump a few words starting at 0x00000000.
If your binary does not start with a vector table and/or if the vector table has even numbered addresses in it you will go off the rails immediately after reset. If it does, then you would need to dig further.