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

Debugging Issue: Single Step vs Brakepoint not Yielding Same Result.

I am new to ARM and nRF51822. I am using a development kit with the PCA10000 dongle and the PCA10005 daughter card. I wrote a simple C program (attached) to blink the LEDs on the dongle. I also hooked up LEDs to the same GPIO pins on the daughter card. The program works fine on the daughter card, but does not work on the dongle.

For both setups I am using emIDE and the JLink GDB Server. For the daughter card, I am using the provided J-Link lite device.

I carefully stepped through the program on each device to narrow down the difference in execution. The execution diverges in this code segment:


76 	{
0x00000194	push	{r7, lr}
0x00000196	sub	sp, #16
0x00000198	add	r7, sp, #0
0x0000019A	str	r0, [r7, #4]
77 	    uint32_t *pCnf;
79 	    pCnf = (uint32_t *) (GPIO_PINCNF + (4 * iLedPin));
0x0000019C	ldr	r3, [r7, #4]

Location 0x194 is the entry point into a subroutine. When I step on each assembly level instruction from 0x194 to 0x19c, everything is fine, and the stack pointer value at 0x19c is 0x20001c28. However, if I put a breakpoint at 0x19c, and run the program, then, when the breakpoint is triggered, the stack pointer's reported value is 0x20001c38. It seems (to me) that the subtraction instruction at 0x196 does not get executed at full speed.

What could be wrong?

Thanks for any help.

main.c

  • It seems that you don't use the official SDK. I'd strongly recommend you to do so, since it contains a lot of defines that makes your code nicer and easier to write. Especially consider using nrf51.h and nrf51_bitfields.h. There are also examples of a lot of things, that could be useful to refer to.

    I'm also having a little trouble understanding what you try to do at the start of your main function. The CLENR0 register in UICR is a flash register, and there is no need to write to it on every reset. I'd therefore recommend you to remove this snippet completely, and see if that changes anything.

    Also, beware that the upper 8 kB of flash is not on by default, and must be explicitly turned on. This doesn't seem to be the problem here, but I guess it's an issue you'll easily hit later. In the SDK code, this is done with the following assembly code in the Reset_Handler:

    
    /* Reset Handler */
    
        .equ    NRF_POWER_RAMON_ADDRESS,            0x40000524
        .equ    NRF_POWER_RAMON_RAMxON_ONMODE_Msk,  0xF  
    
        .text
        .thumb
        .thumb_func
        .align 1
        .globl    Reset_Handler
        .type    Reset_Handler, %function
    Reset_Handler:
        .fnstart
    
    /* Make sure ALL RAM banks are powered on */
        LDR     R0, =NRF_POWER_RAMON_ADDRESS
        LDR     R2, [R0]
        MOVS    R1, #NRF_POWER_RAMON_RAMxON_ONMODE_Msk
        ORRS    R2, R1
        STR     R2, [R0]
    
    

    You may also have use in looking at this GitHub repository.

    Edit: As for the difference between the boards, I don't have any immediate good explanations for that. The only thing I can think of that could be worth checking is the "Allow instruction set simulation" option in the J-Link settings (right-click the J-Link icon in the taskbar, go to settings tab). I've seen previously that this sometimes give unexpected behavior, although I can't remember having seen anything like what you describe.

    You should of course also make sure that you start from blank flash before programming on both chips, but I assume you have already done so.

  • Hey, thanks for the response. I really appreciate it. I do intend to use the official SDK, and thanks for the tips on the issues with the flash. The only point of my code was a learning exercise -- In regards to CLENR0, I was just trying to see if changing it made any difference.

    But, all this is besides the point. Why would the same code work on the PCA10005 and not the PCA10000? And what could cause a different result if I use a breakpoint vs a single step? I can use J-Commander and see that the two devices are flashed exactly the same way. If it is something that is unexplainable, that's fine, maybe I will discover the answer as I continue learning...

    Thanks Again.
    Dal

  • Sorry for overlooking that part. I edited my answer a little to expand somewhat on this, although I don't really have any great suggestions.

Related