2022-03-10 03:23 PM
Here is a weird one for ya.
I am programming on the STM32L4R9I-EVAL dev board, but my project is configured
for the STM32L4S9AII6. I am clocked at 120MHz.
My program has started failing for what seems to be because I have too many
MX_<peripheral>_init() functions. Can you configure too many peripherals?
I started getting this bug off and on as I was getting my TIM15 peripheral up and
running. I now have my TIM15 working, or I should say I had it working until
now. I thought before that the TIM15 was the culprit as that was what I was
working on. So I would comment out it's init function in main() and then the
error would go away. I would mess around some more in MxCube and then the
problem would go away (for a while). This seemed to be a repeating theme as I
worked on that.
So I moved on writing a small amount of other code that had nothing to do with any
peripheral and this problem happened again. Only this time, I don't dare mess
with MxCube because before this everything was working perfectly. What is funny
now though is that I notice that the problem goes away when I comment out
MX_TIM15_Init() as before, but now I thought to try commenting out other
peripheral init functions as well. Low and behold, it doesn't matter what init
function I choose to comment out. If I comment out any one of them, this error
goes away.
Enough of the back story, here is the error that I am referring to:
After attempting to run HAL_Init() at the very beginning of the program (and before
any peripheral init function has a chance to be called), the program tries to
run code outside the allocated memory space as shown here:
This is super weird to me because (again) the error occurs before any peripheral init function has a chance to run. So how in the world does commenting out code that never has a chance to execute cause this error to go away? Again, do I have to many peripheral init functions? Again, it does NOT matter which function I choose to comment out, the problem will go away if I comment out ANY one of them.
Here are the init functions as they currently exist in my program:
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_DAC1_Init();
MX_I2C1_Init();
MX_I2C2_Init();
MX_IWDG_Init();
MX_OCTOSPI1_Init();
MX_OCTOSPI2_Init();
MX_SPI1_Init();
MX_SPI2_Init();
MX_SPI3_Init();
MX_TIM15_Init();
MX_USART1_UART_Init();
I'm sorry but this is just weird. Any hints would be greatly appreciated. Thanks!
Solved! Go to Solution.
2022-03-15 01:09 PM
I think I figured it out and I have it working again. However, this is the 3rd time I have fixed this issue (or issues with the same behavior). The first two times the behavior came back with a vengeance shortly afterwards, so hopefully it sticks this time.
Before I get to my fix, let me make a note of lessons learned. TDK was right when he said, "The MCU does not behave erratically given the same input.". I confused myself on exactly when it was failing based on whether I was troubleshooting in debug mode or in real time. It looked like it was making it slightly further when run in debug mode, but that wasn't actually the case.
The program consistently failed right at the end of the HAL_TIM_Base_Start_IT(&htim2) function call right at the beginning of the program within the HAL_Init() function. Note that htim2 is the timer I am now using for the FreeRTOS timebase as I have tried many others. I don't think it matters what timer is used as the timebase as htim2 was giving me the same grief as all the others I tried.
What "seemed" to fix this issue is I tried unchecking the radio box to use the internal clock as the source for the other one-shot timer that I have been fighting (TIM15). I assumed that every timer needs some sort of timer to sync with and since this was the only option I assumed it needed to be checked. I guess I'm wrong. I unchecked it and not only did everything start working again, but the TIM15 was still operating as a slave to the 120MHz main internal system clock. I know this because my ARR period settings were still set up for 120MHz source and the timing at the output of TIM15 still worked the same.
So let me ask, what does checking this box do if the timer is going to sync to the internal clock regardless?
Checking this box seems to do nothing but break the timer set up as the timebase for FreeRTOS.
2022-03-10 03:57 PM
No, you can't have too many init functions in any practical sense.
Look at VECTACTIVE and see if it's in an interrupt. Ensure SCB->VTOR is set correctly.
Step through the code and see where exactly it jumps to 0x1FFFxxxx. Probably corresponds with an interrupt enable.
2022-03-10 04:43 PM
This is most likely the infamous AN2606-pattern6-PEMPTY problem.
http://efton.sk/STM32/gotcha/g44.html
https://community.st.com/s/article/Empty-check-mechanism-on-SMT32
There's also a related thread here roughly once in a month for the last year or two, try to search if you are interested.
Impact of adding/removing functions is coincidental, I don't even try to speculate how.
JW
2022-03-14 03:17 PM
The program doesn't shoot out of program memory from the same point every time, but it always seems to happen somewhere within HAL_Init() and always seems to be very soon after the TIM3 (FreeRTOS kernel tick) interrupt is enabled. This only happens when I have a 2nd timer configured within MxCube.
I have a hard time believing it is a bootloader issue because it always seems to at least make it to HAL_Init().
I agree that this seems to be related to interrupt configuration, but I am having a difficult time figuring out exactly what. How do I "Look at VECTACTIVE and see if it's in an interrupt."?
I tried removing TIM15 (or whatever other TIMx I try) and corresponding enabled interrupt from MxCube and the problem goes away. Is there a conflict between TIM3 & other TIMx Interrupts?
Also, I am very convinced this is a problem with MxCube because the only way I am ever able to get another timer set up and working as expected is if I manually add the following line at the end of that timers Init function.
htim15.Instance->DIER |= TIM_DIER_UIE; // Update interrupt enable
Twice now after much fighting and un/re-configuring whatever other timer within MxCube, I eventually (by some anomaly) get the problem to go away without having to sacrifice the other timer configuration . Seeming that the problem has been resolved, I continue on to work on other non-related code. After a few tests though, the problem comes back and I have to spend several more hours fighting it.
It seems to me that the interrupts are being set up consistently within the HAL generated code. Other than changing what timers are used for the FreeRTOS scheduler (TIM3) and my needed one shot timer (TIM15), I am out of ideas.
More on how my TIM15 was set up is described in my post from last week. At the time, I thought this was resolved.
2022-03-14 04:32 PM
Why your FreeRTOS timer is TIM3 instead of systick?
It should be the other way, al least in the ST-maintained version.
Make TIM3 the HAL timer, leave systick to FreeRTOS. You can even make the HAL timer tickless (free running without interrupts) and rewrite HAL_GetTick etc,
2022-03-14 04:39 PM
The IPSR register contains the VECTACTIVE field which can be viewed in the register viewer. This field gives the current interrupt.
https://interrupt.memfault.com/blog/arm-cortex-m-exceptions-and-nvic
The MCU does not behave erratically given the same input. I would suggest freezing the code and making deliberate changes to chase down the issue.
Very likely it is a CubeMX generation issue. Perhaps TIM3 isn't initialized correctly as systick if TIM15 is used as well. Possibly conflicting TIM_MspInit definitions within the code generator so it skips one of them.
2022-03-14 04:43 PM
MxCube selected TIM3 by default and since the max frequency the FreeRTOS kernel tick can be configured as is 1ms, I haven't seen a reason to change it. I'll give it a try, but I have heard from other sources that doing this is a bad idea because it restricts what freeRTOS functions can be called and caused other issues. Again, I'll give it a try and let you know how it goes.
2022-03-14 04:46 PM
On second thought, I'm not even going to try it.
2022-03-15 12:49 PM
The IPSR Register? VECTACTIVE? I understand this in reference to the website you shared, but I have not been able to find such registers documented in the datasheet, reference guide, or a matching label reference within the register watch window. However, observing all NVIC register changes in the register watch window I am able to detect the issue. I was not aware of that feature, so thank you very much for that.
2022-03-15 01:09 PM
I think I figured it out and I have it working again. However, this is the 3rd time I have fixed this issue (or issues with the same behavior). The first two times the behavior came back with a vengeance shortly afterwards, so hopefully it sticks this time.
Before I get to my fix, let me make a note of lessons learned. TDK was right when he said, "The MCU does not behave erratically given the same input.". I confused myself on exactly when it was failing based on whether I was troubleshooting in debug mode or in real time. It looked like it was making it slightly further when run in debug mode, but that wasn't actually the case.
The program consistently failed right at the end of the HAL_TIM_Base_Start_IT(&htim2) function call right at the beginning of the program within the HAL_Init() function. Note that htim2 is the timer I am now using for the FreeRTOS timebase as I have tried many others. I don't think it matters what timer is used as the timebase as htim2 was giving me the same grief as all the others I tried.
What "seemed" to fix this issue is I tried unchecking the radio box to use the internal clock as the source for the other one-shot timer that I have been fighting (TIM15). I assumed that every timer needs some sort of timer to sync with and since this was the only option I assumed it needed to be checked. I guess I'm wrong. I unchecked it and not only did everything start working again, but the TIM15 was still operating as a slave to the 120MHz main internal system clock. I know this because my ARR period settings were still set up for 120MHz source and the timing at the output of TIM15 still worked the same.
So let me ask, what does checking this box do if the timer is going to sync to the internal clock regardless?
Checking this box seems to do nothing but break the timer set up as the timebase for FreeRTOS.