This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM62P: uart_callback example: the usage of semaphore

Part Number: AM62P

Hi, 

I configure UART driver as callback mode to transmit and receive data. In the "uart_echo_callback" example provided in MCU+SDK, I noticed that there are two created  semaphore gUartWriteDoneSem and gUartReadDoneSem to monitor the Tx/Rx completion. When I disable those semaphores, I found this example cannot work normally. My question is are those semaphores compulsory to ensure the normal function of UART driver? If so, can you explain the reason in detail?

Regards,

Bomiao 

  • Hi Fan,

    A good question on the use of semaphores inside a callback example/application.

    The short answer is: the semaphores are not a requirement of the UART driver itself, but they are essential for the sequential application design pattern used in this example.


    How callback mode works

    In UART_TRANSFER_MODE_CALLBACK, both UART_write() and UART_read() return immediately after queueing the transfer to the interrupt-driven driver — they do not wait for the transfer to finish. The actual data movement happens in the background via interrupts. When the transfer completes, the driver calls your registered callback (uart_echo_write_callback / uart_echo_read_callback) from ISR context.

    This is the fundamental difference from blocking mode, where the driver internally waits until completion before returning.


    Why removing the semaphores breaks the example

    The example is written as a strictly sequential flow:

    UART_write(prompt) -> UART_read(8 chars) -> UART_write(echo) -> UART_write(exit msg)

    Without SemaphoreP_pend() calls between each step, the main task races ahead and issues all four transfers back-to-back without waiting. This causes three distinct problems:

    1. Overlapping TX transfers crash or get silently dropped

    The UART driver supports only one active TX transfer at a time. If UART_write() is called while a previous write is still in progress, the second call will return an error (driver busy). In the example, the prompt string (~90 bytes) takes measurable time to transmit at baud rate. Without waiting, the next UART_write() (echo) is called before the first finishes.

    2. Buffer still in use by the ISR

    UART_Transaction trans is a local stack variable. The driver holds a pointer to it and reads from it during interrupt processing until the transfer completes. If the main task moves on and reinitializes trans via UART_Transaction_init(&trans) for the next transfer while the ISR is still referencing the old one, the ISR operates on corrupted data, causing undefined behavior.

    3. Logical sequencing is broken

    The echo test requires that the read only begins after the user has seen the prompt, and that the echo write only begins after the received data is fully in gUartReceiveBuffer. Without synchronization, UART_read() could be queued before the prompt has finished transmitting, and UART_write(echo) could start before any data has been received into the buffer.

    Hope this explanation helps.

    Regards,

    Vaibhav