[RFC v2] rtems: Add options to kernel output char handler
Sebastian Huber
sebastian.huber at embedded-brains.de
Thu Apr 25 09:22:33 UTC 2024
Make the kernel I/O output character device processing configurable
through an option set parameter. Add RTEMS_IO_NO_OUTPUT and
RTEMS_IO_DRAIN options. The goal of this API change is to enable
draining the kernel output device in the system termination process
before a reset is issued. A use case for using RTEMS_NO_WAIT is the
polled processing of an input and output stream from and to the I/O
device.
---
v2:
* Do not use EARS.
* Rename RTEMS_FLUSH in RTEMS_IO_DRAIN.
* Rename RTEMS_NO_OUTPUT in RTEMS_IO_NO_TRANSMISSION.
* Add example adoption for sparc/leon3.
bsps/sparc/leon3/console/printk_support.c | 54 +++++++++++++++++++---
cpukit/include/rtems/bspIo.h | 55 ++++++++++++++++++++++-
cpukit/include/rtems/rtems/options.h | 22 ++++++++-
cpukit/libcsupport/src/rtems_putc.c | 4 +-
testsuites/validation/tc-io-put-char.c | 8 +++-
testsuites/validation/tr-io-kernel.c | 4 +-
6 files changed, 132 insertions(+), 15 deletions(-)
diff --git a/bsps/sparc/leon3/console/printk_support.c b/bsps/sparc/leon3/console/printk_support.c
index fd23a5033f..adfd653060 100644
--- a/bsps/sparc/leon3/console/printk_support.c
+++ b/bsps/sparc/leon3/console/printk_support.c
@@ -43,6 +43,7 @@
#include <bsp/leon3.h>
#include <rtems/bspIo.h>
#include <rtems/sysinit.h>
+#include <rtems/dev/io.h>
#include <grlib/apbuart.h>
#include <grlib/io.h>
@@ -56,6 +57,11 @@ apbuart *leon3_debug_uart = NULL;
static void bsp_debug_uart_init(void);
+static bool apbuart_can_transmit(apbuart *regs)
+{
+ return (grlib_load_32(®s->status) & APBUART_STATUS_TE) != 0;
+}
+
static void apbuart_enable_receive_and_transmit(apbuart *regs)
{
uint32_t ctrl;
@@ -66,10 +72,38 @@ static void apbuart_enable_receive_and_transmit(apbuart *regs)
grlib_store_32(®s->status, 0);
}
-static void bsp_debug_uart_output_char(char c)
+static rtems_status_code bsp_debug_uart_output_char(
+ char c,
+ rtems_option option_set
+)
{
- apbuart_outbyte_polled(leon3_debug_uart, c);
- apbuart_outbyte_wait(leon3_debug_uart);
+ apbuart *regs = leon3_debug_uart;
+ rtems_status_code status = RTEMS_SUCCESSFUL;
+
+ while (true) {
+ if (apbuart_can_transmit(regs)) {
+ if ((option_set & RTEMS_IO_NO_TRANSMISSION) == 0) {
+ grlib_store_32(®s->data, (uint8_t) c);
+ }
+
+ break;
+ }
+
+ if ((option_set & RTEMS_NO_WAIT) != 0) {
+ status = RTEMS_UNSATISFIED;
+ break;
+ }
+
+ _IO_Relax();
+ }
+
+ if ((option_set & RTEMS_IO_DRAIN) != 0) {
+ while (!apbuart_can_transmit(regs)) {
+ _IO_Relax();
+ }
+ }
+
+ return status;
}
static int bsp_debug_uart_poll_char(void)
@@ -77,10 +111,13 @@ static int bsp_debug_uart_poll_char(void)
return apbuart_inbyte_nonblocking(leon3_debug_uart);
}
-static void bsp_debug_uart_pre_init_out(char c)
+static rtems_status_code bsp_debug_uart_pre_init_out(
+ char c,
+ rtems_option option_set
+)
{
bsp_debug_uart_init();
- (*BSP_output_char)(c);
+ return (*BSP_output_char)(c, option_set);
}
#if defined(LEON3_APBUART_BASE)
@@ -94,9 +131,14 @@ static void bsp_debug_uart_init(void)
#else /* !LEON3_APBUART_BASE */
-static void bsp_debug_uart_discard(char c)
+static rtems_status_code bsp_debug_uart_discard(
+ char c,
+ rtems_option option_set
+)
{
(void) c;
+ (void) option_set;
+ return RTEMS_SUCCESSFUL;
}
/* Initialize the BSP system debug console layer. It will scan AMBA Plu&Play
diff --git a/cpukit/include/rtems/bspIo.h b/cpukit/include/rtems/bspIo.h
index 31580cd800..7848704992 100644
--- a/cpukit/include/rtems/bspIo.h
+++ b/cpukit/include/rtems/bspIo.h
@@ -10,7 +10,7 @@
*/
/*
- * Copyright (C) 2020, 2021 embedded brains GmbH & Co. KG
+ * Copyright (C) 2020, 2024 embedded brains GmbH & Co. KG
* Copyright (C) 2015 On-Line Applications Research Corporation (OAR)
*
* Redistribution and use in source and binary forms, with or without
@@ -58,6 +58,8 @@
#define _RTEMS_BSPIO_H
#include <stdarg.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/status.h>
#include <rtems/score/basedefs.h>
#ifdef __cplusplus
@@ -89,8 +91,48 @@ extern "C" {
* @ingroup RTEMSAPIKernelCharIO
*
* @brief Polled character output functions shall have this type.
+ *
+ * @param out is the character to transmit.
+ *
+ * @param option_set is the option set.
+ *
+ * The behaviour of polled character output functions can be controlled by the
+ * three options #RTEMS_NO_WAIT, #RTEMS_IO_NO_TRANSMISSION, and #RTEMS_IO_DRAIN
+ * specified in the ``option_set`` parameter.
+ *
+ * If the #RTEMS_NO_WAIT option is set in the ``option_set`` parameter and the
+ * device cannot immediately accept a character for transmission, then the
+ * character in ``out`` shall not be transmitted by the device, optionally the
+ * device shall be drained, and ::RTEMS_UNSATISFIED shall be returned.
+ *
+ * If the #RTEMS_IO_NO_TRANSMISSION option is set in the ``option_set``
+ * parameter, the character in the ``out`` parameter shall not be transmitted
+ * by the device.
+ *
+ * If the #RTEMS_NO_WAIT and #RTEMS_IO_NO_TRANSMISSION options are cleared in
+ * the ``option_set`` parameter, then the character in the ``out`` parameter
+ * shall transmitted by the device.
+ *
+ * If the #RTEMS_NO_WAIT option is set and the #RTEMS_IO_NO_TRANSMISSION option
+ * is cleared in the ``option_set`` parameter, and the device can immediately
+ * accept a character for transmission, then the character in ``out`` shall be
+ * transmitted by the device.
+ *
+ * If the #RTEMS_IO_DRAIN option is set in the ``option_set`` parameter, then
+ * the device shall be drained before the function returns. Draining the
+ * device should ensure that all characters in transmission are visible to
+ * external consumers. For example, the device transmit FIFO and transmit shift
+ * register should be empty.
+ *
+ * @retval ::RTEMS_SUCCESSFUL The requested operation was successful.
+ *
+ * @retval ::RTEMS_UNSATISFIED The device is was not immediately ready to
+ * transmit a character.
*/
-typedef void ( *BSP_output_char_function_type )( char );
+typedef rtems_status_code ( *BSP_output_char_function_type )(
+ char out,
+ rtems_option option_set
+);
/* Generated from spec:/rtems/io/if/bsp-output-char */
@@ -333,6 +375,15 @@ int rtems_printk_printer( void *unused, const char *fmt, va_list ap );
* @ingroup RTEMSAPIKernelCharIO
*
* @brief Polled character input functions shall have this type.
+ *
+ * If a character is available in the device, then a polled character input
+ * function shall return the least recently received character available in the
+ * device as an unsigned character, otherwise it shall return minus one.
+ *
+ * @retval -1 There was no received character available in the device.
+ *
+ * @return Returns the least recently received character available in the
+ * device as an unsigned character.
*/
typedef int (* BSP_polling_getchar_function_type )( void );
diff --git a/cpukit/include/rtems/rtems/options.h b/cpukit/include/rtems/rtems/options.h
index 44a8d6ccb8..ca6d32639c 100644
--- a/cpukit/include/rtems/rtems/options.h
+++ b/cpukit/include/rtems/rtems/options.h
@@ -9,7 +9,7 @@
*/
/*
- * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ * Copyright (C) 2020, 2024 embedded brains GmbH & Co. KG
* Copyright (C) 1989, 2008 On-Line Applications Research Corporation (OAR)
*
* Redistribution and use in source and binary forms, with or without
@@ -103,6 +103,26 @@ extern "C" {
*/
#define RTEMS_EVENT_ANY 0x00000002
+/* Generated from spec:/rtems/option/if/io-drain */
+
+/**
+ * @ingroup RTEMSAPIClassicOptions
+ *
+ * @brief This option constant indicates that an output device shall be
+ * drained.
+ */
+#define RTEMS_IO_DRAIN 0x00000008
+
+/* Generated from spec:/rtems/option/if/io-no-transmission */
+
+/**
+ * @ingroup RTEMSAPIClassicOptions
+ *
+ * @brief This option constant indicates that nothing shall be transmitted by a
+ * device.
+ */
+#define RTEMS_IO_NO_TRANSMISSION 0x00000004
+
/* Generated from spec:/rtems/option/if/no-wait */
/**
diff --git a/cpukit/libcsupport/src/rtems_putc.c b/cpukit/libcsupport/src/rtems_putc.c
index a9e84c0043..73bd6f1fb1 100644
--- a/cpukit/libcsupport/src/rtems_putc.c
+++ b/cpukit/libcsupport/src/rtems_putc.c
@@ -46,8 +46,8 @@ void rtems_putc( char c )
output_char = BSP_output_char;
if ( c == '\n' ) {
- ( *output_char )( '\r' );
+ (void) ( *output_char )( '\r', RTEMS_DEFAULT_OPTIONS );
}
- ( *output_char )( c );
+ (void) ( *output_char )( c, RTEMS_DEFAULT_OPTIONS );
}
diff --git a/testsuites/validation/tc-io-put-char.c b/testsuites/validation/tc-io-put-char.c
index 671eed9835..7df8d7f3f2 100644
--- a/testsuites/validation/tc-io-put-char.c
+++ b/testsuites/validation/tc-io-put-char.c
@@ -159,16 +159,20 @@ static void Output( int value )
++ctx->output_count;
}
-static void WrongOutput( char c )
+static rtems_status_code WrongOutput( char c, rtems_option option_set )
{
(void) c;
+ (void) option_set;
Output( -1 );
+ return RTEMS_SUCCESSFUL;
}
-static void OutputChar( char c )
+static rtems_status_code OutputChar( char c, rtems_option option_set )
{
+ (void) option_set;
BSP_output_char = WrongOutput;
Output( (unsigned char) c );
+ return RTEMS_SUCCESSFUL;
}
static void RtemsIoReqPutChar_Pre_Char_Prepare(
diff --git a/testsuites/validation/tr-io-kernel.c b/testsuites/validation/tr-io-kernel.c
index bbebfe5a26..99969776b6 100644
--- a/testsuites/validation/tr-io-kernel.c
+++ b/testsuites/validation/tr-io-kernel.c
@@ -83,9 +83,9 @@
static void RtemsIoValKernel_Action_0( void )
{
T_report_hash_sha256_update( 'X' );
- ( *BSP_output_char )( 'X' );
+ (void) ( *BSP_output_char )( 'X', RTEMS_DEFAULT_OPTIONS );
T_report_hash_sha256_update( '\n' );
- ( *BSP_output_char )( '\n' );
+ (void) ( *BSP_output_char )( '\n', RTEMS_DEFAULT_OPTIONS );
}
/**
--
2.35.3
More information about the devel
mailing list