You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2021/01/24 20:20:10 UTC

[GitHub] [incubator-nuttx] acassis opened a new pull request #2736: Add generic support to LWL Console

acassis opened a new pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736


   ## Summary
   Add generic support to LWL Console
   ## Impact
   Avoid creating a new LWL driver for each arch
   ## Testing
   STM32F4DISCOVERY
   


----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r564090345



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))

Review comment:
       Done!




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#issuecomment-767262825


   @acassis LGTM now, could you squash the patches into one?


----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r563452813



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>

Review comment:
       remove syscall.h and nuttx/arch.h, both should not used.

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318

Review comment:
       add LWL_ prefix?

##########
File path: drivers/Kconfig
##########
@@ -24,6 +24,22 @@ config DRVR_MKRD
 		the selecting this option will also enable the BOARDIOC_MKRD
 		command that will support creation of RAM disks from applications.
 
+# ARCH needs to support memory access while CPU is running to be able to use
+# the LWL CONSOLE
+
+config ARCH_HAVE_RDWR_MEM_CPU_RUN

Review comment:
       should we remove arm version?
   https://github.com/apache/incubator-nuttx/blob/master/arch/arm/src/common/arm_lwl_console.c

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;

Review comment:
       how to handle the host transfer the data more than one byte?

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))

Review comment:
       why not change to while here and remove the loop from lwlconsole_read to make it like writeword?

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);

Review comment:
       remove LWL_DNSENSE(g_d.upword) | ?

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;
+
+  /* Flip the bit to indicate the datum is read */
+
+  g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_ioctl
+ ****************************************************************************/
+
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_read
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen)
+{
+  if (buflen == 0 || !linkactive())
+    {
+      return 0;
+    }
+
+  while (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))
+    {
+    }
+
+  return 1;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_write
+ ****************************************************************************/
+
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen)
+{
+  uint32_t oc = 0;
+
+  while (buflen)
+    {
+      switch (buflen)
+        {
+          case 0:
+            return oc;
+
+          case 1:
+            if (write8bits(LWL_PORT_CONSOLE, buffer[0]))
+              {
+                oc++;
+                buffer++;
+                buflen--;
+              }
+            break;
+
+          case 2:
+            if (write16bits(LWL_PORT_CONSOLE, buffer[0] | (buffer[1] << 8)))
+              {
+                oc += 2;
+                buffer += 2;
+                buflen -= 2;
+              }
+            break;
+
+          default:
+            if (write24bits(LWL_PORT_CONSOLE, buffer[0] |
+                            (buffer[1] << 8) | (buffer[2] << 16)))
+              {
+                oc += 3;
+                buffer += 3;
+                buflen -= 3;
+              }
+            break;
+        }
+    }
+
+  return oc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lwlconsole_init
+ ****************************************************************************/
+
+void lwlconsole_init(void)
+{
+  g_d.upword = 0;

Review comment:
       don't need?

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;
+
+  /* Flip the bit to indicate the datum is read */
+
+  g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_ioctl
+ ****************************************************************************/
+
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_read
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen)
+{
+  if (buflen == 0 || !linkactive())

Review comment:
       move linkactive to read8bits like writeword

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,

Review comment:
       add FAR for all pointer




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r564190459



##########
File path: drivers/lwl_console.c
##########
@@ -208,11 +208,17 @@ static bool write24bits(uint8_t port, uint32_t val)
 
 static bool read8bits(uint8_t port, uint8_t * store)

Review comment:
       add FAR

##########
File path: drivers/lwl_console.c
##########
@@ -235,16 +242,17 @@ static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
  * Name: lwlconsole_read
  ****************************************************************************/
 
-static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+static ssize_t lwlconsole_read(FAR struct file *filep, FAR char *buffer,
                                size_t buflen)
 {
-  if (buflen == 0 || !linkactive())
+  if (buflen == 0)
     {
       return 0;
     }
 
-  while (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))
+  if (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))

Review comment:
       add FAR 




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r564082610



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;
+
+  /* Flip the bit to indicate the datum is read */
+
+  g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_ioctl
+ ****************************************************************************/
+
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_read
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen)
+{
+  if (buflen == 0 || !linkactive())
+    {
+      return 0;
+    }
+
+  while (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))
+    {
+    }
+
+  return 1;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_write
+ ****************************************************************************/
+
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen)
+{
+  uint32_t oc = 0;
+
+  while (buflen)
+    {
+      switch (buflen)
+        {
+          case 0:
+            return oc;
+
+          case 1:
+            if (write8bits(LWL_PORT_CONSOLE, buffer[0]))
+              {
+                oc++;
+                buffer++;
+                buflen--;
+              }
+            break;
+
+          case 2:
+            if (write16bits(LWL_PORT_CONSOLE, buffer[0] | (buffer[1] << 8)))
+              {
+                oc += 2;
+                buffer += 2;
+                buflen -= 2;
+              }
+            break;
+
+          default:
+            if (write24bits(LWL_PORT_CONSOLE, buffer[0] |
+                            (buffer[1] << 8) | (buffer[2] << 16)))
+              {
+                oc += 3;
+                buffer += 3;
+                buflen -= 3;
+              }
+            break;
+        }
+    }
+
+  return oc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lwlconsole_init
+ ****************************************************************************/
+
+void lwlconsole_init(void)

Review comment:
       Ok, I put it on drivers/drivers.h




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r563452813



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>

Review comment:
       remove syscall.h and nuttx/arch.h, both should not used.

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318

Review comment:
       add LWL_ prefix?

##########
File path: drivers/Kconfig
##########
@@ -24,6 +24,22 @@ config DRVR_MKRD
 		the selecting this option will also enable the BOARDIOC_MKRD
 		command that will support creation of RAM disks from applications.
 
+# ARCH needs to support memory access while CPU is running to be able to use
+# the LWL CONSOLE
+
+config ARCH_HAVE_RDWR_MEM_CPU_RUN

Review comment:
       should we remove arm version?
   https://github.com/apache/incubator-nuttx/blob/master/arch/arm/src/common/arm_lwl_console.c

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;

Review comment:
       how to handle the host transfer the data more than one byte?

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))

