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.

TivaC/TI-RTOS Uart_read() in call back mode is blocking other tasks.

Hello,

I'm using the Tiva TM4c1294XL ethernet board. TI-RTOS version: 2.16.1.14

There are two tasks running on the board. An LED task every 1 second and a task to do UART parsing.

I'm using the call back method for uart_read/uart_write.  The UART_read() call  is in a while loop under the parser task waiting for a new line to trigger the callback. Maybe I'm not using it  right? I'm not sure. This methodology blocks the LED task.

However if I move to the UART_MODE_BLOCKED(without callbacks), the LED starts blinking. Any insight into what I'm doing wrong. Should the UART_read() have a task sleep in it so as to yield to the other tasks?

LED Task config:

{
    while (1) {
        Task_sleep((unsigned int)arg0);
        GPIO_toggle(Board_LED0);
    }
}

LED Task

Void heartBeatFxn(UArg arg0, UArg arg1)
{
    while (1) {
        Task_sleep((unsigned int)arg0);
        GPIO_toggle(Board_LED0);
    }
}

UART Task config:

    /* Construct UART parser Task  thread */
    Task_Params_init(&taskParams);
    taskParams.stackSize = TASKSTACKSIZE_UART_PARSER;
    taskParams.stack = &uartParserStack;
    taskParams.instance->name = "echo";
    Task_construct(&uartParserStruct, (Task_FuncPtr)uartParserFxn, &taskParams, NULL);

UART Task

Void uartParserFxn(UArg arg0, UArg arg1)
{

    UART_Handle uart;
    UART_Params uartParams;
    const char echoPrompt[] = "\fTesting:\r\n";
    Int16 lsiUartReturn = 0;

    /* Create a UART with data processing off. */
    UART_Params_init(&uartParams);
    uartParams.writeDataMode    = UART_DATA_TEXT;
    uartParams.readDataMode     = UART_DATA_TEXT;
    uartParams.writeMode        = UART_MODE_CALLBACK;
    uartParams.readMode         = UART_MODE_CALLBACK;
    uartParams.writeCallback    = &uartWriteCallback;
    uartParams.readCallback     = &uartReadCallback;
    uartParams.readReturnMode   = UART_RETURN_NEWLINE;
    uartParams.readEcho         = UART_ECHO_OFF;
    uartParams.baudRate         = 9600;
    uart = UART_open(Board_UART0, &uartParams);

    /* Make a copy of the handle to be used for parser functions. */
    uartDebug = uart;

    if (uart == NULL)
    {
        System_abort("Error opening the UART");
    }


    UART_write(uart, echoPrompt, sizeof(echoPrompt));

    while (1)
    {
        lsiUartReturn = UART_read(uart, &input, 20);
    }
}

Callbacks
void uartWriteCallback(UART_Handle handle, void *buffer, size_t num)
{
    /* Handle check. */
    if (handle == 0)
    {
        return;
    }
    //UART_read(handle, buffer, 20);
}

void uartReadCallback(UART_Handle handle, void *buffer, size_t num)
{

    /* Handle check. */
    if (handle == 0)
    {
        return;
    }

    /* String check. */
    if (buffer == 0)
    {
        return;
    }
}

  • Hi Gerard,

    Since the task has a while(1) and the UART_read() call is non-blocking when using callback mode, the parser task will run forever. In order to take advantage of the callback mode, you can do something like this:

    - Pend on a semaphore in the while(1) loop. This will block the parser task and let the LED task run.

    - Post the same semaphore in the read callback function. This will unblock the parser task.

    - Call UART_read() from parser task. Once read is complete, it will loop back and execute Semaphore_pend() again. This will block the task again so the LED task can run.

    Best,

    Ashish

  • Thanks Ashish. This worked well.