This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

S120 Hard Fault in softdevice_handler_init - IAR

I'm trying to bring up a basic S120 application on PCA10001 based on the multilink central example, using the IAR toolchain.

I've programmed the S120 device using 1.0.0_3 using the batch file. I've used a custom linker file for embedded workbench using the IAR S110 HRS project as a template, but adjusting the values for Flash & RAM start addresses to 0x0018000 and 0x20002800 as per the S120 SD specification. (not forgetting to move the vector table to 0x18000 too)

However when I call ble_stack_init() I get a hard fault in the SVC call made from sd_softdevice_enable.

Stepping a little further into the SVC call, the execution correctly vectors to 0x6b0 (the SVC vector) then examines the link register to determine which stack to access the caller preserved registers and then gets the SVC code in the usual way, this is then tested (at 0x6c8) to see if it is 0x18 which it isn't, so execution branches to 0x6d0. At this point R2 is loaded with a the start address of the RAM 0x20000000 and then R2 is loaded with the contents of 0x20000000. It is this indirect load at 0x6d2 that causes the vector to the hard fault handler.

When this is executed, the contents of 0x20000000 is 0xA801BE00 which is in a reserved area of the address space (AKA garbage).

It appears that this area of RAM is not being initialised at reset. If I overwrite this data with the debugger then reset and run again, at the point where the SVC instruction is invoked again then the pattern I wrote the RAM is still there, suggesting that whatever initialisation of the RAM should be happening by the soft device isn't occuring.

However, if I manually set the PC to the reset vector address, I see that the data is initialised when execution resumes.

Given that others are using S120 with other toolchains OK, and the behaviour I've described, I'm fairly convinced it's related to the tools. I've tried the in-built jlink debug interface and the GDB debug interface but the behaviour is the same.

Any ideas ?

        
        0x6b0: 0x480d         LDR.N     R0, [PC, #0x34]         ; [0x6e8] 0xfffffffd (-3)
        0x6b2: 0x4570         CMP       R0, LR
        0x6b4: 0xd102         BNE.N     0x6bc
        0x6b6: 0xf3ef 0x8109  MRS       R1, PSP
        0x6ba: 0xe001         B.N       0x6c0
        0x6bc: 0xf3ef 0x8108  MRS       R1, MSP
        0x6c0: 0x6988         LDR       R0, [R1, #0x18]
        0x6c2: 0x3802         SUBS      R0, #2
        0x6c4: 0x7800         LDRB      R0, [R0]
        0x6c6: 0x2818         CMP       R0, #24                 ; 0x18
        0x6c8: 0xd102         BNE.N     0x6d0
        0x6ca: 0x46c0         MOV       R8, R8
        0x6cc: 0x4a07         LDR.N     R2, [PC, #0x1c]         ; [0x6ec] 0x3d7 (983)
        0x6ce: 0x4710         BX        R2
        0x6d0: 0x4a07         LDR.N     R2, [PC, #0x1c]         ; [0x6f0] 0x20000000 (536870912)
        0x6d2: 0x6812         LDR       R2, [R2]
        0x6d4: 0x322c         ADDS      R2, R2, #44             ; 0x2c
        0x6d6: 0x6812         LDR       R2, [R2]
        0x6d8: 0x4710         BX        R2
        0x6da: 0x0000         MOVS      R0, R0
        0x6dc: 0xb500         PUSH      {LR}
        0x6de: 0x4b05         LDR.N     R3, [PC, #0x14]         ; [0x6f4] 0x1000 (4096)
        0x6e0: 0x4a05         LDR.N     R2, [PC, #0x14]         ; [0x6f8] 0x4 (4)
        0x6e2: 0x589b         LDR       R3, [R3, R2]
        0x6e4: 0x4798         BLX       R3
        0x6e6: 0xbd00         POP       {PC}
        0x6e8: 0xfffd 0xffff  MRC2      p15, #7, PC, C13, C15, #7
  • OK - so replying to my own question, in the hope that this is useful to someone else....

    The problem does seem to be related to the CSpy debugger. Having turned on jlink debugging, I can see that the IDE resets the processor, halts it, then amongst other things it reads the initial stack pointer address and reset vector and sets these manually in the appropriate registers. Because it only knows about the modified application vector table, it just sets up the application start address and thus completely skips the soft device startup code.

    This also explains why I saw failures the first time I ran my peripheral application using the SD110, though that worked after a reset.

    I guess I need to get my head around CSPY macros now to fix this.

    T55B0 000:695 JLINK_Reset() -- CPU_ReadMem(4 bytes @ 0x200005BC) -- CPU_WriteMem(4 bytes @ 0x200005BC) -- CPU_WriteMem(4 bytes @ 0xE000EDF0) -- CPU_WriteMem(4 bytes @ 0xE000EDFC) >0x35 TIF> -- CPU_WriteMem(4 bytes @ 0xE000ED0C) -- CPU_ReadMem(4 bytes @ 0xE000EDF0) -- CPU_ReadMem(4 bytes @ 0xE000EDF0) -- CPU_WriteMem(4 bytes @ 0xE000EDF0) -- CPU_WriteMem(4 bytes @ 0xE000EDFC) -- CPU is running -- CPU_ReadMem(4 bytes @ 0xE000EDF0) -- CPU_WriteMem(4 bytes @ 0xE0002000) (0020ms, 0448ms total)
    T55B0 000:715 JLINK_IsHalted()  returns TRUE (0000ms, 0448ms total)
    T55B0 000:715 JLINK_ReadMemU32(0x00018000, 0x0001 Items, ...) -- Read from flash cache (4 bytes @ 0x00018000) -- Data:  F0 38 00 20  returns 0x01 (0000ms, 0448ms total)
    T55B0 000:715 JLINK_ReadMemU32(0x00018004, 0x0001 Items, ...) -- Read from flash cache (4 bytes @ 0x00018004) -- Data:  85 AD 01 00  returns 0x01 (0000ms, 0448ms total)
    T55B0 000:715 JLINK_ReadRegs(NumRegs = 1, Indexes: 15) -- R15 (PC)=0x630  returns 0x00 (0000ms, 0448ms total)
    T55B0 000:715 JLINK_WriteReg(R15 (PC), 0x0001AD84)  returns 0x00 (0000ms, 0448ms total)
    T55B0 000:715 JLINK_ReadRegs(NumRegs = 1, Indexes: 17) -- MSP=0x708  returns 0x00 (0000ms, 0448ms total)
    T55B0 000:715 JLINK_ReadRegs(NumRegs = 1, Indexes: 18) -- PSP=0xFFFFFFFC  returns 0x00 (0000ms, 0448ms total)
    T55B0 000:715 JLINK_ReadRegs(NumRegs = 1, Indexes: 20) -- CFBP=0x00  returns 0x00 (0000ms, 0448ms total)
    T55B0 000:715 JLINK_WriteReg(MSP, 0x200038F0)  returns 0x00 (0000ms, 0448ms total)
    
Related