cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L Problem in booting without debugger

patroklos
Associate II
Posted on July 15, 2015 at 14:02

I have a STM32L151UC, I am compiling a project getting a Hex and and Elf file, I flash the Hex file using ST-Link Utility and St-Link/V2 and I can start it on debug mode over openocd and gdb, being able to print with semihosting, step over/into/etc.

When I remove the debugger and power cycle the board, I would expect that the program would start, but I think it does not reach the main().

NRST is pulled high with a resistor and I can touch it to low, the program is flashed on 0x0800 0000 and the part starting from 0x0 seems to be a copy of 0x0800 0000.

I think the reset vector is properly linked and leads to the startup sequence, the bss inits and eventually main(). The linker includes stabs debugging sections, I don't know if that is a problem..

Am I missing some step?

4 REPLIES 4
Posted on July 15, 2015 at 14:28

The STM32 maps/shadows different memories (RAM, ROM, FLASH) at address zero based on the state of the BOOTx pins at reset. The memories continue to exists at their normal addresses so control immediately transfers there.

Make sure you are enabling all the clocks you need, as the debugger may enable the ones it needs, and is no longer there to do that.

Check your code in SystemInit(), that it runs. That it sets the Vector Table (SCB->VTOR) to the true base of your code. You can double check that in the .MAP file.

Use GPIO pins, LEDs or USARTs, to determine how deep into you code you've gotten, and where it might be stuck. Add a real Hard Fault Handler, and look for other places where you might be spinning in tight loops waiting for something, that apparently isn't happening.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
patroklos
Associate II
Posted on July 15, 2015 at 15:53

1. STM32L15*UC is a cat3 device (Ref.Man. p40) so as I keep BOOT* pins to LOW the 0x0 address should be a shadow of the Main Flash Memory (Ref.Man ch2.7) which is address 0x0800 0000 (datasheet ch5). This looks ok.

2. Good point, I will enable all clocks for debugging

3. I do not know how to make sure that SystemInit() is reached. On the MAP file, I see:

.isr_vector     0x08000000      0x378

                0x08000000                . = ALIGN (0x4)

 *(.isr_vector)

 .isr_vector    0x08000000      0x10c ./arch/stm32/cmsis/src/vectors_stm32l1xx.o

                0x08000000                g_pfnVectors

 *(.cfmconfig)

 *(.after_vectors .after_vectors.*)

 .after_vectors

                0x0800010c      0x114 ./arch/stm32/newlib/_startup.o

                0x0800010c                _start

 .after_vectors

                0x08000220       0x28 ./arch/stm32/cmsis/src/vectors_stm32l1xx.o

          ...all irq handlers on same address space ...

 .after_vectors

                0x08000248      0x130 ./arch/stm32/User/exception_handlers.o

                0x08000248                Reset_Handler

                0x08000268                HardFault_Handler_C

                0x080002e0                BusFault_Handler_C

                0x08000328                UsageFault_Handler_C

                0x08000378                . = ALIGN (0x4)

And I know that _start and ResetHandler call _hardware_initialize() which in turn calls SystemInit(). SystemInit() sets

  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */     which is the address 0x0800 0000

4. GPIOs, LEDs and USARTs would work only after we reach main normally, right? Or perhaps I could connect with the debugger to running target and see where it is trapped.
Posted on July 15, 2015 at 17:04

3) The vector at 0x08000004 should contain 0x08000249

4) They work as soon as you program the registers, I do this in the Reset_Handler when I need too.

At the very minimum you need to confirm you get to main(), if you don't you need to look at what's going on in the Reset_Handler(), and SystemInit(), and the things called from there. In Keil the statics are not fully initialized when it calls SystemInit(), so be careful about your expectations there, and in functions call from there.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
patroklos
Associate II
Posted on July 15, 2015 at 17:37

I see. Yes the address 0x08000004 contains 0x08000249.

I wrote a small codeblock that enables all clocks and toggles a gpio:

 

RCC->AHBENR = 0x4B0090FF;

    RCC->APB2ENR = 0x5A1D;

    RCC->APB1ENR = 0xB0FECA3F;

    GPIOB->MODER = 0x100280;

    GPIOB->OSPEEDR = 0xC0;

    GPIOB->PUPDR = 0x200100;

    GPIOB->OTYPER = 0;

    while(1){

        GPIO_SetBits(GPIOB, ((uint16_t)0x0400));

        GPIO_ResetBits(GPIOB, ((uint16_t)0x0400));

    }

It runs fine even on ResetHandler. It runs as long as the chip is programmed even without hitting run. Runs even with debugger disconnected and powercycling. Although does not run if the debugger is connected but the USB cable is unplugged (not important anyway)

I think I can take it from here and find where the code hangs. Thank you for the guide. This approach is a simple and nice future reference for anyone who may encounter similar problems. 🙂

PS> Regarding the KEIL comment, the above was done in Eclipse with ''GNU Tools for ARM Embedded Processors Toolchain'' & the eclipse plug-ins