[rtems commit] bsp/xilinx-zynq: Use new Termios device driver

Sebastian Huber sebh at rtems.org
Tue Feb 21 11:12:49 UTC 2017


Module:    rtems
Branch:    master
Commit:    6b2fcc40ac8013d37e4c8aa4ea162316e2388ada
Changeset: http://git.rtems.org/rtems/commit/?id=6b2fcc40ac8013d37e4c8aa4ea162316e2388ada

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Feb 21 10:30:30 2017 +0100

bsp/xilinx-zynq: Use new Termios device driver

---

 c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am       |   7 +-
 .../arm/xilinx-zynq/console/console-config.c       | 100 +++++++--------------
 .../libbsp/arm/xilinx-zynq/console/debug-console.c |  68 ++++++++++++++
 .../lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c |  94 +++++++++----------
 .../arm/xilinx-zynq/include/zynq-uart-regs.h       |   2 +-
 .../lib/libbsp/arm/xilinx-zynq/include/zynq-uart.h |  27 +++++-
 .../lib/libbsp/arm/xilinx-zynq/startup/bspreset.c  |   6 +-
 7 files changed, 168 insertions(+), 136 deletions(-)

diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am b/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am
index 8e6f8c3..1f9ed59 100644
--- a/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am
+++ b/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am
@@ -106,12 +106,9 @@ libbsp_a_SOURCES += ../../shared/src/irq-shell.c
 libbsp_a_SOURCES += ../shared/arm-gic-irq.c
 
 # Console
-libbsp_a_SOURCES += ../../shared/console.c
-libbsp_a_SOURCES += ../../shared/console_control.c
-libbsp_a_SOURCES += ../../shared/console_read.c
-libbsp_a_SOURCES += ../../shared/console_select_simple.c
-libbsp_a_SOURCES += ../../shared/console_write.c
+libbsp_a_SOURCES += ../../shared/console-termios.c
 libbsp_a_SOURCES += console/console-config.c
+libbsp_a_SOURCES += console/debug-console.c
 libbsp_a_SOURCES += console/zynq-uart.c
 
 # Clock
diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/console/console-config.c b/c/src/lib/libbsp/arm/xilinx-zynq/console/console-config.c
index 94e5e4f..ce7da2f 100644
--- a/c/src/lib/libbsp/arm/xilinx-zynq/console/console-config.c
+++ b/c/src/lib/libbsp/arm/xilinx-zynq/console/console-config.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2013, 2017 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -12,89 +12,51 @@
  * http://www.rtems.org/license/LICENSE.
  */
 
-#include <libchip/serial.h>
-
+#include <rtems/console.h>
 #include <rtems/bspIo.h>
 
-#include <bsp.h>
 #include <bsp/irq.h>
 #include <bsp/zynq-uart.h>
 
