‎2020-02-04 10:53 PM
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.
‎2020-02-05 09:09 AM
Reentry? Yes, in a way it is a re-entry, but not on the same hardware (I2C1 != I2C2), but rather a re-entry into the HAL routine, because they are shared, this is the starting point of the post.
‎2020-02-05 09:13 AM
As mentioned above, when using the queue, it is possible to avoid using the same HAL sub-routine before it is finished. This is the code I'm testing:
HAL_StatusTypeDef MPU6050_send(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
acc_busy = TRUE;
while(rtc_busy == TRUE)
{
IWDG_delay_ms(0);
}
HAL_StatusTypeDef result = HAL_I2C_Master_Transmit(hi2c, DevAddress, pData, Size, Timeout);
acc_busy = FALSE;
return result;
}
HAL_StatusTypeDef MPU6050_receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
acc_busy = TRUE;
while(rtc_busy == TRUE)
{
IWDG_delay_ms(0);
}
HAL_StatusTypeDef result = HAL_I2C_Master_Receive(hi2c, DevAddress, pData, Size, Timeout);
acc_busy = FALSE;
return result;
}
HAL_StatusTypeDef DS3231_send(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
rtc_busy = TRUE;
while(acc_busy == TRUE)
{
IWDG_delay_ms(0);
}
HAL_StatusTypeDef result = HAL_I2C_Master_Transmit(hi2c, DevAddress, pData, Size, Timeout);
rtc_busy = FALSE;
return result;
}
HAL_StatusTypeDef DS3231_receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
rtc_busy = TRUE;
while(acc_busy == TRUE)
{
IWDG_delay_ms(0);
}
HAL_StatusTypeDef result = HAL_I2C_Master_Receive(hi2c, DevAddress, pData, Size, Timeout);
rtc_busy = FALSE;
return result;
}
‎2020-02-05 09:20 AM
:sad_but_relieved_face:
‎2020-02-05 09:40 AM
You wrote earlier
>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.
HAL_I2C_Master_Transmit() and HAL_I2C_Master_Receive() are blocking functions, not to be used in interrupts.
If one of these function are called in an interrupt handler, the acc_busy/rtc_busy flag in the while loop will never be cleared, because the interrupt handler blocks the main thread from running. A classic case of deadlock.
‎2020-02-05 09:51 AM
The HAL used to have a lot of issues, and potential race conditions, but by and large ST has tried to partition stuff into structures passed as handles/pointers. If people use the wrong ones, or have crosslinked global structures, or multiple structures describing the same hardware, in different states, I can see that being a problem. The HAL also poorly communicates the hazards of interrupt/callback context and what should and should not be occurring there. Especially things that block.
I think some of the ownership/mutex stuff needs to be done at an os/driver level, and the HAL shouldn't be the thing burdened with protecting everyone from themselves.
‎2020-02-05 09:52 AM
ISR in general shall be as brief as possible. Sending a full I2C transaction within an ISR may make the code weaker?
Also avoid putting delay functions in the ISR.
As for the previous question, on the HW level, I2C1 and I2C2 HW peripherals are decorellated.
I2C is a relatively slow speed serial interface. If I really get multiple "sources" requesting to use it to communicate, then it's an I2C transaction FIFO with callbacks that may need to be implemented, hoping not needing "to be done within *** msec" parameters... we are getting to a peripheral OS then.
(one transaction to queue being Start Write operation Start Read Operation Stop)
‎2020-02-05 09:54 AM
Yeah, you need to be mutexing ownership of the peripheral so you don't tread on your own feet.
Probably need to consider using non-blocking functions, and better managing the sequencing the usage to a singular resource.
‎2020-02-05 09:55 AM
Normally these peripherals shouldn't crosstalk. In HW anyway they are decoupled.