Review comment:
       why not change to while here and remove the loop from lwlconsole_read to make it like writeword?

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);

Review comment:
       remove LWL_DNSENSE(g_d.upword) | ?

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;
+
+  /* Flip the bit to indicate the datum is read */
+
+  g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_ioctl
+ ****************************************************************************/
+
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_read
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen)
+{
+  if (buflen == 0 || !linkactive())
+    {
+      return 0;
+    }
+
+  while (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))
+    {
+    }
+
+  return 1;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_write
+ ****************************************************************************/
+
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen)
+{
+  uint32_t oc = 0;
+
+  while (buflen)
+    {
+      switch (buflen)
+        {
+          case 0:
+            return oc;
+
+          case 1:
+            if (write8bits(LWL_PORT_CONSOLE, buffer[0]))
+              {
+                oc++;
+                buffer++;
+                buflen--;
+              }
+            break;
+
+          case 2:
+            if (write16bits(LWL_PORT_CONSOLE, buffer[0] | (buffer[1] << 8)))
+              {
+                oc += 2;
+                buffer += 2;
+                buflen -= 2;
+              }
+            break;
+
+          default:
+            if (write24bits(LWL_PORT_CONSOLE, buffer[0] |
+                            (buffer[1] << 8) | (buffer[2] << 16)))
+              {
+                oc += 3;
+                buffer += 3;
+                buflen -= 3;
+              }
+            break;
+        }
+    }
+
+  return oc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lwlconsole_init
+ ****************************************************************************/
+
+void lwlconsole_init(void)
+{
+  g_d.upword = 0;

Review comment:
       don't need?

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;
+
+  /* Flip the bit to indicate the datum is read */
+
+  g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_ioctl
+ ****************************************************************************/
+
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_read
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen)
+{
+  if (buflen == 0 || !linkactive())

Review comment:
       move linkactive to read8bits like writeword

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,

Review comment:
       add FAR for all pointer

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;
+
+  /* Flip the bit to indicate the datum is read */
+
+  g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_ioctl
+ ****************************************************************************/
+
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_read
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen)
+{
+  if (buflen == 0 || !linkactive())
+    {
+      return 0;
+    }
+
+  while (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))
+    {
+    }
+
+  return 1;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_write
+ ****************************************************************************/
+
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen)
+{
+  uint32_t oc = 0;
+
+  while (buflen)
+    {
+      switch (buflen)
+        {
+          case 0:
+            return oc;
+
+          case 1:
+            if (write8bits(LWL_PORT_CONSOLE, buffer[0]))
+              {
+                oc++;
+                buffer++;
+                buflen--;
+              }
+            break;
+
+          case 2:
+            if (write16bits(LWL_PORT_CONSOLE, buffer[0] | (buffer[1] << 8)))
+              {
+                oc += 2;
+                buffer += 2;
+                buflen -= 2;
+              }
+            break;
+
+          default:
+            if (write24bits(LWL_PORT_CONSOLE, buffer[0] |
+                            (buffer[1] << 8) | (buffer[2] << 16)))
+              {
+                oc += 3;
+                buffer += 3;
+                buflen -= 3;
+              }
+            break;
+        }
+    }
+
+  return oc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lwlconsole_init
+ ****************************************************************************/
+
+void lwlconsole_init(void)

Review comment:
       need add a public header file or put into drivers/drivers.h for lwlconsole_init declaration.

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);

