3 Replies Latest reply on Sep 2, 2020 8:36 AM by BragadeeshV_41

    FreeRTOS UART receiver ISR using a binary semaphore

    jihe_298791

      How do you write a UART receiver ISR in FreeRTOS when I send a command and sometimes get a response quickly. I'm trying to use a binary semaphore but I have a race condition where I get the response before I execute the xSemaphoreTake(). Here's what I'm doing:

       

      SemaphoreHandle_t msg_rcvd_semaphore = NULL;

      uint32 my_data;

       

      void xbee_rx_isr(void)

      {

           volatile uint32_t read_data;

       

           // Ignore all but received byte interrupts

           if((XBEE_UART_HW->INTR_RX_MASKED & SCB_INTR_RX_MASKED_NOT_EMPTY_Msk ) == 0) {

                return;

           }

       

          // Clear UART "RX fifo not empty interrupt"

           XBEE_UART_HW->INTR_RX = XBEE_UART_HW->INTR_RX & SCB_INTR_RX_NOT_EMPTY_Msk;       

             

           // Get the byte

           my_data = Cy_SCB_UART_Get(XBEE_UART_HW);

       

           //

           BaseType_t xHigherPriorityTaskWoken = pdFALSE;

           xSemaphoreGiveFromISR(msg_rcvd_semaphore, &xHigherPriorityTaskWoken);

           if (xHigherPriorityTaskWoken == pdTRUE) {

                portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

           }

      }

       

       

      void task (void)

      {

           msg_rcvd_semaphore = xSemaphoreCreateBinary();

       

           // Initialize the receiver here

       

           // Send commands and block for their responses

           for (;;) {

       

                // Transmit a command

                xbee_uart_put_string("my_command");

       

                // MY PROBLEM: Sometimes the response (and ISR) comes before I execute the following

                // xSemaphoreTake(), in which case xSemaphoreTake() hangs forever.

       

                // Wait for response (with 100 ms timeout)

                 if (xSemaphoreTake(msg_rcvd_semaphore, pdMS_TO_TICKS(100u)) == pdPASS) {

                     // Process my_data

                } else {

                     // Process timeout

                }

           }

      }