apache / nuttx

Apache NuttX is a mature, real-time embedded operating system (RTOS)
https://nuttx.apache.org/
Apache License 2.0
2.83k stars 1.17k forks source link

Question about uart_xmitchars() #9482

Open GooTal opened 1 year ago

GooTal commented 1 year ago

Hi, i was running nuttx flat build on LoongArch 3A5000 CPU(not qemu). I`ve ported this version earlier. It`s strange that NuttShell (NSH) NuttX-12.0.0 could not be printed from uart. So i checked the code and found out that line 65 will judge whether the uart_txready is true. https://github.com/apache/nuttx/blob/a720984eb7b1cabd259014df0d4e9ac0ef0e94dd/drivers/serial/serial_io.c#L65

If it`s false, uart just won`t print anything.

Shall we change the code to synchronously wait for uart_txready? Like this:

  // while (dev->xmit.head != dev->xmit.tail && uart_txready(dev))
  while (dev->xmit.head != dev->xmit.tail)
    {
      /* Send the next byte */

      uart_send(dev, dev->xmit.buffer[dev->xmit.tail]);//Call u16550_send function below
      nbytes++;

      /* Increment the tail index */

      if (++(dev->xmit.tail) >= dev->xmit.size)
        {
          dev->xmit.tail = 0;
        }
    }

In u16550_send change it like this:

static void u16550_send(struct uart_dev_s *dev, int ch)
{
  while (!uart_txready(dev));  //wait untill it`s ready
  FAR struct u16550_s *priv = (FAR struct u16550_s *)dev->priv;
  u16550_serialout(priv, UART_THR_OFFSET, (uart_datawidth_t)ch);
}

I`ve also added this in u16550_setup() so that showprogress could print out ABC successfully.

static int u16550_setup(FAR struct uart_dev_s *dev)
{
//other codes
  /* Clear fifos */
  while ((u16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) == 0);//newly added
  u16550_serialout(priv, UART_FCR_OFFSET,
                   (UART_FCR_RXRST | UART_FCR_TXRST));
mu578 commented 1 year ago

I think the issue is not about synchronously waiting, there is an update/refresh state never happening, to me it is hiding a blind spot.

xiaoxiang781216 commented 1 year ago

but u16550_txready read LSR directly, 16550 hardware should finish the transmit in the finite time.

GooTal commented 1 year ago

I`m not sure what is happening on real hardware. It can`t print out anything without the changes above Maybe i`ve configured something wrong. Maybe it`s the hardware`s feature or defect.

davids5 commented 1 year ago

Is it TX holding register or TX shift register that is being checked? Is HW Flow control active? If CTS is active (at UASRT a HIGH) Some HW will not TX.

mu578 commented 1 year ago

Yes it might be in a busy state.