Review comment:
       Yes, you are right.

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;

Review comment:
       Ok, let wait more feedback from user.

##########
File path: drivers/lwl_console.c
##########
@@ -208,11 +208,17 @@ static bool write24bits(uint8_t port, uint32_t val)
 
 static bool read8bits(uint8_t port, uint8_t * store)

Review comment:
       add FAR

##########
File path: drivers/lwl_console.c
##########
@@ -235,16 +242,17 @@ static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
  * Name: lwlconsole_read
  ****************************************************************************/
 
-static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+static ssize_t lwlconsole_read(FAR struct file *filep, FAR char *buffer,
                                size_t buflen)
 {
-  if (buflen == 0 || !linkactive())
+  if (buflen == 0)
     {
       return 0;
     }
 
-  while (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))
+  if (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))

Review comment:
       add FAR 




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r564660809



##########
File path: drivers/lwl_console.c
##########
@@ -235,16 +242,17 @@ static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
  * Name: lwlconsole_read
  ****************************************************************************/
 
-static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+static ssize_t lwlconsole_read(FAR struct file *filep, FAR char *buffer,
                                size_t buflen)
 {
-  if (buflen == 0 || !linkactive())
+  if (buflen == 0)
     {
       return 0;
     }
 
-  while (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))
+  if (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))

Review comment:
       done




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r563698983



##########
File path: drivers/Kconfig
##########
@@ -24,6 +24,22 @@ config DRVR_MKRD
 		the selecting this option will also enable the BOARDIOC_MKRD
 		command that will support creation of RAM disks from applications.
 
+# ARCH needs to support memory access while CPU is running to be able to use
+# the LWL CONSOLE
+
+config ARCH_HAVE_RDWR_MEM_CPU_RUN

Review comment:
       Yes, it is a separated commit, I don't want to mix the generic driver with arch specific code/modifications. Let's focus in the generic LWL driver, the next commit will remove the arch driver, enable the ARCH_HAVE_RDWR_MEM_CPU_RUN and replace CONFIG_ARM_LWL_CONSOLE with CONFIG_LWL_CONSOLE.




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r563668593



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318

Review comment:
       Ok




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r563455576



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;
+
+  /* Flip the bit to indicate the datum is read */
+
+  g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_ioctl
+ ****************************************************************************/
+
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_read
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen)
+{
+  if (buflen == 0 || !linkactive())
+    {
+      return 0;
+    }
+
+  while (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))
+    {
+    }
+
+  return 1;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_write
+ ****************************************************************************/
+
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen)
+{
+  uint32_t oc = 0;
+
+  while (buflen)
+    {
+      switch (buflen)
+        {
+          case 0:
+            return oc;
+
+          case 1:
+            if (write8bits(LWL_PORT_CONSOLE, buffer[0]))
+              {
+                oc++;
+                buffer++;
+                buflen--;
+              }
+            break;
+
+          case 2:
+            if (write16bits(LWL_PORT_CONSOLE, buffer[0] | (buffer[1] << 8)))
+              {
+                oc += 2;
+                buffer += 2;
+                buflen -= 2;
+              }
+            break;
+
+          default:
+            if (write24bits(LWL_PORT_CONSOLE, buffer[0] |
+                            (buffer[1] << 8) | (buffer[2] << 16)))
+              {
+                oc += 3;
+                buffer += 3;
+                buflen -= 3;
+              }
+            break;
+        }
+    }
+
+  return oc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lwlconsole_init
+ ****************************************************************************/
+
+void lwlconsole_init(void)

Review comment:
       need add a public header file or put into drivers/drivers.h for lwlconsole_init declaration.




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#issuecomment-767262825


   @acassis LGTM now, could you squash the patches into one?


----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 merged pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 merged pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736


   


----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#issuecomment-767673153


   > @acassis LGTM now, could you squash the patches into one?
   
   done!


----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r563668676



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>

Review comment:
       Ok




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r563676594



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);

