]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
serial: introduce CONFIG_CONSOLE_FLUSH_ON_NEWLINE
authorRasmus Villemoes <rasmus.villemoes@prevas.dk>
Mon, 16 Oct 2023 08:35:22 +0000 (10:35 +0200)
committerTom Rini <trini@konsulko.com>
Tue, 24 Oct 2023 21:05:24 +0000 (17:05 -0400)
When debugging, one sometimes only gets partial output lines or
nothing at all from the last printf, because the uart has a largish
buffer, and the code after the printf() may cause the CPU to hang
before the uart IP has time to actually emit all the characters. That
can be very confusing, because one doesn't then know exactly where the
hang happens.

Introduce a config knob allowing one to wait for the uart fifo to
drain whenever a newline character is printed, roughly corresponding
to the effect of setvbuf(..., _IOLBF, ...) in ordinary C programs.

Since this uses IS_ENABLED() instead of cpp ifdef, we can remove the
ifdef around the _serial_flush() definition - if neither
CONSOLE_FLUSH_SUPPORT or CONSOLE_FLUSH_ON_NEWLINE are enabled, the
compiler elides _serial_flush(), but it won't warn about it being
unused.

Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Reviewed-by: Simon Glass <sjg@chromium.org>
common/Kconfig
drivers/serial/serial-uclass.c

index 93c96f23b013644cf7cc4ec9179ec1edb35f97b7..43701fe9e8974d265835788327e56dd7acf81af5 100644 (file)
@@ -224,6 +224,16 @@ config CONSOLE_FLUSH_SUPPORT
        help
          This enables compilation of flush() function for console flush support.
 
+config CONSOLE_FLUSH_ON_NEWLINE
+       bool "Flush console buffer on every newline character"
+       depends on DM_SERIAL
+       help
+         This makes the serial core code flush the console device
+         whenever a newline (\n) character has been emitted. This can
+         be especially useful when "printf debugging", as otherwise
+         lots of output could still be in the UART's FIFO by the time
+         one hits the code which causes the CPU to hang or reset.
+
 config CONSOLE_MUX
        bool "Enable console multiplexing"
        default y if VIDEO || LCD
index 8bdcdd1eaae7c390380e10dc25f57ce244ac75ce..df6a387284ac5c6937397207382f196cfdb56f09 100644 (file)
@@ -182,7 +182,6 @@ int serial_initialize(void)
        return serial_init();
 }
 
-#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
 static void _serial_flush(struct udevice *dev)
 {
        struct dm_serial_ops *ops = serial_get_ops(dev);
@@ -192,7 +191,6 @@ static void _serial_flush(struct udevice *dev)
        while (ops->pending(dev, false) > 0)
                ;
 }
-#endif
 
 static void _serial_putc(struct udevice *dev, char ch)
 {
@@ -205,6 +203,9 @@ static void _serial_putc(struct udevice *dev, char ch)
        do {
                err = ops->putc(dev, ch);
        } while (err == -EAGAIN);
+
+       if (IS_ENABLED(CONFIG_CONSOLE_FLUSH_ON_NEWLINE) && ch == '\n')
+               _serial_flush(dev);
 }
 
 static int __serial_puts(struct udevice *dev, const char *str, size_t len)
@@ -243,6 +244,9 @@ static void _serial_puts(struct udevice *dev, const char *str)
                if (*newline && __serial_puts(dev, "\r\n", 2))
                        return;
 
+               if (IS_ENABLED(CONFIG_CONSOLE_FLUSH_ON_NEWLINE) && *newline)
+                       _serial_flush(dev);
+
                str += len + !!*newline;
        } while (*str);
 }