Skip to main content
Visitor II
December 9, 2021
Question

STM32F4: Purpose of the usage of ATOMIC_SET_BIT ATOMIC_CLEAR_BIT macros in the low level drivers related to UART peripheral

  • December 9, 2021
  • 13 replies
  • 12584 views

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)

  • LL_USART_EnableDirectionRx is now using ATOMIC_SET_BIT macro instead of SET_BIT
  • LL_USART_DisableDirectionRx is now using ATOMIC_CLEAR_BIT macro instead of CLEAR_BIT
  • LL_USART_EnableDirectionTx is now using ATOMIC_SET_BIT macro instead of SET_BIT
  • LL_USART_DisableDirectionTx is now using ATOMIC_CLEAR_BIT macro instead of CLEAR_BIT
  • LL_USART_SetTransferDirection is now using ATOMIC_MODIFY_REG macro instead of MODIFY_REG
  • LL_USART_EnableIT_IDLE is now using ATOMIC_SET_BIT macro instead of SET_BIT
  • LL_USART_EnableIT_RXNE is now using ATOMIC_SET_BIT macro instead of SET_BIT
  • LL_USART_EnableIT_TC is now using ATOMIC_SET_BIT macro instead of SET_BIT
  • LL_USART_EnableIT_TXE is now using ATOMIC_SET_BIT macro instead of SET_BIT
  • LL_USART_EnableIT_PE is now using ATOMIC_SET_BIT macro instead of SET_BIT
  • LL_USART_EnableIT_ERROR is now using ATOMIC_SET_BIT macro instead of SET_BIT
  • LL_USART_EnableIT_CTS is now using ATOMIC_SET_BIT macro instead of SET_BIT
  • LL_USART_DisableIT_IDLE is now using ATOMIC_CLEAR_BIT macro instead of CLEAR_BIT
  • LL_USART_DisableIT_RXNE is now using ATOMIC_CLEAR_BIT macro instead of CLEAR_BIT
  • LL_USART_DisableIT_TC is now using ATOMIC_CLEAR_BIT macro instead of CLEAR_BIT
  • LL_USART_DisableIT_TXE is now using ATOMIC_CLEAR_BIT macro instead of CLEAR_BIT
  • LL_USART_DisableIT_PE is now using ATOMIC_CLEAR_BIT macro instead of CLEAR_BIT
  • LL_USART_DisableIT_ERROR is now using ATOMIC_CLEAR_BIT macro instead of CLEAR_BIT
  • LL_USART_DisableIT_CTS is now using ATOMIC_CLEAR_BIT macro instead of CLEAR_BIT
  • LL_USART_EnableDMAReq_RX is now using ATOMIC_SET_BIT macro instead of SET_BIT
  • LL_USART_DisableDMAReq_RX is now using ATOMIC_CLEAR_BIT macro instead of CLEAR_BIT
  • LL_USART_EnableDMAReq_TX is now using ATOMIC_SET_BIT macro instead of SET_BIT
  • LL_USART_DisableDMAReq_TX is now using ATOMIC_CLEAR_BIT macro instead of CLEAR_BIT

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?

    This topic has been closed for replies.

    13 replies

    Graduate
    December 12, 2021

    I looked a bit at the "thread safe" implementations, which are options in the CubeMX setups. Some of the higher level routines (fprint for instance), need to be surrounded by an RTOS semaphore when using RTOS.

    That kind of behavior ought to be a default (it is in some cases) with an RTOS. Not quite sure that it is.

    What the current implementation of "atomic" happens to be, I don't know, nor do I know why it was in there.

    In an 8 bit processor, accessing a 16 bit I/O address is a two cycle operation, which can possibly be interrupted. With an RTOS (or even an IRQ), you don't want this. Hence ATOMIC inserted as user code. Whether or not a 32 bit processor does the same in successive 16 bit writes (or 8 bit writes) which can happen depending on how external memory is mapped) no idea.

    Visitor II
    December 13, 2021

    When a peripheral can be shared with multiple async codes, the smart hardware should provide assist like gpio BSRR, or EXTI channel byte access, or RP2040 4 memory zones for direct, set, reset on registers. Otherwise, atomic penalty comes into play. Now most coders are single core and already interrupt disable comes with implementation dilemma, except in the cortex M0 where only one way exists...

    Super User
    December 13, 2021

    Right, smart hardware is always appreciated for SW development, as the additional complexity is then moved into the hardware.

    But, SW supporting synchronisation primitives are also inevitable when firmware reaches some complexity (not talking about bit/register level access only).

    The overhead of ATOMIC_SET_BIT compared to SET_BIT is 2 instruction cycles (cmp, bne) for the good case (branch/loop not taken).

    hth

    KnarfB

    Explorer II
    December 13, 2021

    There is a beginning of an answer in the release note of the HAL. But that does not indicate precisely which case is being treated.:

    "Handling of UART concurrent register access in case of race condition between Tx and Rx transfers (HAL UART and LL LPUART)"

    Super User
    December 13, 2021

    That makes the most sense. You could be setting up an RX transfer just as a TX interrupt hits and modifies the same registers.