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.

UARTFlushTx (false) is stalling the program

Other Parts Discussed in Thread: TM4C123GH6PM

Hello,

as I understand, the UARTFlushTx(false) is waiting for the uartstdio to transmit all remaining characters in the Tx buffer and on the return, the Tx buffer is empty. My UART0 initialization looks like this:

void ConfigureUART0(void)
	{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);	// Enable the GPIO Peripheral used by the UART.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);	// Enable UART0

    GPIOPinConfigure(GPIO_PA0_U0RX);	// Configure GPIO Pins for UART mode.
    GPIOPinConfigure(GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);	// Use the internal 16MHz oscillator as the UART clock source.
    UARTStdioConfig(0, 115200, 16000000);	// Initialize the UART for console I/O.
    UARTEchoSet(0);
	}

And my program line looks like this:

UARTprintf("01234567012345670123456701234567\r\n");
UARTFlushTx(0);

What I'm getting on the terminal is:

01234567012345670

This is first 17 characters and then program stalls. When "UARTFlushTx(0);" line is commented, I am getting all the characters and program is working ok.

Another problem is this one: if I am replacing UARTFlushTx(0); with SysCtlDelay(...);, I am getting those first 17 chars before delay and the other remaining chars after delay, no matter how long delay is!!! I dont know, where the problem is...

  • Justinas Zdanevicius said:
    What I'm getting on the terminal is:

    01234567012345670

    This is first 17 characters and then program stalls.

    If uartstudio is set to buffered mode, then UARTprintf writes characters to the UART transmit FIFO until the UART transmit FIFO is full, and then stores the remaining characters in a software buffer which are output by an interrupt handler.

    If the program which uses uartstudio hasn't installed the required interrupt handler, then the program can stall because it ends up in the default interrupt handler which just spins in a loop.

    To install the usartstudio interrupt handler in the startup_ccs.c file you need to:

    - Add a prototype for the UARTStdioIntHandler function:

    //*****************************************************************************
    //
    // External declarations for the interrupt handlers used by the application.
    //
    //*****************************************************************************
    extern void UARTStdioIntHandler(void);
    

    - Add UARTStdioIntHandler in the g_pfnVectors array for the UART0 entry:

        UARTStdioIntHandler,                    // UART0 Rx and Tx
    

    The attached 3568.TM4C123_uart_test.zip CCS project has a call to UARTprintf which outputs all the characters.

  • I forgot to mention, that the UARTprintf(...) and UARTFlushTx(...) are in GPIO pin interrupt handler. If not in the GPIO interrupt handler, everything works fine. Is this because of interrupt priorities???

    My GPIO pin interrupt is registered like this:

    void Cfg_SW1(void)
    	{
    	GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4);												// Init PF4 as input
    	GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);		// Enable weak pullup resistor for PF4
    	GPIOIntDisable(GPIO_PORTF_BASE, GPIO_INT_PIN_4);        										// Disable interrupt for PF4 (in case it was enabled)
    	GPIOIntClear(GPIO_PORTF_BASE, GPIO_INT_PIN_4);      											// Clear pending interrupts for PF4
    	GPIOIntRegister(GPIO_PORTF_BASE, GPIOPortFIntHandler);
    	GPIOIntTypeSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_FALLING_EDGE);             					// Configure PF4 for falling edge trigger
    	GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4);     											// Enable interrupt for PF4
    	}

  • Thank you, Chester, for the quick reply! But everything is fine with startup file and there is UARTStdioIntHandlerwritten in the interrups vector array.

  • Justinas Zdanevicius said:
    I forgot to mention, that the UARTprintf(...) and UARTFlushTx(...) are in GPIO pin interrupt handler. If not in the GPIO interrupt handler, everything works fine. Is this because of interrupt priorities???

    Section 2.5.5 Exception Priorities of the TM4C123GH6PM data sheet says:

    When the processor is executing an exception handler, the exception handler is preempted if a higher priority exception occurs. If an exception occurs with the same priority as the exception being handled, the handler is not preempted, irrespective of the exception number. However, the status of the new interrupt changes to pending.

    The NVIC Interrupt Priority registers are all shown as having the same value (i.e. priority) at device reset. Therefore, if the GPIO interrupt handler calls UARTFlushTx then with the default priorities the processor will remain in a tight loop in the GPIO interrupt handler and not allow the UART interrupt handler to execute (which is required to flush the UART software buffer).

    While calling IntPrioritySet to set the UART interrupt priority to be higher than the GPIO interrupt handler could be used to avoid this problem, it will still mean the processor will be spinning in the GPIO interrupt handler in the call to UARTFlushTx function until the UART buffer has been flushed and thus prevent the processor from executing any non-interrupt code.

    Out of interest, what is the design reason for calling UARTFlushTx inside the GPIO interrupt handler?

    [I consider the normal approach is to make the interrupt handler do the minimum to service the interrupt source, with any operation which may "block" deferred to the main code. E.g. if using SYS/BIOS the interrupt handler gives a semaphore which a task is waiting on]

  • Hello Chester

    If the intent is to invoke UART print from the interrupt handler of the GPIO, wouldn't it be better to use the non-buffered version so that the the entire transmission is completed before any further information is processed within and outside the Interrupt handler of the GPIO.

    Regards

    Amit