2021-12-09 06:20 AM
Hello, I'm using LL driver in projects and I found these differences comparing the newest LL driver version (1.7.13) with my current why:
in file stm32f4xx_ll_usart.h/c (macro with prefix ATOMIC_ is now used in several functions)
So the question is, for what reason the macro with ATOMIC_ prefix is now used? Why only for UART peripheral? What these changes may affect?
2021-12-10 09:06 PM
> Documentation from ARM indicates "memory" access.
ARM's documentation says: "Load Exclusive and Store Exclusive operations must be performed only on Normal memory"
So, @Vladislav Yurov you can open a bug.
2021-12-11 03:06 AM
Interesting. And when you use simple SET_BIT/CLEAR_BIT ASSERT bailed out?
2021-12-11 07:38 AM
Correct. I also varied ARR to ensure it interrupts in different spots.
The IRQ code is a little different than what I wrote above.
void TIM1_UP_TIM10_IRQHandler() {
// clear update flag
TIM1->SR = ~TIM_SR_UIF;
++timx_toggles;
// toggle bit
if (timx_toggles % 2) {
ASSERT(!(GPIOA->ODR & GPIO_PIN_0));
ATOMIC_SET_BIT(GPIOA->ODR, GPIO_PIN_0);
ASSERT(GPIOA->ODR & GPIO_PIN_0);
} else {
ASSERT(GPIOA->ODR & GPIO_PIN_0);
ATOMIC_CLEAR_BIT(GPIOA->ODR, GPIO_PIN_0);
ASSERT(!(GPIOA->ODR & GPIO_PIN_0));
}
}
void VerifyStrEx() {
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIOA->ODR = 0;
__HAL_RCC_TIM1_CLK_ENABLE();
TIM1->ARR = 500;
TIM1->DIER |= TIM_DIER_UIE;
TIM1->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
while (1) {
ASSERT(!(GPIOA->ODR & GPIO_PIN_1));
SET_BIT(GPIOA->ODR, GPIO_PIN_1);
ASSERT(GPIOA->ODR & GPIO_PIN_1);
CLEAR_BIT(GPIOA->ODR, GPIO_PIN_1);
--TIM1->ARR;
if (TIM1->ARR < 100) {
TIM1->ARR = 500;
}
}
}
2021-12-11 08:09 AM
Toggling makes sense. From the main loop's view, the IRQ handler acts atomic anyway.
Thanks
KnarfB
2021-12-11 09:42 AM
Thanks.
JW
2021-12-11 07:11 PM
If this is now a two cycle instruction, then an interrupt can happen right in the middle of an instruction cycle. When using an RTOS, this can lead to very unwanted behavior. Making it atomic turns off interrupts so that the read/modify/write cycle that seems to be here cannot have an undesired context switch. Possibly has to do with AZURE RTOS and perhaps dual core processors?
2021-12-11 07:38 PM
2021-12-11 07:53 PM
Then this is not the meaning of "ATOMIC" that I am familiar with. I'm used to something like
"ATOMIC (option)
(
Code with interrupts turned off
}
2021-12-11 10:49 PM
I agree with you Harvey. If the reference code must be compatible with all projects, of course it wilk have to give up some performance away for the sake of shorter debug experience with non expert embedded coders. In the end, if the code you develop goes into a resale product, coder will own the whole code that you probably personalized and optimised as the spec is known. Maybe it is bare metal, so atomic maybe removed. Maybe the code runs in non priviledged mode and it's ok for the coder.
The key is to start with a safe code for new coders. Now the atomic could be done by the coder, and to me it is passing a know how and challenge upward, increasing the jitter coming from the WCET growing...
2021-12-11 11:58 PM
No, it is not. Turning interrupts off has global impact on the core (timing). One task/thread/irq takes ownership of the core and the others are starving. In contrast, ldrex + strex have only impact on the current task/thread/irq: the strex might fail. Often spin lock loops are built around that. So, if a race condition occured, the task/thread/irq repeats the request until done. This sounds fair, at least if there are many tasks/threads/irqs and the chance of a collision is low.
hth
KnarfB