cancel
Showing results for 
Search instead for 
Did you mean: 

[Bug found] Interference occurs in the processing of similar hardware, when operated with interruption, due to the sharing of HAL subroutines.

Not applicable

When similar hardware, such as USB, or SPI, or I2C etc. is operating on the main routine, and other hardware is operated with an interrupt, the main routine's hardware suffers errors. Although the hardware has independent registers, sharing subroutines with similar hardware blocks the simultaneous use of similar hardware.

With hundreds of mega hertz processing and a good amount of memory, an STM32 needs at least one core library that operates with each hardware independently, without sharing subroutines.

17 REPLIES 17
berendi
Principal

Do you have any specific code examples?

RMcCa
Senior II

First thing is to do figure out what's​ wrong with your code. Vaguely blaming STM on a public forum isn't necessarily going to help very much. Microcontroller makers assume you can read & understand data sheets and that you have enough programming and technical knowledge to get it do what you want. STM32s are made to be extremely versatile and are thus fairly complicated.

JoniS
Senior

Can we get minimal code to reproduce the issue?

And can you be little bit more specific about the "​main routine's hardware suffers errors" part.

Not applicable

I saw that there are queues for RTOS and, following the same principle, I was testing the use of waiting variables, to wait for the use of the shared subroutine. And it works.

Before performing the operation with the hardware, it is checked if it is busy, then it waits to be free. As if the hardware itself was being used.

I believe that this occurs with the use of external communication, I experienced these problems with USB Host, I2C Master etc. So it may be necessary to use external devices to reproduce this problem.

For example, if a DS3231 (I2C addr 0xD0) is operated on port I2C1 and an MPU6050 (I2C addr 0xD0) on port I2C2.

The I2C2 port is accessed in the main subroutine (runs independent of interruption). And in an interruption performed by a timer, access is made to the I2C1 port.

When timer interrupt occurs, data from port I2C1 is always obtained correctly. But communication with the I2C2 port fails, the data obtained is not correct.

Similar to what happens with I2C, when trying to use timer interrupt to control access on the USB Host port. If, for example, the HS port is being accessed in the main () routine and the FS port is being accessed via interruption, then an error occurs in the data of one of the ports.

But if the subroutines for each hardware are cloned, and each hardware operates with independent core subroutines, this problem will stop.

For example, I2C1 and I2C2 do not use the same basic HAL subroutines.

The HAL driver subroutines are the core of any project made with the STM32CubeIDE, and if they are shared with hardware this always happens.

I understand that sharing routines can be interesting to avoid the consumption of memory resources, but this ends up being a secondary concern when working with higher capacity ARM.

I see that the features of the STM32F4 and STM32F7 line are very interesting, but if it is not possible to use each hardware independently, then having a lot of FLASH or RAM is unnecessary.

S.Ma
Principal

Well, I can't comment on RTOS nor dual core. I try to have functions which their data universe is mostly passed from struct pointer (the context) and not use any global variables. Normally, the function should only use stack for local variables (if the stack is deep enough, Cube default setting is too low, maybe this could be one possible reason for the strange behaviour).

I do use same functions for various peripherals this way, and actually, don't need (with IAR) to use volatile for global structure: Some globals will be written by ISR and cleared by main loop, or writeable only on one side. Such would be SW FIFO.

What's also important is interrupt priority and interrupt maximum allowed lag and duration: This is one tricky part for embedded or the SW will fail after some time.

When compiler generate code, it might already factorize code without tell you within a C file scope...

So there is a reentrancy issue in your code. Perhaps if you could post some actual code, it might be possible to pinpoint the exact problem, and help you fixing it.

Most subroutine should be coded in a thread-safe manner, so typically avoiding internal static variables, and use of global variables.

A lot of developers seem to like to use global variables, when structures, and objects would be far more appropriate.

Hardware peripherals frequently won't support concurrent operation, you should mutex things with complex operation and FIFOs to protect against multiple usage, say SDIO/SDMMC with FatFS, at some level you need to enforce ownership of resources to prevent multiple threads stepping on each other.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

>don't need (with IAR) to use volatile for global structure

No compiler needs volatile if the optimization settings (or capabilities) are sufficiently low, all variables are effectively treated as volatile, resulting in safe but inefficient code.

>When compiler generate code, it might already factorize code without tell you within a C file scope...

Or even across C files. There is a reason why STM32CubeIDE has removed the -lto option from the compiler settings, it would expose loads of bugs in legacy code, including their precious HAL library.

The question is about using distinct peripherals concurrently, e.g. I2C1 in an interrupt handler, and I2C2 in the main thread.

Are there known cases of such "crosstalk" between communication peripherals? (except those caused by software bugs)