1

I am trying to read data with unkown size using UART Receive Interrupt. In the call back function, I enabled Rx interrupt in order to read characters until \n is gotten. If \n is get, then higher priority task which is deferred interrupt handler is woken. The problem is that I tried to read one by one byte via call back function and I tried to put each character into a buffer, but unfortunately buffer could not get any character. Moreover, deferred interrupt handler could not be woken.

My STM32 board is STM32F767ZI, and my IDE is KEIL.

Some Important notes before sharing the code: 1. rxIndex and gpsBuffer are declared as global. 2. Periodic function works without any problem.

Here is my code:

  1. Periodic Function, Priority = 1
void vPeriodicTask(void *pvParameters)
{
    const TickType_t xDelay500ms = pdMS_TO_TICKS(500UL);

    while (1) {
        vTaskDelay(xDelay500ms);

        HAL_UART_Transmit(&huart3,(uint8_t*)"Imu\r\n",sizeof("Imu\r\n"),1000);
        HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7);

    }
}
  1. Deferred Interrupt, Priority = 3
void vHandlerTask(void *pvParameters)
{
    const TickType_t xMaxExpectedBlockTime = pdMS_TO_TICKS(1000); 

    while(1) {
        if (xSemaphoreTake(xBinarySemaphore,xMaxExpectedBlockTime) == pdPASS) {
            HAL_UART_Transmit(&huart3,(uint8_t*)"Semaphore Acquired\r\n",sizeof("Semaphore 
                                                                                 Acquired\r\n"),1000);
            // Some important processes will be added here
            rxIndex = 0;
            HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14);
        }
    }
}
  1. Call back function:
void HAL_UART_RxCptlCallBack(UART_HandleTypeDef *huart)
{
        gpsBuffer[rxIndex++] = rData;
        if (rData == 0x0A) {
            BaseType_t xHigherPriorityTaskWoken;

            xSemaphoreGiveFromISR(xBinarySemaphore,&xHigherPriorityTaskWoken);
            portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
        }
        HAL_UART_Receive_IT(huart,(uint8_t*)&rData,1);
}
  1. Main function
    HAL_UART_Receive_IT(&huart3,&rData,1);
    xBinarySemaphore = xSemaphoreCreateBinary();
    if (xBinarySemaphore != NULL) {
        //success
        xTaskCreate(vHandlerTask,"Handler",128,NULL,1,&vHandlerTaskHandler);

        xTaskCreate(vPeriodicTask,"Periodic",128,NULL,3,&vPeriodicTaskHandler);

        vTaskStartScheduler();
    }

1 Answer 1

1
  1. Using HAL for it is a best way to get into the troubles. It uses HAL_Delay which is systick dependant and you should rewrite this function to read RTOS tick instead.

  2. I use queues to pass the data (the references to data) but it should work. There is always a big question mark when using the HAL functions.

void HAL_UART_RxCptlCallBack(UART_HandleTypeDef *huart)
{
     BaseType_t xHigherPriorityTaskWoken = pdFALSE;
        gpsBuffer[rxIndex++] = rData;
        if (rData == 0x0A) {

            if(xSemaphoreGiveFromISR(xBinarySemaphore,&xHigherPriorityTaskWoken) == pdFALSE)
            {
                /* some error handling */
            }
        }
     HAL_UART_Receive_IT(huart,(uint8_t*)&rData,1);
     portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}

Concluding if I use HAL & RTOS I always modify the way HAL handles timeouts.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your interest! I am going to try it :)
I do not know as I do not have this problem. But I do not use HAL to handle such a simple peripherals like UART

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.