xiaoxiang781216 commented on code in PR #7554: URL: https://github.com/apache/nuttx/pull/7554#discussion_r1036293284
########## drivers/drivers_initialize.c: ########## @@ -64,6 +65,24 @@ void drivers_initialize(void) syslog_initialize(); +#if defined (CONFIG_CONSOLE_RTT) Review Comment: ```suggestion #if defined(CONFIG_CONSOLE_RTT) ``` ########## drivers/drivers_initialize.c: ########## @@ -64,6 +65,24 @@ void drivers_initialize(void) syslog_initialize(); +#if defined (CONFIG_CONSOLE_RTT) + serial_rtt_register("/dev/console", 0, true, + CONFIG_SEGGER_RTT_BUFFER_SIZE_UP, + CONFIG_SEGGER_RTT_BUFFER_SIZE_DOWN); +#endif + +#if defined (CONFIG_SERIAL_RTT1) Review Comment: ```suggestion #if defined(CONFIG_SERIAL_RTT1) ``` ########## drivers/drivers_initialize.c: ########## @@ -64,6 +65,24 @@ void drivers_initialize(void) syslog_initialize(); +#if defined (CONFIG_CONSOLE_RTT) + serial_rtt_register("/dev/console", 0, true, + CONFIG_SEGGER_RTT_BUFFER_SIZE_UP, + CONFIG_SEGGER_RTT_BUFFER_SIZE_DOWN); +#endif + +#if defined (CONFIG_SERIAL_RTT1) + serial_rtt_register("/dev/rtt1", 1, + CONFIG_SEGGER_RTT1_BUFFER_SIZE_UP, + CONFIG_SEGGER_RTT1_BUFFER_SIZE_DOWN); +#endif + +#if defined (CONFIG_SERIAL_RTT2) Review Comment: ```suggestion #if defined(CONFIG_SERIAL_RTT2) ``` ########## drivers/segger/Kconfig: ########## @@ -63,6 +63,34 @@ config SEGGER_RTT_BUFFER_SIZE_DOWN ---help--- Size of the buffer for terminal input to target from host (Usually keyboard input) +config SEGGER_RTT1_BUFFER_SIZE_UP + int "RTT channel 1 tx buffer size" + depends on SEGGER_RTT_MAX_NUM_UP_BUFFERS >= 2 + default SEGGER_RTT_BUFFER_SIZE_UP + ---help--- + Size of the buffer for channel 1 output of target, up to host + +config SEGGER_RTT1_BUFFER_SIZE_DOWN + int "RTT channel 1 tx buffer size" + depends on SEGGER_RTT_MAX_NUM_DOWN_BUFFERS >= 2 Review Comment: ```suggestion depends on SEGGER_RTT_MAX_NUM_DOWN_BUFFERS >= 1 ``` ########## drivers/drivers_initialize.c: ########## @@ -64,6 +65,24 @@ void drivers_initialize(void) syslog_initialize(); +#if defined (CONFIG_CONSOLE_RTT) + serial_rtt_register("/dev/console", 0, true, + CONFIG_SEGGER_RTT_BUFFER_SIZE_UP, + CONFIG_SEGGER_RTT_BUFFER_SIZE_DOWN); +#endif + +#if defined (CONFIG_SERIAL_RTT1) + serial_rtt_register("/dev/rtt1", 1, Review Comment: add false ########## drivers/drivers_initialize.c: ########## @@ -64,6 +65,24 @@ void drivers_initialize(void) syslog_initialize(); +#if defined (CONFIG_CONSOLE_RTT) + serial_rtt_register("/dev/console", 0, true, + CONFIG_SEGGER_RTT_BUFFER_SIZE_UP, + CONFIG_SEGGER_RTT_BUFFER_SIZE_DOWN); +#endif + +#if defined (CONFIG_SERIAL_RTT1) + serial_rtt_register("/dev/rtt1", 1, + CONFIG_SEGGER_RTT1_BUFFER_SIZE_UP, + CONFIG_SEGGER_RTT1_BUFFER_SIZE_DOWN); +#endif + +#if defined (CONFIG_SERIAL_RTT2) + serial_rtt_register("/dev/rtt2", 2, Review Comment: add false ########## drivers/segger/Kconfig: ########## @@ -94,6 +122,48 @@ config SYSLOG_RTT ---help--- Use Segger J-Link RTT as a SYSLOG output device. +config SERIAL_RTT + bool + select SEGGER_RTT + select SERIAL_RXDMA + select SERIAL_TXDMA + default n + ---help--- + This option is used to enable RTT serial device + In Segger RTT serial driver, RTT channel buffer and serial DMA buffer are shared, + So you cannot use RTT stream to operate it + +config SERIAL_RTT1 + bool "Segger RTT serial for channel 1" + default n + select SERIAL_RTT + ---help--- + This option is used to enable the serial driver of channel 1 + +config SERIAL_RTT2 + bool "Segger RTT serial for channel 2" + default n + select SERIAL_RTT Review Comment: depends on SEGGER_RTT_MAX_NUM_UP_BUFFERS >= 2 && SEGGER_RTT_MAX_NUM_DOWN_BUFFERS >= 2 ########## drivers/segger/serial_rtt.c: ########## @@ -0,0 +1,380 @@ +/**************************************************************************** + * drivers/segger/serial_rtt.c + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <assert.h> +#include <debug.h> +#include <errno.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#include <nuttx/kmalloc.h> +#include <nuttx/kthread.h> +#include <nuttx/list.h> +#include <nuttx/serial/serial.h> +#include <nuttx/signal.h> + +#include <SEGGER_RTT.h> + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct serial_rtt_dev_s +{ + struct list_node node; + struct uart_dev_s uart; + int channel; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int serial_rtt_setup(FAR struct uart_dev_s *dev); +static void serial_rtt_shutdown(FAR struct uart_dev_s *dev); +static int serial_rtt_attach(FAR struct uart_dev_s *dev); +static void serial_rtt_detach(FAR struct uart_dev_s *dev); +static int serial_rtt_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); +static int serial_rtt_receive(FAR struct uart_dev_s *dev, + FAR unsigned int *status); +static void serial_rtt_rxint(FAR struct uart_dev_s *dev, bool enable); +static bool serial_rtt_rxavailable(FAR struct uart_dev_s *dev); +static void serial_rtt_dmasend(FAR struct uart_dev_s *dev); +static void serial_rtt_dmareceive(FAR struct uart_dev_s *dev); +static void serial_rtt_dmarxfree(FAR struct uart_dev_s *dev); +static void serial_rtt_dmatxavail(FAR struct uart_dev_s *dev); +static void serial_rtt_send(FAR struct uart_dev_s *dev, int ch); +static void serial_rtt_txint(FAR struct uart_dev_s *dev, bool enable); +static bool serial_rtt_txready(FAR struct uart_dev_s *dev); +static bool serial_rtt_txempty(FAR struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct list_node g_serial_rtt_list = LIST_INITIAL_VALUE(g_serial_rtt_list); + +static const struct uart_ops_s g_serial_rtt_ops = +{ + serial_rtt_setup, + serial_rtt_shutdown, + serial_rtt_attach, + serial_rtt_detach, + serial_rtt_ioctl, + serial_rtt_receive, + serial_rtt_rxint, + serial_rtt_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, +#endif + serial_rtt_dmasend, + serial_rtt_dmareceive, + serial_rtt_dmarxfree, + serial_rtt_dmatxavail, + serial_rtt_send, + serial_rtt_txint, + serial_rtt_txready, + serial_rtt_txempty, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: serial_rtt_setup + ****************************************************************************/ + +static int serial_rtt_setup(FAR struct uart_dev_s *dev) +{ + return OK; +} + +/**************************************************************************** + * Name: serial_rtt_shutdown + ****************************************************************************/ + +static void serial_rtt_shutdown(FAR struct uart_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: serial_rtt_attach + ****************************************************************************/ + +static int serial_rtt_attach(FAR struct uart_dev_s *dev) +{ + return OK; +} + +/**************************************************************************** + * Name: serial_rtt_detach + ****************************************************************************/ + +static void serial_rtt_detach(FAR struct uart_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: serial_rtt_ioctl + ****************************************************************************/ + +static int serial_rtt_ioctl(FAR struct file *filep, int cmd, + unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: serial_rtt_receive + ****************************************************************************/ + +static int serial_rtt_receive(FAR struct uart_dev_s *dev, + FAR unsigned int *status) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: serial_rtt_rxint + ****************************************************************************/ + +static void serial_rtt_rxint(FAR struct uart_dev_s *dev, bool enable) +{ +} + +/**************************************************************************** + * Name: serial_rtt_rxavailable + ****************************************************************************/ + +static bool serial_rtt_rxavailable(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = + (FAR struct serial_rtt_dev_s *)dev->priv; + return SEGGER_RTT_HasData(rtt->channel) != 0; +} + +/**************************************************************************** + * Name: serial_rtt_dmasend + ****************************************************************************/ + +static void serial_rtt_dmasend(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = + (FAR struct serial_rtt_dev_s *)dev->priv; + FAR SEGGER_RTT_BUFFER_UP *ring = (SEGGER_RTT_BUFFER_UP *)((FAR char *) + &_SEGGER_RTT.aUp[rtt->channel] + SEGGER_RTT_UNCACHED_OFF); + FAR struct uart_dmaxfer_s *xfer = &dev->dmatx; + size_t len = xfer->length + xfer->nlength; Review Comment: ``` FAR struct serial_rtt_dev_s *rtt = (FAR struct serial_rtt_dev_s *)dev->priv; FAR struct uart_dmaxfer_s *xfer = &dev->dmatx; if (channel) { FAR SEGGER_RTT_BUFFER_UP *ring = (SEGGER_RTT_BUFFER_UP *)((FAR char *) &_SEGGER_RTT.aUp[rtt->channel] + SEGGER_RTT_UNCACHED_OFF); ring->WrOff = (ring->WrOff + xfer->length + xfer->nlength) % dev->xmit.size; } else { size_t len = SEGGER_RTT_Write(rtt->channel, xfer->buffer, xfer->length); if (len == xfer->length && xfer->nlength) { len += SEGGER_RTT_Write(rtt->channel, xfer->nbuffer, xfer->nlength); } xfer->nbytes = len; uart_xmitchars_done(dev); } ``` ########## drivers/segger/serial_rtt.c: ########## @@ -0,0 +1,380 @@ +/**************************************************************************** + * drivers/segger/serial_rtt.c + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <assert.h> +#include <debug.h> +#include <errno.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#include <nuttx/kmalloc.h> +#include <nuttx/kthread.h> +#include <nuttx/list.h> +#include <nuttx/serial/serial.h> +#include <nuttx/signal.h> + +#include <SEGGER_RTT.h> + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct serial_rtt_dev_s +{ + struct list_node node; + struct uart_dev_s uart; + int channel; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int serial_rtt_setup(FAR struct uart_dev_s *dev); +static void serial_rtt_shutdown(FAR struct uart_dev_s *dev); +static int serial_rtt_attach(FAR struct uart_dev_s *dev); +static void serial_rtt_detach(FAR struct uart_dev_s *dev); +static int serial_rtt_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); +static int serial_rtt_receive(FAR struct uart_dev_s *dev, + FAR unsigned int *status); +static void serial_rtt_rxint(FAR struct uart_dev_s *dev, bool enable); +static bool serial_rtt_rxavailable(FAR struct uart_dev_s *dev); +static void serial_rtt_dmasend(FAR struct uart_dev_s *dev); +static void serial_rtt_dmareceive(FAR struct uart_dev_s *dev); +static void serial_rtt_dmarxfree(FAR struct uart_dev_s *dev); +static void serial_rtt_dmatxavail(FAR struct uart_dev_s *dev); +static void serial_rtt_send(FAR struct uart_dev_s *dev, int ch); +static void serial_rtt_txint(FAR struct uart_dev_s *dev, bool enable); +static bool serial_rtt_txready(FAR struct uart_dev_s *dev); +static bool serial_rtt_txempty(FAR struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct list_node g_serial_rtt_list = LIST_INITIAL_VALUE(g_serial_rtt_list); + +static const struct uart_ops_s g_serial_rtt_ops = +{ + serial_rtt_setup, + serial_rtt_shutdown, + serial_rtt_attach, + serial_rtt_detach, + serial_rtt_ioctl, + serial_rtt_receive, + serial_rtt_rxint, + serial_rtt_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, +#endif + serial_rtt_dmasend, + serial_rtt_dmareceive, + serial_rtt_dmarxfree, + serial_rtt_dmatxavail, + serial_rtt_send, + serial_rtt_txint, + serial_rtt_txready, + serial_rtt_txempty, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: serial_rtt_setup + ****************************************************************************/ + +static int serial_rtt_setup(FAR struct uart_dev_s *dev) +{ + return OK; +} + +/**************************************************************************** + * Name: serial_rtt_shutdown + ****************************************************************************/ + +static void serial_rtt_shutdown(FAR struct uart_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: serial_rtt_attach + ****************************************************************************/ + +static int serial_rtt_attach(FAR struct uart_dev_s *dev) +{ + return OK; +} + +/**************************************************************************** + * Name: serial_rtt_detach + ****************************************************************************/ + +static void serial_rtt_detach(FAR struct uart_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: serial_rtt_ioctl + ****************************************************************************/ + +static int serial_rtt_ioctl(FAR struct file *filep, int cmd, + unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: serial_rtt_receive + ****************************************************************************/ + +static int serial_rtt_receive(FAR struct uart_dev_s *dev, + FAR unsigned int *status) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: serial_rtt_rxint + ****************************************************************************/ + +static void serial_rtt_rxint(FAR struct uart_dev_s *dev, bool enable) +{ +} + +/**************************************************************************** + * Name: serial_rtt_rxavailable + ****************************************************************************/ + +static bool serial_rtt_rxavailable(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = + (FAR struct serial_rtt_dev_s *)dev->priv; + return SEGGER_RTT_HasData(rtt->channel) != 0; +} + +/**************************************************************************** + * Name: serial_rtt_dmasend + ****************************************************************************/ + +static void serial_rtt_dmasend(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = + (FAR struct serial_rtt_dev_s *)dev->priv; + FAR SEGGER_RTT_BUFFER_UP *ring = (SEGGER_RTT_BUFFER_UP *)((FAR char *) + &_SEGGER_RTT.aUp[rtt->channel] + SEGGER_RTT_UNCACHED_OFF); + FAR struct uart_dmaxfer_s *xfer = &dev->dmatx; + size_t len = xfer->length + xfer->nlength; + size_t slen = 0; + + if (rtt->channel) + { + ring->WrOff = (ring->WrOff + len) % dev->xmit.size; + } + else + { + slen += SEGGER_RTT_Write(rtt->channel, xfer->buffer, xfer->length); + slen += SEGGER_RTT_Write(rtt->channel, xfer->nbuffer, xfer->nlength); + } + + xfer->nbytes = slen; + uart_xmitchars_done(dev); +} + +/**************************************************************************** + * Name: serial_rtt_dmareceive + ****************************************************************************/ + +static void serial_rtt_dmareceive(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = + (FAR struct serial_rtt_dev_s *)dev->priv; + FAR struct uart_dmaxfer_s *xfer = &dev->dmarx; + FAR SEGGER_RTT_BUFFER_DOWN *ring = (SEGGER_RTT_BUFFER_DOWN *)((FAR char *) + &_SEGGER_RTT.aDown[rtt->channel] + SEGGER_RTT_UNCACHED_OFF); + size_t space = xfer->length + xfer->nlength; + size_t recvlen = 0; + + if (rtt->channel) + { + if (ring->RdOff <= ring->WrOff) + { + recvlen = ring->WrOff - ring->RdOff; + } + else + { + recvlen = ring->SizeOfBuffer - (ring->WrOff - ring->RdOff); + } + + recvlen = (recvlen > space) ? space : recvlen; + ring->RdOff = recvlen; + } + else + { + recvlen += SEGGER_RTT_Read(rtt->channel, xfer->buffer, xfer->length); + if ((recvlen == xfer->length) && SEGGER_RTT_HasData(rtt->channel)) + { + recvlen += SEGGER_RTT_Read(rtt->channel, xfer->nbuffer, + xfer->nlength); + } + } + + xfer->nbytes = recvlen; + uart_recvchars_done(dev); +} + +/**************************************************************************** + * Name: serial_rtt_dmarxfree + ****************************************************************************/ + +static void serial_rtt_dmarxfree(FAR struct uart_dev_s *dev) +{ + /* When the DMA buffer is empty, check whether there is data to read */ + + if (serial_rtt_rxavailable(dev)) + { + uart_recvchars_dma(dev); + } +} + +/**************************************************************************** + * Name: serial_rtt_dmatxavail + ****************************************************************************/ + +static void serial_rtt_dmatxavail(FAR struct uart_dev_s *dev) +{ + uart_xmitchars_dma(dev); Review Comment: change to: ``` if (dev->dmatx.length == 0) { uart_xmitchars_dma(dev); } ``` ########## drivers/segger/serial_rtt.c: ########## @@ -0,0 +1,380 @@ +/**************************************************************************** + * drivers/segger/serial_rtt.c + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <assert.h> +#include <debug.h> +#include <errno.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#include <nuttx/kmalloc.h> +#include <nuttx/kthread.h> +#include <nuttx/list.h> +#include <nuttx/serial/serial.h> +#include <nuttx/signal.h> + +#include <SEGGER_RTT.h> + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct serial_rtt_dev_s +{ + struct list_node node; + struct uart_dev_s uart; + int channel; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int serial_rtt_setup(FAR struct uart_dev_s *dev); +static void serial_rtt_shutdown(FAR struct uart_dev_s *dev); +static int serial_rtt_attach(FAR struct uart_dev_s *dev); +static void serial_rtt_detach(FAR struct uart_dev_s *dev); +static int serial_rtt_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); +static int serial_rtt_receive(FAR struct uart_dev_s *dev, + FAR unsigned int *status); +static void serial_rtt_rxint(FAR struct uart_dev_s *dev, bool enable); +static bool serial_rtt_rxavailable(FAR struct uart_dev_s *dev); +static void serial_rtt_dmasend(FAR struct uart_dev_s *dev); +static void serial_rtt_dmareceive(FAR struct uart_dev_s *dev); +static void serial_rtt_dmarxfree(FAR struct uart_dev_s *dev); +static void serial_rtt_dmatxavail(FAR struct uart_dev_s *dev); +static void serial_rtt_send(FAR struct uart_dev_s *dev, int ch); +static void serial_rtt_txint(FAR struct uart_dev_s *dev, bool enable); +static bool serial_rtt_txready(FAR struct uart_dev_s *dev); +static bool serial_rtt_txempty(FAR struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct list_node g_serial_rtt_list = LIST_INITIAL_VALUE(g_serial_rtt_list); + +static const struct uart_ops_s g_serial_rtt_ops = +{ + serial_rtt_setup, + serial_rtt_shutdown, + serial_rtt_attach, + serial_rtt_detach, + serial_rtt_ioctl, + serial_rtt_receive, + serial_rtt_rxint, + serial_rtt_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, +#endif + serial_rtt_dmasend, + serial_rtt_dmareceive, + serial_rtt_dmarxfree, + serial_rtt_dmatxavail, + serial_rtt_send, + serial_rtt_txint, + serial_rtt_txready, + serial_rtt_txempty, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: serial_rtt_setup + ****************************************************************************/ + +static int serial_rtt_setup(FAR struct uart_dev_s *dev) +{ + return OK; +} + +/**************************************************************************** + * Name: serial_rtt_shutdown + ****************************************************************************/ + +static void serial_rtt_shutdown(FAR struct uart_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: serial_rtt_attach + ****************************************************************************/ + +static int serial_rtt_attach(FAR struct uart_dev_s *dev) +{ + return OK; +} + +/**************************************************************************** + * Name: serial_rtt_detach + ****************************************************************************/ + +static void serial_rtt_detach(FAR struct uart_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: serial_rtt_ioctl + ****************************************************************************/ + +static int serial_rtt_ioctl(FAR struct file *filep, int cmd, + unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: serial_rtt_receive + ****************************************************************************/ + +static int serial_rtt_receive(FAR struct uart_dev_s *dev, + FAR unsigned int *status) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: serial_rtt_rxint + ****************************************************************************/ + +static void serial_rtt_rxint(FAR struct uart_dev_s *dev, bool enable) +{ +} + +/**************************************************************************** + * Name: serial_rtt_rxavailable + ****************************************************************************/ + +static bool serial_rtt_rxavailable(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = + (FAR struct serial_rtt_dev_s *)dev->priv; + return SEGGER_RTT_HasData(rtt->channel) != 0; +} + +/**************************************************************************** + * Name: serial_rtt_dmasend + ****************************************************************************/ + +static void serial_rtt_dmasend(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = + (FAR struct serial_rtt_dev_s *)dev->priv; + FAR SEGGER_RTT_BUFFER_UP *ring = (SEGGER_RTT_BUFFER_UP *)((FAR char *) + &_SEGGER_RTT.aUp[rtt->channel] + SEGGER_RTT_UNCACHED_OFF); + FAR struct uart_dmaxfer_s *xfer = &dev->dmatx; + size_t len = xfer->length + xfer->nlength; + size_t slen = 0; + + if (rtt->channel) + { + ring->WrOff = (ring->WrOff + len) % dev->xmit.size; + } + else + { + slen += SEGGER_RTT_Write(rtt->channel, xfer->buffer, xfer->length); + slen += SEGGER_RTT_Write(rtt->channel, xfer->nbuffer, xfer->nlength); + } + + xfer->nbytes = slen; + uart_xmitchars_done(dev); +} + +/**************************************************************************** + * Name: serial_rtt_dmareceive + ****************************************************************************/ + +static void serial_rtt_dmareceive(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = + (FAR struct serial_rtt_dev_s *)dev->priv; + FAR struct uart_dmaxfer_s *xfer = &dev->dmarx; + FAR SEGGER_RTT_BUFFER_DOWN *ring = (SEGGER_RTT_BUFFER_DOWN *)((FAR char *) + &_SEGGER_RTT.aDown[rtt->channel] + SEGGER_RTT_UNCACHED_OFF); + size_t space = xfer->length + xfer->nlength; + size_t recvlen = 0; + + if (rtt->channel) + { + if (ring->RdOff <= ring->WrOff) + { + recvlen = ring->WrOff - ring->RdOff; + } + else + { + recvlen = ring->SizeOfBuffer - (ring->WrOff - ring->RdOff); + } + + recvlen = (recvlen > space) ? space : recvlen; + ring->RdOff = recvlen; + } + else + { + recvlen += SEGGER_RTT_Read(rtt->channel, xfer->buffer, xfer->length); + if ((recvlen == xfer->length) && SEGGER_RTT_HasData(rtt->channel)) + { + recvlen += SEGGER_RTT_Read(rtt->channel, xfer->nbuffer, + xfer->nlength); + } + } + + xfer->nbytes = recvlen; + uart_recvchars_done(dev); +} + +/**************************************************************************** + * Name: serial_rtt_dmarxfree + ****************************************************************************/ + +static void serial_rtt_dmarxfree(FAR struct uart_dev_s *dev) +{ + /* When the DMA buffer is empty, check whether there is data to read */ + + if (serial_rtt_rxavailable(dev)) + { + uart_recvchars_dma(dev); + } +} + +/**************************************************************************** + * Name: serial_rtt_dmatxavail + ****************************************************************************/ + +static void serial_rtt_dmatxavail(FAR struct uart_dev_s *dev) +{ + uart_xmitchars_dma(dev); +} + +/**************************************************************************** + * Name: serial_rtt_send + ****************************************************************************/ + +static void serial_rtt_send(FAR struct uart_dev_s *dev, int ch) Review Comment: need add, otherwise the output from irq will lose: ``` int nexthead; nexthead = dev->xmit.head + 1; if (nexthead >= dev->xmit.size) { nexthead = 0; } if (nexthead != dev->xmit.tail) { /* No.. not full. Add the character to the TX buffer and return. */ dev->xmit.buffer[dev->xmit.head] = ch; dev->xmit.head = nexthead; } uart_rtt_dmatxavail(dev); ``` ########## drivers/segger/Kconfig: ########## @@ -94,6 +122,48 @@ config SYSLOG_RTT ---help--- Use Segger J-Link RTT as a SYSLOG output device. +config SERIAL_RTT + bool + select SEGGER_RTT + select SERIAL_RXDMA + select SERIAL_TXDMA + default n + ---help--- + This option is used to enable RTT serial device + In Segger RTT serial driver, RTT channel buffer and serial DMA buffer are shared, + So you cannot use RTT stream to operate it + +config SERIAL_RTT1 + bool "Segger RTT serial for channel 1" + default n + select SERIAL_RTT Review Comment: depends on SEGGER_RTT_MAX_NUM_UP_BUFFERS >= 1 && SEGGER_RTT_MAX_NUM_DOWN_BUFFERS >= 1 ########## drivers/segger/Kconfig: ########## @@ -63,6 +63,34 @@ config SEGGER_RTT_BUFFER_SIZE_DOWN ---help--- Size of the buffer for terminal input to target from host (Usually keyboard input) +config SEGGER_RTT1_BUFFER_SIZE_UP + int "RTT channel 1 tx buffer size" + depends on SEGGER_RTT_MAX_NUM_UP_BUFFERS >= 2 Review Comment: ```suggestion depends on SEGGER_RTT_MAX_NUM_UP_BUFFERS >= 1 ``` ########## drivers/segger/Kconfig: ########## @@ -94,6 +122,48 @@ config SYSLOG_RTT ---help--- Use Segger J-Link RTT as a SYSLOG output device. +config SERIAL_RTT + bool + select SEGGER_RTT + select SERIAL_RXDMA + select SERIAL_TXDMA + default n + ---help--- + This option is used to enable RTT serial device + In Segger RTT serial driver, RTT channel buffer and serial DMA buffer are shared, + So you cannot use RTT stream to operate it + +config SERIAL_RTT1 + bool "Segger RTT serial for channel 1" + default n + select SERIAL_RTT + ---help--- + This option is used to enable the serial driver of channel 1 + +config SERIAL_RTT2 + bool "Segger RTT serial for channel 2" + default n + select SERIAL_RTT + ---help--- + This option is used to enable the serial driver of channel 2 + +config SERIAL_RTT_POLLING_INTERVAL + int "Segger RTT serial pilling interval (us)" + default 10000 + depends on SERIAL_RTT + ---help--- + This option is used to configure the RTT serial polling interval + +config CONSOLE_RTT Review Comment: move before line 136 ########## drivers/segger/serial_rtt.c: ########## @@ -0,0 +1,380 @@ +/**************************************************************************** + * drivers/segger/serial_rtt.c + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <assert.h> +#include <debug.h> +#include <errno.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#include <nuttx/kmalloc.h> +#include <nuttx/kthread.h> +#include <nuttx/list.h> +#include <nuttx/serial/serial.h> +#include <nuttx/signal.h> + +#include <SEGGER_RTT.h> + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct serial_rtt_dev_s +{ + struct list_node node; + struct uart_dev_s uart; + int channel; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int serial_rtt_setup(FAR struct uart_dev_s *dev); +static void serial_rtt_shutdown(FAR struct uart_dev_s *dev); +static int serial_rtt_attach(FAR struct uart_dev_s *dev); +static void serial_rtt_detach(FAR struct uart_dev_s *dev); +static int serial_rtt_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); +static int serial_rtt_receive(FAR struct uart_dev_s *dev, + FAR unsigned int *status); +static void serial_rtt_rxint(FAR struct uart_dev_s *dev, bool enable); +static bool serial_rtt_rxavailable(FAR struct uart_dev_s *dev); +static void serial_rtt_dmasend(FAR struct uart_dev_s *dev); +static void serial_rtt_dmareceive(FAR struct uart_dev_s *dev); +static void serial_rtt_dmarxfree(FAR struct uart_dev_s *dev); +static void serial_rtt_dmatxavail(FAR struct uart_dev_s *dev); +static void serial_rtt_send(FAR struct uart_dev_s *dev, int ch); +static void serial_rtt_txint(FAR struct uart_dev_s *dev, bool enable); +static bool serial_rtt_txready(FAR struct uart_dev_s *dev); +static bool serial_rtt_txempty(FAR struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct list_node g_serial_rtt_list = LIST_INITIAL_VALUE(g_serial_rtt_list); + +static const struct uart_ops_s g_serial_rtt_ops = +{ + serial_rtt_setup, + serial_rtt_shutdown, + serial_rtt_attach, + serial_rtt_detach, + serial_rtt_ioctl, + serial_rtt_receive, + serial_rtt_rxint, + serial_rtt_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, +#endif + serial_rtt_dmasend, + serial_rtt_dmareceive, + serial_rtt_dmarxfree, + serial_rtt_dmatxavail, + serial_rtt_send, + serial_rtt_txint, + serial_rtt_txready, + serial_rtt_txempty, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: serial_rtt_setup + ****************************************************************************/ + +static int serial_rtt_setup(FAR struct uart_dev_s *dev) +{ + return OK; +} + +/**************************************************************************** + * Name: serial_rtt_shutdown + ****************************************************************************/ + +static void serial_rtt_shutdown(FAR struct uart_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: serial_rtt_attach + ****************************************************************************/ + +static int serial_rtt_attach(FAR struct uart_dev_s *dev) +{ + return OK; +} + +/**************************************************************************** + * Name: serial_rtt_detach + ****************************************************************************/ + +static void serial_rtt_detach(FAR struct uart_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: serial_rtt_ioctl + ****************************************************************************/ + +static int serial_rtt_ioctl(FAR struct file *filep, int cmd, + unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: serial_rtt_receive + ****************************************************************************/ + +static int serial_rtt_receive(FAR struct uart_dev_s *dev, + FAR unsigned int *status) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: serial_rtt_rxint + ****************************************************************************/ + +static void serial_rtt_rxint(FAR struct uart_dev_s *dev, bool enable) +{ +} + +/**************************************************************************** + * Name: serial_rtt_rxavailable + ****************************************************************************/ + +static bool serial_rtt_rxavailable(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = + (FAR struct serial_rtt_dev_s *)dev->priv; + return SEGGER_RTT_HasData(rtt->channel) != 0; +} + +/**************************************************************************** + * Name: serial_rtt_dmasend + ****************************************************************************/ + +static void serial_rtt_dmasend(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = + (FAR struct serial_rtt_dev_s *)dev->priv; + FAR SEGGER_RTT_BUFFER_UP *ring = (SEGGER_RTT_BUFFER_UP *)((FAR char *) + &_SEGGER_RTT.aUp[rtt->channel] + SEGGER_RTT_UNCACHED_OFF); + FAR struct uart_dmaxfer_s *xfer = &dev->dmatx; + size_t len = xfer->length + xfer->nlength; + size_t slen = 0; + + if (rtt->channel) + { + ring->WrOff = (ring->WrOff + len) % dev->xmit.size; + } + else + { + slen += SEGGER_RTT_Write(rtt->channel, xfer->buffer, xfer->length); + slen += SEGGER_RTT_Write(rtt->channel, xfer->nbuffer, xfer->nlength); + } + + xfer->nbytes = slen; + uart_xmitchars_done(dev); +} + +/**************************************************************************** + * Name: serial_rtt_dmareceive + ****************************************************************************/ + +static void serial_rtt_dmareceive(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = + (FAR struct serial_rtt_dev_s *)dev->priv; + FAR struct uart_dmaxfer_s *xfer = &dev->dmarx; + FAR SEGGER_RTT_BUFFER_DOWN *ring = (SEGGER_RTT_BUFFER_DOWN *)((FAR char *) + &_SEGGER_RTT.aDown[rtt->channel] + SEGGER_RTT_UNCACHED_OFF); + size_t space = xfer->length + xfer->nlength; + size_t recvlen = 0; + + if (rtt->channel) + { + if (ring->RdOff <= ring->WrOff) + { + recvlen = ring->WrOff - ring->RdOff; + } + else + { + recvlen = ring->SizeOfBuffer - (ring->WrOff - ring->RdOff); + } + + recvlen = (recvlen > space) ? space : recvlen; + ring->RdOff = recvlen; + } + else + { + recvlen += SEGGER_RTT_Read(rtt->channel, xfer->buffer, xfer->length); + if ((recvlen == xfer->length) && SEGGER_RTT_HasData(rtt->channel)) + { + recvlen += SEGGER_RTT_Read(rtt->channel, xfer->nbuffer, + xfer->nlength); + } + } + + xfer->nbytes = recvlen; + uart_recvchars_done(dev); +} + +/**************************************************************************** + * Name: serial_rtt_dmarxfree + ****************************************************************************/ + +static void serial_rtt_dmarxfree(FAR struct uart_dev_s *dev) +{ + /* When the DMA buffer is empty, check whether there is data to read */ + + if (serial_rtt_rxavailable(dev)) Review Comment: if (dev->dmarx.length == 0 && serial_rtt_rxavailable(dev)) ########## drivers/segger/serial_rtt.c: ########## @@ -0,0 +1,380 @@ +/**************************************************************************** + * drivers/segger/serial_rtt.c + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <assert.h> +#include <debug.h> +#include <errno.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#include <nuttx/kmalloc.h> +#include <nuttx/kthread.h> +#include <nuttx/list.h> +#include <nuttx/serial/serial.h> +#include <nuttx/signal.h> + +#include <SEGGER_RTT.h> + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct serial_rtt_dev_s +{ + struct list_node node; + struct uart_dev_s uart; + int channel; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int serial_rtt_setup(FAR struct uart_dev_s *dev); +static void serial_rtt_shutdown(FAR struct uart_dev_s *dev); +static int serial_rtt_attach(FAR struct uart_dev_s *dev); +static void serial_rtt_detach(FAR struct uart_dev_s *dev); +static int serial_rtt_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); +static int serial_rtt_receive(FAR struct uart_dev_s *dev, + FAR unsigned int *status); +static void serial_rtt_rxint(FAR struct uart_dev_s *dev, bool enable); +static bool serial_rtt_rxavailable(FAR struct uart_dev_s *dev); +static void serial_rtt_dmasend(FAR struct uart_dev_s *dev); +static void serial_rtt_dmareceive(FAR struct uart_dev_s *dev); +static void serial_rtt_dmarxfree(FAR struct uart_dev_s *dev); +static void serial_rtt_dmatxavail(FAR struct uart_dev_s *dev); +static void serial_rtt_send(FAR struct uart_dev_s *dev, int ch); +static void serial_rtt_txint(FAR struct uart_dev_s *dev, bool enable); +static bool serial_rtt_txready(FAR struct uart_dev_s *dev); +static bool serial_rtt_txempty(FAR struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct list_node g_serial_rtt_list = LIST_INITIAL_VALUE(g_serial_rtt_list); + +static const struct uart_ops_s g_serial_rtt_ops = +{ + serial_rtt_setup, + serial_rtt_shutdown, + serial_rtt_attach, + serial_rtt_detach, + serial_rtt_ioctl, + serial_rtt_receive, + serial_rtt_rxint, + serial_rtt_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + NULL, +#endif + serial_rtt_dmasend, + serial_rtt_dmareceive, + serial_rtt_dmarxfree, + serial_rtt_dmatxavail, + serial_rtt_send, + serial_rtt_txint, + serial_rtt_txready, + serial_rtt_txempty, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: serial_rtt_setup + ****************************************************************************/ + +static int serial_rtt_setup(FAR struct uart_dev_s *dev) +{ + return OK; +} + +/**************************************************************************** + * Name: serial_rtt_shutdown + ****************************************************************************/ + +static void serial_rtt_shutdown(FAR struct uart_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: serial_rtt_attach + ****************************************************************************/ + +static int serial_rtt_attach(FAR struct uart_dev_s *dev) +{ + return OK; +} + +/**************************************************************************** + * Name: serial_rtt_detach + ****************************************************************************/ + +static void serial_rtt_detach(FAR struct uart_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: serial_rtt_ioctl + ****************************************************************************/ + +static int serial_rtt_ioctl(FAR struct file *filep, int cmd, + unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: serial_rtt_receive + ****************************************************************************/ + +static int serial_rtt_receive(FAR struct uart_dev_s *dev, + FAR unsigned int *status) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: serial_rtt_rxint + ****************************************************************************/ + +static void serial_rtt_rxint(FAR struct uart_dev_s *dev, bool enable) +{ +} + +/**************************************************************************** + * Name: serial_rtt_rxavailable + ****************************************************************************/ + +static bool serial_rtt_rxavailable(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = + (FAR struct serial_rtt_dev_s *)dev->priv; + return SEGGER_RTT_HasData(rtt->channel) != 0; +} + +/**************************************************************************** + * Name: serial_rtt_dmasend + ****************************************************************************/ + +static void serial_rtt_dmasend(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = + (FAR struct serial_rtt_dev_s *)dev->priv; + FAR SEGGER_RTT_BUFFER_UP *ring = (SEGGER_RTT_BUFFER_UP *)((FAR char *) + &_SEGGER_RTT.aUp[rtt->channel] + SEGGER_RTT_UNCACHED_OFF); + FAR struct uart_dmaxfer_s *xfer = &dev->dmatx; + size_t len = xfer->length + xfer->nlength; + size_t slen = 0; + + if (rtt->channel) + { + ring->WrOff = (ring->WrOff + len) % dev->xmit.size; + } + else + { + slen += SEGGER_RTT_Write(rtt->channel, xfer->buffer, xfer->length); + slen += SEGGER_RTT_Write(rtt->channel, xfer->nbuffer, xfer->nlength); + } + + xfer->nbytes = slen; + uart_xmitchars_done(dev); +} + +/**************************************************************************** + * Name: serial_rtt_dmareceive + ****************************************************************************/ + +static void serial_rtt_dmareceive(FAR struct uart_dev_s *dev) +{ + FAR struct serial_rtt_dev_s *rtt = Review Comment: ``` FAR struct serial_rtt_dev_s *rtt = (FAR struct serial_rtt_dev_s *)dev->priv; FAR struct uart_dmaxfer_s *xfer = &dev->dmarx; if (rtt->channel) { FAR SEGGER_RTT_BUFFER_DOWN *ring = (SEGGER_RTT_BUFFER_DOWN *)((FAR char *) &_SEGGER_RTT.aDown[rtt->channel] + SEGGER_RTT_UNCACHED_OFF); ring->RdOff = (ring->RdOff + xfer->length + xfer->nlength) % dev->recv.size; } else { size_t len = SEGGER_RTT_Read(rtt->channel, xfer->buffer, xfer->length); if ((len == xfer->length) && xfer->nlength) { len += SEGGER_RTT_Read(rtt->channel, xfer->nbuffer, xfer->nlength); } xfer->nbytes = len; uart_recvchars_done(dev); } ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org