cancel
Showing results for 
Search instead for 
Did you mean: 

[STM32F07x] Unexpected software reset when BOOT0 pin is connected to Vdd

KlaasHoekstra
Associate II

Hello,

I am currently working on a custom PCB which has an STM32F072 chip on it.

We want to be able to program it using ST's internal bootloader, so we placed a 10k pull-up resistor to the BOOT0 pin.

I generated a basic program using CubeMX to test the PCB.

When I start debugging the application, a breakpoint is triggered at the start of the main application, as expected.

However, as soon as I continue debugging, a reset is triggered and the chip switches to its internal booloader, since the BOOT0 pin is high. This reset is seen on the NRST pin using a scope, and the PINRSTF and SFTRSTF bits are set in the RCC->CSR register.

I also tried sending a go command in the bootloader, thus without the debugger connected, but here I see the same reset happening.

When I step through the code, the reset does not happen and the program just loops its main loop. But the SysTick_Handler is never triggered.

The reset circuit has a 10k pull-up resistor and a 100nF capacitance, and is only connected to the debug header.

The weird thing is, when I remove the pull-up resistor from the BOOT0 pin and place a pull-down resistor instead. The firmware is working exactly as expected, the SysTick_Handler is triggered, and not a single reset is seen on the NRST pin. So nothing is changed in the reset circuit, only the level of the BOOT0 pin is changed.

I generated code using CubeMX 4.27 and CubeMX 5.4, but both give the same result.

Debugging is done with an ST-Link.

Can somebody tell me what is causing this reset and how can I prevent it from happening?

Thank you in advance!

1 ACCEPTED SOLUTION

Accepted Solutions
KlaasHoekstra
Associate II

Thank you for the answers.

In my previous PCB design, I used a STM32L031F4.

Here we also fixed the BOOT0 pin to boot to the bootloader, and started the application using a GO command.

Hence the reason we designed this the same way.

The difference is that the STM32L031F4 is a Cortex M0+, whilst the STM32F072 is a Cortex M0.

The Cortex M0+ has a vector table offset register (VTOR), which makes it possible to use the vector table of the application code, even though the BOOT0 pin is connected such that the bootloader vector table is mapped to address 0x0000.

The Cortex M0 does not have a VTOR, which means that after a GO command to jump from the bootloader to the application code, the vector table of the bootloader is still mapped to 0x0000 and thus when an interrupt is triggered, code execution will jump to the bootloader again.

That's why it worked on the previous design, but not here.

I will have to do a change in the PCB to make it work, thank you for pointing me in the right direction!

View solution in original post

6 REPLIES 6

Software issue?

What happens if main contains only an empty loop?

JW

PS. Please change your username to a normal nick.

KlaasHoekstra
Associate II

I just tried with the following main:

int main (void)
{
    while (1)
    {
 
    }
}

Now I do not see the reset happening.

Could it be an init function that is generated by CubeMX?

KlaasHoekstra
Associate II

So I have been trying some more things.

I changed the CubeMX configuration to generate the LL version of the RCC instead of the HAL version.

When I do this, the reset is not triggered, but I noticed the Systick_Handler is also not triggered.

So I added a call to LL_SYSTICK_EnableIT().

But because of this, the reset is triggered again, when the BOOT0 pin is high.

So my guess is that somehow the reset happens when the SysTick interrupt request is called.

I still don't have any clue on how to fix this...

Edit:

I think the issue is the same as here: https://community.st.com/s/question/0D50X00009hmikeSAA/stm32f070cbt6-systickhandler-never-called

But they fixed it by setting BOOT0 to GND instead of Vdd.

Is it not possible then to have a SysTick Handler when BOOT0 is connected to Vdd?

Stecklo
Senior

@KlaasHoekstra​ , you actually need to pull BOOT0 down to run application code. If you need access to the bootloader you should have a switch on your board to shortcut BOOT0 to VDD

Stecklo
Senior

There are also option bytes nSWBOOT0 and nBOOT0 that can be used instead of BOOT0 pin. They can be accessed via debug probe, but it is some overengineering in case you want to use obly the internal bootloader and no debug probe. Be careful playing with those bytes via bootloader, as writing nBOOT0=1 and nSWBOOT0=0 makes device boot from app code whatever the BOOT0 pin state is

KlaasHoekstra
Associate II

Thank you for the answers.

In my previous PCB design, I used a STM32L031F4.

Here we also fixed the BOOT0 pin to boot to the bootloader, and started the application using a GO command.

Hence the reason we designed this the same way.

The difference is that the STM32L031F4 is a Cortex M0+, whilst the STM32F072 is a Cortex M0.

The Cortex M0+ has a vector table offset register (VTOR), which makes it possible to use the vector table of the application code, even though the BOOT0 pin is connected such that the bootloader vector table is mapped to address 0x0000.

The Cortex M0 does not have a VTOR, which means that after a GO command to jump from the bootloader to the application code, the vector table of the bootloader is still mapped to 0x0000 and thus when an interrupt is triggered, code execution will jump to the bootloader again.

That's why it worked on the previous design, but not here.

I will have to do a change in the PCB to make it work, thank you for pointing me in the right direction!