cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F303VCT - Code hangs on sysTick IRQ enable

jlag
Associate III

STM32F303VCT

STM32CubeIDE 1.14.1

Simple program generation with IDE, main() while loop user code that toggles a GPIO.

System hangs during HAL_Init() for the sysTick vector in: 

void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));

/* Enable interrupt */
NVIC_EnableIRQ(IRQn);
}

Break the debugger and we are at an invalid address: 0x1FFFEf06.

I am assuming there is something wrong with either the vector table location and/or the NVIC configuration, but the vector table at 0x08000000 and code/flash are identical to the code that runs on Discovery board.

Both are using SWD. Discovery board is loaded/debugged via ST_LINK USB, custom board is loaded/debugged via STLINK-V3MINIE, USB to SWD.

I have been through many threads regarding user vector table locations, offsets, etc but none have seemed to help. All looks good.

Is there something that the ST-LINK on the Discovery board is doing during load/boot that the V3MINI isn't that could be affecting interrupt configuration?

 

 

16 REPLIES 16

(Didn't fully read your reply before which explains that VTOR shouldn't need changed. Apologies.)

Hmm, maybe your understanding is a little better than mine. It would be good to get to the bottom of it since it really is a recurring theme and trips up new users before they even have a chance at understanding what's going on.

Still seems like VTOR isn't pointing to the right place. Maybe the debugger "helpfully" does something non-standard that trips things up. User is debugging, so it's definitely not a fresh start from reset.

If you feel a post has answered your question, please click "Accept as Solution".

> Hmm, maybe your understanding is a little better than mine. 

Obviously not, otherwise I wouldn't be asking.

Problem is, I never came across such a problem, so don't have any first-hand experience/insight. But of course it may happen to me in the future, too, and I would like to be prepared to that occasion. That's why I'm pestering here.

> Maybe the debugger "helpfully" does something non-standard that trips things up.

Yes, that sounds much like a factor.

> Still seems like VTOR isn't pointing to the right place.

Yes, so I'd add to my request above, in the failed state, to read out also VTOR.

JW

Here's the solution.

So it was the classic case of BOOT0 being not even floating but held actively high, inadvertently;  and, as @TDK said above, most likely the debugger/IDE added to the confusion to run the application (i.e. what's in FLASH at 0x0800'0000) forcibly(**), regardless of state of the address 0 remap. That resulted in the application failing at the first interrupt, where it picks the interrupt vector from bootloader's table at 0, and in turn gets lost in bootloader's code (in fact, there's no "guarantee" for instant failure - newer bootloaders are Cube-based so they do have e.g. systick interrupt implemented, except that it increments "some" address in memory instead of application's 1ms counter). And then changing VTOR effectively masks this case indeed. As long as the debugger provides that "merciful" startup.

So the real test for this situation would be, try without debugger. Here, that test was successful in that it lead to recognizing the real root of the problem (*).

But most of the cases I've seen is related to the "empty FLASH" mechanism (AN2606 Pattern 6 and similar), which is resolved by a power cycle. Most users would not remove the debugger live, so they would introduce the power cycle without realizing it, thus the problem "goes away" and they wave the whole incident as a fluke.

(*) This case is also a prime example of why the "source code" (here, schematics) should never be trusted, because there's a long path between the source and real life, and many things can go wrong at that path. That's why it's not enough to look at the schematics and at the source code, but it is necessary to measure directly at the pin (plus make sure the pin is properly soldered, yes, even with professional board makers - especially with prototypes, it is always a new set of circumstances and things can go wrong in subtle ways at that stage, too) and it is necessary to read out and check the registers content.

What I personally learned here is, always instruct the OP to measure directly at the pin. In most cases they will ignore it just like they ignore my adage to read out the registers, but maybe there's a fraction of them who will.

JW

Well that explains why I was unable to replicate this.

I did learn something:

On the STM32H723, the reset value for SCB->VTOR is 0x08000000. Directly after reset, that is what it's set to. I can't find any documentation which states this. Cortex M7 documentation doesn't specify this value, presumably it's up to the implementation. Might give some justification for ST's decision to not set the value on startup. (It's still a bad decision, regardless.)

On the STM32F4xx, whatever chip I was using, the reset value for SCB->VTOR is 0

If you feel a post has answered your question, please click "Accept as Solution".

I was working for a week on this one. This post solved the issue for me.

I actually got down to starting a new project with only 4 output pins. It would still only go so far before it hung. I felt it was an interrupt, but only had the defaults, none of my own. Certainly ST Code should work out of the box, shouldn't it?

It looks like the answer is no. I took your advice here and uncommented #define USER_VECT_TAB_ADDRESS in system_stm32l4xx.c and my program is not stopping anymore.

Kudos to you. Yet another time you helped me out.

Hi @kmoravec ,

Actually, the corollary of this thread is, that BOOT0 pin needs to be grounded.

Can you please check, by measuring directly on BOOT0 pin, that it is grounded?

Can you please try to run your program without debugger?

Can you please check that you haven't set bootloader entry through the Option bytes?

In 'L4, there's an additional issue, in that after initial programming, there needs to be a power cycle, because of the "empty" mechanism to enter the bootloader.

JW

What @waclawek.jan said :)