Gordon Finlay

Serial driver IOCTL_SERIAL_WAIT_FOR_TC blocks waiting for TC flag (draining UART) & IOCTL_SERIAL_TX_DRAINED question

Discussion created by Gordon Finlay on Mar 9, 2017
Latest reply on Mar 9, 2017 by Gordon Finlay

I am running MQX 3.8 on a Kinetis K20 device where I have serial driver issues. I'm using the interrupt-driven itty0: device. So I have a couple of related questions:

 

  1. In the MQX serial driver in serl_pol_kuart.c, the _kuart_polled_ioctl function will block indefinitely while waiting for the TC transmit complete flag to become set in the IO_IOCTL_SERIAL_WAIT_FOR_TC sub-command. The code gets stuck in a while loop indefinitely (which triggers a WDOG timeout) while it sits there waiting for the TC bit in the S1 register to become set indicating that the there is no more outgoing data in the FIFO waiting to drain.

 

case IO_IOCTL_SERIAL_WAIT_FOR_TC:

/* wait for transmission end signal */
while( ! sci_ptr->S1 & UART_S1_TC_MASK )
{ };                                       <-- stuck here - never exits while
break;

 

Is there any reason that the Kinetis UART could get stuck while attempting to drain the contents of the UART FIFO, and as a result will fail to set the TC bit in the S1 status register?  I don't expect this to block.

 

2. I'm looking for more background on whether there ever was a single MQX ioctl sub-command IO_IOCTL_SERIAL_TX_DRAINED which flushes both the serial driver circular queue ring buffers AND also ensures that the Kinetis UART is drained. In the MQX IO User Guide documentation there was an IO control sub-command titled IO_IOCTL_SERIAL_TX_DRAINED which stated that it "Returns TRUE if there are no transmit characters in the FIFOs or in the software rings".  Effectively, what I expect is a single MQX API which has the functionality where it implements the combination or equivalent of both fflush (pSerialPort) and  ioctl(pSerialPort, IO_IOCTL_SERIAL_WAIT_FOR_TC, NULL).

The fflush formatted I/O call will do a IO_IOCTL_FLUSH_OUTPUT that waits for the ring buffer to empty using while(!_CHARQ_EMPTY(int_io_dev_ptr->OUT_QUEUE)).  The IOCTL_SERIAL_WAIT_FOR_TC will wait for the UART to drain (as in the code in item 1 above).

 

In the history of the MQX IO User Guide, this IOCTL command was present from Rev 10 to Rev 22 of the MQX IO Users Guide, but was no longer included in MQX IO User Guide Rev 24.

 

MQX Version          IO User Guide Rev                  IO_IOCTL_SERIAL_TX_DRAINED included?

----------------------------------------------------------------------------------------------------------------------------------------

3.8                          Rev 10                                     Y

4.0                          Rev 16                                      Y

4.0.2                       Rev 18                                      Y

4.1                          Rev 22                                      Y

4.2                          Rev 24                                      N

 

 

I cannot see any implementation of the IO_IOCTL_SERIAL_TX_DRAINED in any serl_pol_kuart.c, serl_int.c, or serl_int_kuart.c low-level drivers for any version of MQX from 3.8 onwards.  Was this IOCTL command ever implemented?  There was no mention of removing this IOCTL from the documentation in the MQXCHLGUG Change log for MQX from V3.0.0 to 4.2.0 (dated 06/2015).

 

I look forward to feedback on both the issue with the UART FIFO draining (TC flag in S1 never gets set), as well as the question about the history of IO_IOCTL_SERIAL_TX_DRAINED in the IO User Guide and why this was never implemented.

Regards,

Gordon

Outcomes