Review comment:
       This bit is checked in the read function to verify that the data was read or still new.
   
   Then after the read the bit
   ```
     /* Flip the bit to indicate the datum is read */
     g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
   ```
   
   Both upword and downword have DNSENSE bit and UPSENSE bit.




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r564090197



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;
+
+  /* Flip the bit to indicate the datum is read */
+
+  g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_ioctl
+ ****************************************************************************/
+
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_read
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen)
+{
+  if (buflen == 0 || !linkactive())

Review comment:
       Done!




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r563711965



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;

Review comment:
       Ok, let wait more feedback from user.




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r563668593



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318

Review comment:
       Ok

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>

Review comment:
       Ok

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,

Review comment:
       Ok

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);

Review comment:
       This bit is checked in the read function to verify that the data was read or still new.
   
   Then after the read the bit
   ```
     /* Flip the bit to indicate the datum is read */
     g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
   ```
   
   Both upword and downword have DNSENSE bit and UPSENSE bit.

##########
File path: drivers/Kconfig
##########
@@ -24,6 +24,22 @@ config DRVR_MKRD
 		the selecting this option will also enable the BOARDIOC_MKRD
 		command that will support creation of RAM disks from applications.
 
+# ARCH needs to support memory access while CPU is running to be able to use
+# the LWL CONSOLE
+
+config ARCH_HAVE_RDWR_MEM_CPU_RUN

Review comment:
       Yes, it is a separated commit, I don't want to mix the generic driver with arch specific code/modifications. Let's focus in the generic LWL driver, the next commit will remove the arch driver, enable the ARCH_HAVE_RDWR_MEM_CPU_RUN and replace CONFIG_ARM_LWL_CONSOLE with CONFIG_LWL_CONSOLE.

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;

Review comment:
       I think Dave Marples created it this way because normally the user will type only a keystroke by time. In the other hand the result of a typed command could be many bytes to be returned to the user.

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;
+
+  /* Flip the bit to indicate the datum is read */
+
+  g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_ioctl
+ ****************************************************************************/
+
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_read
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen)
+{
+  if (buflen == 0 || !linkactive())
+    {
+      return 0;
+    }
+
+  while (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))
+    {
+    }
+
+  return 1;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_write
+ ****************************************************************************/
+
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen)
+{
+  uint32_t oc = 0;
+
+  while (buflen)
+    {
+      switch (buflen)
+        {
+          case 0:
+            return oc;
+
+          case 1:
+            if (write8bits(LWL_PORT_CONSOLE, buffer[0]))
+              {
+                oc++;
+                buffer++;
+                buflen--;
+              }
+            break;
+
+          case 2:
+            if (write16bits(LWL_PORT_CONSOLE, buffer[0] | (buffer[1] << 8)))
+              {
+                oc += 2;
+                buffer += 2;
+                buflen -= 2;
+              }
+            break;
+
+          default:
+            if (write24bits(LWL_PORT_CONSOLE, buffer[0] |
+                            (buffer[1] << 8) | (buffer[2] << 16)))
+              {
+                oc += 3;
+                buffer += 3;
+                buflen -= 3;
+              }
+            break;
+        }
+    }
+
+  return oc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lwlconsole_init
+ ****************************************************************************/
+
+void lwlconsole_init(void)
+{
+  g_d.upword = 0;

Review comment:
       Ok

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;
+
+  /* Flip the bit to indicate the datum is read */
+
+  g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_ioctl
+ ****************************************************************************/
+
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_read
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen)
+{
+  if (buflen == 0 || !linkactive())
+    {
+      return 0;
+    }
+
+  while (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))
+    {
+    }
+
+  return 1;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_write
+ ****************************************************************************/
+
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen)
+{
+  uint32_t oc = 0;
+
+  while (buflen)
+    {
+      switch (buflen)
+        {
+          case 0:
+            return oc;
+
+          case 1:
+            if (write8bits(LWL_PORT_CONSOLE, buffer[0]))
+              {
+                oc++;
+                buffer++;
+                buflen--;
+              }
+            break;
+
+          case 2:
+            if (write16bits(LWL_PORT_CONSOLE, buffer[0] | (buffer[1] << 8)))
+              {
+                oc += 2;
+                buffer += 2;
+                buflen -= 2;
+              }
+            break;
+
+          default:
+            if (write24bits(LWL_PORT_CONSOLE, buffer[0] |
+                            (buffer[1] << 8) | (buffer[2] << 16)))
+              {
+                oc += 3;
+                buffer += 3;
+                buflen -= 3;
+              }
+            break;
+        }
+    }
+
+  return oc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lwlconsole_init
+ ****************************************************************************/
+
+void lwlconsole_init(void)

Review comment:
       Ok, I put it on drivers/drivers.h

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;
+
+  /* Flip the bit to indicate the datum is read */
+
+  g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_ioctl
+ ****************************************************************************/
+
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_read
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen)
+{
+  if (buflen == 0 || !linkactive())

Review comment:
       Done!

##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))

Review comment:
       Done!




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r564663171



##########
File path: drivers/lwl_console.c
##########
@@ -208,11 +208,17 @@ static bool write24bits(uint8_t port, uint32_t val)
 
 static bool read8bits(uint8_t port, uint8_t * store)

Review comment:
       done




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r563688713



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);

