From 98b2949e3be884384525c6b9c89946dd54a70b8c Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 14 Mar 2020 10:30:07 -0600 Subject: [PATCH] z20x: Improve usability of bootloader boards/z80/ez80/z20x/configs/w25boot/defconfig: Increase size of serial Tx buffer. boards/z80/ez80/z20x/src/w25_main.c: Add some fflush() in necessary places. Greatly improves the usability of the UI. boards/z80/ez80/z20x/README.txt: Trival update to README drivers/serial/serial.c and tcdrain.c: Correct some typos. --- boards/z80/ez80/z20x/README.txt | 4 + .../z80/ez80/z20x/configs/w25boot/defconfig | 1 - boards/z80/ez80/z20x/src/w25_main.c | 28 +++++- drivers/serial/serial.c | 96 ++++++++----------- drivers/serial/tcdrain.c | 5 +- 5 files changed, 76 insertions(+), 58 deletions(-) diff --git a/boards/z80/ez80/z20x/README.txt b/boards/z80/ez80/z20x/README.txt index 9aa6578994..6c0c074682 100644 --- a/boards/z80/ez80/z20x/README.txt +++ b/boards/z80/ez80/z20x/README.txt @@ -229,6 +229,10 @@ Configuration Subdirectories information see: apps/system/nsh/README.txt and Documentation/NuttShell.html. + To be usable, this configuration should: (1) Use the same BAUD + as the bootloader and (2) switch from the MMC/SD card to the second + partition in the W25 part. + NOTES: 1. This configuration builds for execution entirely from RAM. A diff --git a/boards/z80/ez80/z20x/configs/w25boot/defconfig b/boards/z80/ez80/z20x/configs/w25boot/defconfig index c8fa1c40bb..d4c1357e8b 100644 --- a/boards/z80/ez80/z20x/configs/w25boot/defconfig +++ b/boards/z80/ez80/z20x/configs/w25boot/defconfig @@ -38,7 +38,6 @@ CONFIG_UART1_BAUD=2400 CONFIG_UART1_BITS=0 CONFIG_UART1_RXBUFSIZE=4096 CONFIG_UART1_SERIAL_CONSOLE=y -CONFIG_UART1_TXBUFSIZE=64 CONFIG_USER_ENTRYPOINT="w25_main" CONFIG_WDOG_INTRESERVE=1 CONFIG_Z20X_W25BOOT=y diff --git a/boards/z80/ez80/z20x/src/w25_main.c b/boards/z80/ez80/z20x/src/w25_main.c index 46cfc8ce91..053e845b96 100644 --- a/boards/z80/ez80/z20x/src/w25_main.c +++ b/boards/z80/ez80/z20x/src/w25_main.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -544,6 +545,20 @@ static int w25_boot_program(void) return ret; } +#ifdef CONFIG_SERIAL_TERMIOS + /* Drain all pending Tx output in stdout. "Booting..." message will be + * lost if the outgoing Tx bytes are not drained. + */ + + ret = tcdrain(1); + if (ret < 0) + { + ret = -get_errno(); + fprintf(stderr, "ERROR: tcdrain() failed: %d\n", ret); + return ret; + } +#endif + /* Start the successfully loaded program */ SRAM_ENTRY(); @@ -680,6 +695,7 @@ static int w25_wait_keypress(FAR char *keyset, int nseconds) if (++count == 10) { putchar('.'); + fflush(stdout); count = 0; } } @@ -771,6 +787,9 @@ int w25_main(int argc, char *argv) { return EXIT_FAILURE; } + + /* Load HEX command */ + else if (ret == 'L' || ret == 'l') { ret = w25_write_program(); @@ -781,8 +800,15 @@ int w25_main(int argc, char *argv) disable = true; } } - else /* if (ret == 'B' || ret == 'b' || ret == '\0') */ + + /* Boot from FLASH or timeout */ + + else /* if (ret == 'B' || ret == 'b' || ret == 0) */ { + /* REVISIT: The program is probably already in RAM. We may + * not have to reload and verify it. + */ + ret = w25_boot_program(); /* Shouldn't get here unless the FLASH content is bad */ diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index 0b16c80328..07cda2946b 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -1,36 +1,20 @@ /************************************************************************************ * drivers/serial/serial.c * - * Copyright (C) 2007-2009, 2011-2013, 2016-2019 Gregory Nutt. All rights - * reserved. - * Author: Gregory Nutt + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. * ************************************************************************************/ @@ -107,7 +91,8 @@ static int uart_tcdrain(FAR uart_dev_t *dev, clock_t timeout); static int uart_open(FAR struct file *filep); static int uart_close(FAR struct file *filep); static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen); -static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); +static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg); static int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup); @@ -155,9 +140,9 @@ static int uart_takesem(FAR sem_t *sem, bool errout) #define uart_givesem(sem) (void)nxsem_post(sem) -/**************************************************************************** +/************************************************************************************ * Name: uart_pollnotify - ****************************************************************************/ + ************************************************************************************/ static void uart_pollnotify(FAR uart_dev_t *dev, pollevent_t eventset) { @@ -313,6 +298,7 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock) goto err_out; } #endif + /* Check if we were awakened by signal. */ if (ret < 0) @@ -527,7 +513,7 @@ static int uart_tcdrain(FAR uart_dev_t *dev, clock_t timeout) return -ETIMEDOUT; } } - } + } uart_givesem(&dev->xmit.sem); } @@ -576,6 +562,7 @@ static int uart_open(FAR struct file *filep) #endif /* Start up serial port */ + /* Increment the count of references to the device. */ tmp = dev->open_count + 1; @@ -616,9 +603,9 @@ static int uart_open(FAR struct file *filep) ret = uart_attach(dev); if (ret < 0) { - uart_shutdown(dev); - leave_critical_section(flags); - goto errout_with_sem; + uart_shutdown(dev); + leave_critical_section(flags); + goto errout_with_sem; } #ifdef CONFIG_SERIAL_RXDMA @@ -657,10 +644,10 @@ static int uart_close(FAR struct file *filep) FAR uart_dev_t *dev = inode->i_private; irqstate_t flags; - /* Get exclusive access to the close semaphore (to synchronize open/close operations. - * NOTE: that we do not let this wait be interrupted by a signal. Technically, we - * should, but almost no one every checks the return value from close() so we avoid - * a potential memory leak by ignoring signals in this case. + /* Get exclusive access to the close semaphore (to synchronize open/close + * operations. NOTE: that we do not let this wait be interrupted by a signal. + * Technically, we should, but almost no one every checks the return value from + * close() so we avoid a potential memory leak by ignoring signals in this case. */ uart_takesem(&dev->closesem, false); @@ -852,20 +839,20 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen } break; - } + } #else /* No... the circular buffer is empty. Have we returned anything * to the caller? */ else if (recvd > 0) - { + { /* Yes.. break out of the loop and return the number of bytes * received up to the wait condition. */ break; - } + } /* No... then we would have to wait to get receive some data. * If the user has specified the O_NONBLOCK option, then do not @@ -880,6 +867,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen break; } #endif + /* Otherwise we are going to have to wait for data to arrive */ else @@ -936,7 +924,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen } else #endif - { + { /* Now wait with the Rx interrupt enabled. NuttX will * automatically re-enable global interrupts when this * thread goes to sleep. @@ -1241,6 +1229,7 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg) FAR uart_dev_t *dev = inode->i_private; /* Handle TTY-level IOCTLs here */ + /* Let low-level driver handle the call first */ int ret = dev->ops->ioctl(filep, cmd, arg); @@ -1452,9 +1441,9 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg) return ret; } -/**************************************************************************** +/************************************************************************************ * Name: uart_poll - ****************************************************************************/ + ************************************************************************************/ static int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) { @@ -1531,9 +1520,9 @@ static int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) } if (ndx != dev->xmit.tail) - { - eventset |= (fds->events & POLLOUT); - } + { + eventset |= (fds->events & POLLOUT); + } uart_givesem(&dev->xmit.sem); @@ -1546,9 +1535,9 @@ static int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) uart_takesem(&dev->recv.sem, false); if (dev->recv.head != dev->recv.tail) - { - eventset |= (fds->events & POLLIN); - } + { + eventset |= (fds->events & POLLIN); + } uart_givesem(&dev->recv.sem); @@ -1565,7 +1554,6 @@ static int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) { uart_pollnotify(dev, eventset); } - } else if (fds->priv != NULL) { @@ -1784,8 +1772,8 @@ void uart_connected(FAR uart_dev_t *dev, bool connected) * Name: uart_reset_sem * * Description: - * This function is called when need reset uart semaphore, this may used in kill one - * process, but this process was reading/writing with the semaphore. + * This function is called when need reset uart semaphore, this may used in kill + * one process, but this process was reading/writing with the semaphore. * ************************************************************************************/ diff --git a/drivers/serial/tcdrain.c b/drivers/serial/tcdrain.c index 5171aedf72..5e7f095b16 100644 --- a/drivers/serial/tcdrain.c +++ b/drivers/serial/tcdrain.c @@ -59,7 +59,8 @@ * Function for draining the output buffer of a terminal/serial device * * Input Parameters: - * fd - The 'fd' argument is an open file descriptor associated with a terminal. + * fd - The 'fd' argument is an open file descriptor associated with a + * terminal. * * Returned Value: * Upon successful completion, 0 is returned. Otherwise, -1 is returned and @@ -90,7 +91,7 @@ int tcdrain(int fd) * in this context because we are executing on the calling application's * thread. * - * NOTE: ioctl() will set the errno variable and return ERROR is any error + * NOTE: ioctl() will set the errno variable and return ERROR if any error * occurs. */