-console_tbl Console_Configuration_Ports[] = {
+#include <bspopts.h>
+
+zynq_uart_context zynq_uart_instances[2] = {
   {
-    .sDeviceName = "/dev/ttyS0",
-    .deviceType = SERIAL_CUSTOM,
-    .pDeviceFns = &zynq_uart_fns,
-    .deviceProbe = NULL,
-    .pDeviceFlow = NULL,
-    .ulMargin = 0,
-    .ulHysteresis = 0,
-    .pDeviceParams = (void *) 115200,
-    .ulCtrlPort1 = 0xe0000000,
-    .ulCtrlPort2 = 0,
-    .ulDataPort = 0,
-    .getRegister = NULL,
-    .setRegister = NULL,
-    .getData = NULL,
-    .setData = NULL,
-    .ulClock = 0,
-    .ulIntVector = ZYNQ_IRQ_UART_0
+    .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 0" ),
+    .regs = (volatile struct zynq_uart *) 0xe0000000,
+    .irq = ZYNQ_IRQ_UART_0
   }, {
-    .sDeviceName = "/dev/ttyS1",
-    .deviceType = SERIAL_CUSTOM,
-    .pDeviceFns = &zynq_uart_fns,
-    .deviceProbe = NULL,
-    .pDeviceFlow = NULL,
-    .ulMargin = 0,
-    .ulHysteresis = 0,
-    .pDeviceParams = (void *) 115200,
-    .ulCtrlPort1 = 0xe0001000,
-    .ulCtrlPort2 = 0,
-    .ulDataPort = 0,
-    .getRegister = NULL,
-    .setRegister = NULL,
-    .getData = NULL,
-    .setData = NULL,
-    .ulClock = 0,
-    .ulIntVector = ZYNQ_IRQ_UART_1
+    .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 1" ),
+    .regs = (volatile struct zynq_uart *) 0xe0001000,
+    .irq = ZYNQ_IRQ_UART_1
   }
 };
 
-unsigned long Console_Configuration_Count =
-  RTEMS_ARRAY_SIZE(Console_Configuration_Ports);
-
-static void output_char(char c)
+rtems_status_code console_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *arg
+)
 {
-  int minor = (int) Console_Port_Minor;
-  const console_tbl *ct = Console_Port_Tbl != NULL ?
-    Console_Port_Tbl[minor] : &Console_Configuration_Ports[minor];
-  const console_fns *cf = ct->pDeviceFns;
-
-  if (c == '\n') {
-    (*cf->deviceWritePolled)(minor, '\r');
-  }
+  size_t i;
 
-  (*cf->deviceWritePolled)(minor, c);
-}
-
-static void output_char_init(char c)
-{
-  if (Console_Port_Tbl == NULL) {
-    int minor;
-    const console_fns *cf;
+  rtems_termios_initialize();
 
-    bsp_console_select();
+  for (i = 0; i < RTEMS_ARRAY_SIZE(zynq_uart_instances); ++i) {
+    char uart[] = "/dev/ttySX";
 
-    minor = (int) Console_Port_Minor;
-    cf = Console_Configuration_Ports[minor].pDeviceFns;
+    uart[sizeof(uart) - 2] = (char) ('0' + i);
+    rtems_termios_device_install(
+      &uart[0],
+      &zynq_uart_handler,
+      NULL,
+      &zynq_uart_instances[i].base
+    );
 
-    (*cf->deviceInitialize)(minor);
+    if (i == BSP_CONSOLE_MINOR) {
+      link(&uart[0], CONSOLE_DEVICE_NAME);
+    }
   }
 
-  BSP_output_char = output_char;
-  output_char(c);
+  return RTEMS_SUCCESSFUL;
 }
-
-BSP_output_char_function_type BSP_output_char = output_char_init;
-
-BSP_polling_getchar_function_type BSP_poll_char = NULL;
diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/console/debug-console.c b/c/src/lib/libbsp/arm/xilinx-zynq/console/debug-console.c
new file mode 100644
index 0000000..887a7ea
--- /dev/null
+++ b/c/src/lib/libbsp/arm/xilinx-zynq/console/debug-console.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2013, 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/bspIo.h>
+#include <rtems/sysinit.h>
+
+#include <bsp/zynq-uart.h>
+
+#include <bspopts.h>
+
+static void zynq_debug_console_out(char c)
+{
+  rtems_termios_device_context *base =
+    &zynq_uart_instances[BSP_CONSOLE_MINOR].base;
+
+  if (c == '\n') {
+    zynq_uart_write_polled(base, '\r');
+  }
+
+  zynq_uart_write_polled(base, c);
+}
+
+static void zynq_debug_console_init(void)
+{
+  rtems_termios_device_context *base =
+    &zynq_uart_instances[BSP_CONSOLE_MINOR].base;
+
+  zynq_uart_initialize(base);
+  BSP_output_char = zynq_debug_console_out;
+}
+
+static void zynq_debug_console_early_init(char c)
+{
+  rtems_termios_device_context *base =
+    &zynq_uart_instances[BSP_CONSOLE_MINOR].base;
+
+  zynq_uart_initialize(base);
+  zynq_debug_console_out(c);
+}
+
+static int zynq_debug_console_in(void)
+{
+  rtems_termios_device_context *base =
+    &zynq_uart_instances[BSP_CONSOLE_MINOR].base;
+
+  return zynq_uart_read_polled(base);
+}
+
+BSP_output_char_function_type BSP_output_char = zynq_debug_console_early_init;
+
+BSP_polling_getchar_function_type BSP_poll_char = zynq_debug_console_in;
+
+RTEMS_SYSINIT_ITEM(
+  zynq_debug_console_init,
+  RTEMS_SYSINIT_BSP_START,
+  RTEMS_SYSINIT_ORDER_LAST
+);
diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c b/c/src/lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c
index f9a1cf9..05c8e54 100644
--- a/c/src/lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c
+++ b/c/src/lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2013, 2017 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -17,16 +17,6 @@
 
 #include <bspopts.h>
 
-#include <libchip/sersupp.h>
-
-static volatile zynq_uart *zynq_uart_get_regs(int minor)
-{
-  const console_tbl *ct = Console_Port_Tbl != NULL ?
-    Console_Port_Tbl[minor] : &Console_Configuration_Ports[minor];
-
-  return (volatile zynq_uart *) ct->ulCtrlPort1;
-}
-
 /*
  * Make weak and let the user override.
  */
@@ -112,13 +102,14 @@ static int zynq_cal_baud_rate(uint32_t  baudrate,
   return 0;
 }
 
-static void zynq_uart_initialize(int minor)
+void zynq_uart_initialize(rtems_termios_device_context *base)
 {
-  volatile zynq_uart *regs = zynq_uart_get_regs(minor);
+  zynq_uart_context *ctx = (zynq_uart_context *) base;
+  volatile zynq_uart *regs = ctx->regs;
   uint32_t brgr = 0x3e;
   uint32_t bauddiv = 0x6;
 
-  zynq_cal_baud_rate(115200, &brgr, &bauddiv, regs->mode);
+  zynq_cal_baud_rate(ZYNQ_UART_DEFAULT_BAUD, &brgr, &bauddiv, regs->mode);
 
   regs->control &= ~(ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN);
   regs->control = ZYNQ_UART_CONTROL_RXDIS
@@ -137,27 +128,23 @@ static void zynq_uart_initialize(int minor)
     | ZYNQ_UART_CONTROL_RSTTO;
 }
 
-static int zynq_uart_first_open(int major, int minor, void *arg)
+static bool zynq_uart_first_open(
+  rtems_termios_tty *tty,
+  rtems_termios_device_context *base,
+  struct termios *term,
+  rtems_libio_open_close_args_t *args
+)
 {
-  rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg;
-  struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1;
-  console_data *cd = &Console_Port_Data[minor];
-  const console_tbl *ct = Console_Port_Tbl[minor];
-
-  cd->termios_data = tty;
-  rtems_termios_set_initial_baud(tty, (rtems_termios_baud_t) ct->pDeviceParams);
-
-  return 0;
-}
+  rtems_termios_set_initial_baud(tty, ZYNQ_UART_DEFAULT_BAUD);
+  zynq_uart_initialize(base);
 
-static int zynq_uart_last_close(int major, int minor, void *arg)
-{
-  return 0;
+  return true;
 }
 
-static int zynq_uart_read_polled(int minor)
+int zynq_uart_read_polled(rtems_termios_device_context *base)
 {
-  volatile zynq_uart *regs = zynq_uart_get_regs(minor);
+  zynq_uart_context *ctx = (zynq_uart_context *) base;
+  volatile zynq_uart *regs = ctx->regs;
 
   if ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) != 0) {
     return -1;
@@ -166,9 +153,13 @@ static int zynq_uart_read_polled(int minor)
   }
 }
 