Review comment:
       Yes, you are right.




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r563668773



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,

Review comment:
       Ok




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r563706928



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;

Review comment:
       I think Dave Marples created it this way because normally the user will type only a keystroke by time. In the other hand the result of a typed command could be many bytes to be returned to the user.




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #2736: Add generic support to LWL Console

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #2736:
URL: https://github.com/apache/incubator-nuttx/pull/2736#discussion_r564079555



##########
File path: drivers/lwl_console.c
##########
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * drivers/lwlconsole.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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <syscall.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication.  On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A   31    1 - Service Active (Set by host)
+ * D   30    1 - Downsense (Toggled when there is data)
+ * U   29    1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV  28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A   31    1 - Service Active (Set by device)
+ * D   30    1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ *               data)
+ * U   29    1 - Upsense (Toggled when there is data)
+ * VV  28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2  23-16 8 - Octet 2
+ * O1  15-08 8 - Octet 1
+ * O0  07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct lwl_entry_s
+{
+  uint32_t sig;               /* Location signature */
+  volatile uint32_t downword; /* Host to Target word */
+  uint32_t upword;            /* Target to Host word */
+};
+
+static struct lwl_entry_s g_d =
+{
+  .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+  NULL,                       /* open */
+  NULL,                       /* close */
+  lwlconsole_read,            /* read */
+  lwlconsole_write,           /* write */
+  NULL,                       /* seek */
+  lwlconsole_ioctl,           /* ioctl */
+  NULL                        /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+    ,
+  NULL                        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+  return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+  /* Check link is active */
+
+  if (!linkactive())
+    {
+      return false;
+    }
+
+  /* Spin waiting for previous data to be collected */
+
+  while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+    {
+    }
+
+  /* Load new data, toggling UPSENSE bit to show it is new */
+
+  g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+               (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+  return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+                       LWL_PORT(port) | (val & 0xff);
+
+  return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+                       LWL_PORT(port) | (val & 0xffff);
+
+  return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+  /* Prepare new word */
+
+  uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+                       LWL_PORT(port) | (val & 0xffffff);
+
+  return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+  if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+    {
+      return false;
+    }
+
+  *store = g_d.downword & 255;
+
+  /* Flip the bit to indicate the datum is read */
+
+  g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_ioctl
+ ****************************************************************************/
+
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_read
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+                               size_t buflen)
+{
+  if (buflen == 0 || !linkactive())
+    {
+      return 0;
+    }
+
+  while (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))
+    {
+    }
+
+  return 1;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_write
+ ****************************************************************************/
+
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+                                size_t buflen)
+{
+  uint32_t oc = 0;
+
+  while (buflen)
+    {
+      switch (buflen)
+        {
+          case 0:
+            return oc;
+
+          case 1:
+            if (write8bits(LWL_PORT_CONSOLE, buffer[0]))
+              {
+                oc++;
+                buffer++;
+                buflen--;
+              }
+            break;
+
+          case 2:
+            if (write16bits(LWL_PORT_CONSOLE, buffer[0] | (buffer[1] << 8)))
+              {
+                oc += 2;
+                buffer += 2;
+                buflen -= 2;
+              }
+            break;
+
+          default:
+            if (write24bits(LWL_PORT_CONSOLE, buffer[0] |
+                            (buffer[1] << 8) | (buffer[2] << 16)))
+              {
+                oc += 3;
+                buffer += 3;
+                buflen -= 3;
+              }
+            break;
+        }
+    }
+
+  return oc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lwlconsole_init
+ ****************************************************************************/
+
+void lwlconsole_init(void)
+{
+  g_d.upword = 0;

Review comment:
       Ok




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org