cancel
Showing results for 
Search instead for 
Did you mean: 

LL code from CubeMX not clearing interrupts

Dave Jones
Associate III
Posted on July 15, 2017 at 01:31

I'm using CubeMX to generate the initial code for a custom board using an STM32L452. I've tried a couple of variations of settings, including using HAL for all the peripherals, and using a mix of HAL and LL.

When I use HAL for the EXTI pins, Cube creates an interrupt handler that includes a line in it that calls a generic EXTI GPIO handler that in turn clears the interrupt flag.

But when I have it use LL for the EXTI, it creates an empty interrupt handler with no calls to generic handlers, and no code to clear the interrupt flag.

I know asking for it to make LL code is asking for it to make a slim set of code, but leaving out anything to clear that flag seems a bit too slim. I would think that without clearing that flag, once that interrupt happens, it will happen constantly over and over again.

Shouldn't Cube have at least stuck in something simple to clear the interrupt?

1 ACCEPTED SOLUTION

Accepted Solutions
Jeanne Joly
Senior III
Posted on January 15, 2018 at 16:05

Hi , 

The point you raised was fixed in CubeMX 4.22.

The modification consists in adding include files in stm32xx_it_h.ftl : main.h is included. And if LL is used, 'stm32l4xx_ll_exti.h' is included in main.h.

Please, update your CubeMX release if not already done with this release or the last one (CubeMX4.23).

BR. Jeanne

View solution in original post

6 REPLIES 6
Amel NASRI
ST Employee
Posted on July 17, 2017 at 14:49

Hi

Jones.Dave.002

‌,

I raise your request internally for farther check to conclude either it is possible to add the clear by MX generated code or it has to be done by end user -as it is now-.

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on July 17, 2017 at 17:41

I strongly feel that the code generated by CubeMX should not just be a starting point point, but that it should be a functional starting point. It won't have all the code that the user is going to add, because that's up to the user. But I feel that the user has defined the peripherals they are using, including selecting BAUD rates, initial states of the pins, etc... and that those peripherals should not only be initialized to a working state, but any common required code that is needed (in every single situation) to make them work, should also be generated.

You created the interrupt handlers. You enabled the interrupts. For HAL functions you added the code to clear the interrupt pending bit. But for LL you did not. It's needed in every single interrupt, whether using HAL or LL code. So why not include it? It's not like there are multiple ways to clear the interrupt and you don't know which one the user will want. There aren't. There's one way to clear the pending interrupt, and it MUST be done for the interrupt to work. So LL should add that one line to make it work. Since it is LL, that line should be direct and simple. Simply clear the flag right there in the interrupt service routine that you already created, but left blank. No multiple nested subroutines, like the bloated code in HAL.

And while you are at it, there is a flaw in the interrupts (at least with the L4, but maybe with all of the STM32's) that you should also address in that code. I discovered it the hard way. Simply clearing the pending flag is not enough. The L4 caches the pending register and if you simply clear the pending bit and return, there will be another interrupt immediately following that one. You have to add a line after clearing the pending bit that then reads the pending register in order to clear that cache. Doing that then prevents the double interrupt. So Cube should also be adding that additional line of code, after clearing the pending bit.

Posted on July 17, 2017 at 22:31

It is not caching... it is a pipeline/race condition where the feedback loop (write buffers, buses, etc) takes longer to finish than the NVIC takes to determine where to tail-chain to next. I know I've banging on about it for years. It is a Cortex-M thing, related to how it pushes/pops interrupt context, passes dirty context onto the next interrupt via tail-chaining.

Agreed, the rough framing tools should do the job properly, especially all the repetitive stuff, it is the whole point of automating this in the first place, if you have keep coming back doing the same corrective work, put it in the darn tool in the first place. This comes back to my dog-fooding stance, developers within the organization need to use the tools to create real/workable examples, and the more experiences developers need to drill it into the less experienced ones to do the job properly from the outset, and save from having to hear about, and solve the same set of issues over and over. Assume the code is going to get into everything, and if you don't want your phone ring constantly with people telling you that you screwed up, get it right first time around. Test the crap out of it before it leaves your desk.

Interrupts, depending on how sticky the peripheral implementation is, can be cleared in different ways. The USART for example is self clearing if you read/write the data register to service the cause. But yes, I think there should be validation of the sources you enable, and code to clear, for example a DMA HT/TC example with both paths roughed out, and a 'your code here' designation.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 18, 2017 at 01:41

A race condition makes more sense. 'Caching' was the term used in the blog (off site) where I found the solution.

The interrupts that I generated with CubeMX, and had no code to clear them, were EXTI/GPIO interrupts. And they definitely don't clear themselves (I tested that to see).   ;~)

I agree that code created with CubeMX is going to end up in all sorts of commercial products. And you can't prevent that by simply saying 'this generates sample code but isn't meant for professional use'. As MPUs/MCUs get more and more complex it becomes nearly impossible for all programmers to know all the intricacies of the devices. So we look for shortcuts, like CubeMX, to get us started on parts we aren't familiar with. Or, over time, even on ones we are familiar with. There's never enough time.

Posted on July 18, 2017 at 09:18

I agree that code created with CubeMX is going to end up in all sorts of commercial products. And you can't prevent that by simply saying 'this generates sample code but isn't meant for professional use'

One might suspect it is just to dodge responsibility ...

I find it unfortunate to encourage unskilled beginners with hardly any insight, and often very few interest in the details.

Jeanne Joly
Senior III
Posted on January 15, 2018 at 16:05

Hi , 

The point you raised was fixed in CubeMX 4.22.

The modification consists in adding include files in stm32xx_it_h.ftl : main.h is included. And if LL is used, 'stm32l4xx_ll_exti.h' is included in main.h.

Please, update your CubeMX release if not already done with this release or the last one (CubeMX4.23).

BR. Jeanne