-static void zynq_uart_write_polled(int minor, char c)
+void zynq_uart_write_polled(
+  rtems_termios_device_context *base,
+  char c
+)
 {
-  volatile zynq_uart *regs = zynq_uart_get_regs(minor);
+  zynq_uart_context *ctx = (zynq_uart_context *) base;
+  volatile zynq_uart *regs = ctx->regs;
 
   while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TFUL) != 0) {
     /* Wait */
@@ -177,8 +168,8 @@ static void zynq_uart_write_polled(int minor, char c)
   regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(c);
 }
 
-static ssize_t zynq_uart_write_support_polled(
-  int minor,
+static void zynq_uart_write_support_polled(
+  rtems_termios_device_context *base,
   const char *s,
   size_t n
 )
@@ -186,13 +177,14 @@ static ssize_t zynq_uart_write_support_polled(
   ssize_t i = 0;
 
   for (i = 0; i < n; ++i) {
-    zynq_uart_write_polled(minor, s[i]);
+    zynq_uart_write_polled(base, s[i]);
   }
-
-  return n;
 }
 
-static int zynq_uart_set_attribues(int minor, const struct termios *term)
+static bool zynq_uart_set_attributes(
+  rtems_termios_device_context *context,
+  const struct termios *term
+)
 {
 #if 0
   volatile zynq_uart *regs = zynq_uart_get_regs(minor);
@@ -209,31 +201,27 @@ static int zynq_uart_set_attribues(int minor, const struct termios *term)
   regs->baud_rate_div = ZYNQ_UART_BAUD_RATE_DIV_BDIV(bauddiv);
   regs->control |= ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN;
 
-  return 0;
+  return true;
 #else
-  return -1;
+  return false;
 #endif
 }
 
-const console_fns zynq_uart_fns = {
-  .deviceProbe = libchip_serial_default_probe,
-  .deviceFirstOpen = zynq_uart_first_open,
-  .deviceLastClose = zynq_uart_last_close,
-  .deviceRead = zynq_uart_read_polled,
-  .deviceWrite = zynq_uart_write_support_polled,
-  .deviceInitialize = zynq_uart_initialize,
-  .deviceWritePolled = zynq_uart_write_polled,
-  .deviceSetAttributes = zynq_uart_set_attribues,
-  .deviceOutputUsesInterrupts = false
+const rtems_termios_device_handler zynq_uart_handler = {
+  .first_open = zynq_uart_first_open,
+  .write = zynq_uart_write_support_polled,
+  .poll_read = zynq_uart_read_polled,
+  .set_attributes = zynq_uart_set_attributes,
+  .mode = TERMIOS_POLLED
 };
 
-void zynq_uart_reset_tx_flush(int minor)
+void zynq_uart_reset_tx_flush(zynq_uart_context *ctx)
 {
-  volatile zynq_uart *regs = zynq_uart_get_regs(minor);
+  volatile zynq_uart *regs = ctx->regs;
   int                 c = 4;
 
   while (c-- > 0)
-    zynq_uart_write_polled(minor, '\r');
+    zynq_uart_write_polled(&ctx->base, '\r');
 
   while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) == 0) {
     /* Wait */
diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart-regs.h b/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart-regs.h
index f8f902b..e72b93a 100644
--- a/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart-regs.h
+++ b/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart-regs.h
@@ -30,7 +30,7 @@
 
 #include <bsp/utility.h>
 
-typedef struct {
+typedef struct zynq_uart {
 	uint32_t control;
 #define ZYNQ_UART_CONTROL_STPBRK BSP_BIT32(8)
 #define ZYNQ_UART_CONTROL_STTBRK BSP_BIT32(7)
diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart.h b/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart.h
index 07c883a..57412d7 100644
--- a/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart.h
+++ b/c/src/lib/libbsp/arm/xilinx-zynq/include/zynq-uart.h
@@ -5,7 +5,7 @@
  */
 
 /*
- * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2013, 2017 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -21,7 +21,7 @@
 #ifndef LIBBSP_ARM_XILINX_ZYNQ_UART_H
 #define LIBBSP_ARM_XILINX_ZYNQ_UART_H
 
-#include <libchip/serial.h>
+#include <rtems/termiostypes.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -33,12 +33,31 @@ extern "C" {
  * @brief UART Support
  */
 
-extern const console_fns zynq_uart_fns;
+typedef struct {
+  rtems_termios_device_context base;
+  volatile struct zynq_uart *regs;
+  rtems_vector_number irq;
+} zynq_uart_context;
+
+const rtems_termios_device_handler zynq_uart_handler;
+
+extern zynq_uart_context zynq_uart_instances[2];
+
+#define ZYNQ_UART_DEFAULT_BAUD 115200
+
+void zynq_uart_initialize(rtems_termios_device_context *base);
+
+int zynq_uart_read_polled(rtems_termios_device_context *base);
+
+void zynq_uart_write_polled(
+  rtems_termios_device_context *base,
+  char c
+);
 
 /**
   * Flush TX FIFO and wait until it is empty. Used in bsp_reset.
   */
-void zynq_uart_reset_tx_flush(int minor);
+void zynq_uart_reset_tx_flush(zynq_uart_context *ctx);
 
 #ifdef __cplusplus
 }
diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/startup/bspreset.c b/c/src/lib/libbsp/arm/xilinx-zynq/startup/bspreset.c
index f86d1f3..b57354c 100644
--- a/c/src/lib/libbsp/arm/xilinx-zynq/startup/bspreset.c
+++ b/c/src/lib/libbsp/arm/xilinx-zynq/startup/bspreset.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2013, 2017 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -21,9 +21,7 @@ void bsp_reset(void)
   volatile uint32_t *slcr_unlock = (volatile uint32_t *) 0xf8000008;
   volatile uint32_t *pss_rst_ctrl = (volatile uint32_t *) 0xf8000200;
 
-  if (Console_Port_Tbl != NULL) {
-    zynq_uart_reset_tx_flush((int) Console_Port_Minor);
-  }
+  zynq_uart_reset_tx_flush(&zynq_uart_instances[BSP_CONSOLE_MINOR]);
 
   while (true) {
     *slcr_unlock = 0xdf0d;




More information about the vc mailing list