Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:13

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSPrintSupport
0007  *
0008  * @brief User print interface to the bspIO print plug in.
0009  *
0010  * This include file defines the user interface to kernel print methods.
0011  */
0012 
0013 /*
0014  *  Copyright (c) 2016 Chris Johns <chrisj@rtems.org>
0015  *  All rights reserved.
0016  *
0017  * Redistribution and use in source and binary forms, with or without
0018  * modification, are permitted provided that the following conditions
0019  * are met:
0020  * 1. Redistributions of source code must retain the above copyright
0021  *    notice, this list of conditions and the following disclaimer.
0022  * 2. Redistributions in binary form must reproduce the above copyright
0023  *    notice, this list of conditions and the following disclaimer in the
0024  *    documentation and/or other materials provided with the distribution.
0025  *
0026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0036  * POSSIBILITY OF SUCH DAMAGE.
0037  */
0038 
0039 #ifndef _RTEMS_PRINTER_H
0040 #define _RTEMS_PRINTER_H
0041 
0042 #include <rtems/print.h>
0043 #include <rtems/chain.h>
0044 #include <rtems/rtems/intr.h>
0045 #include <rtems/rtems/tasks.h>
0046 
0047 #include <stdio.h>
0048 #include <string.h>
0049 
0050 #ifdef __cplusplus
0051 extern "C" {
0052 #endif
0053 
0054 /**
0055  * @addtogroup RTEMSPrintSupport
0056  *
0057  * @{
0058  */
0059 
0060 /**
0061  * Type definition for function which can be plugged in to certain reporting
0062  * routines to redirect the output.
0063  *
0064  * Use the RTEMS Print interface to call these functions. Do not directly use
0065  * them.
0066  *
0067  * If the user provides their own printer, then they may redirect those reports
0068  * as they see fit.
0069  */
0070 typedef int (*rtems_print_printer)(void *, const char *format, va_list ap);
0071 
0072 /**
0073  * Type definition for the printer structure used to access the kernel print
0074  * support.
0075  */
0076 struct rtems_printer {
0077   void                *context;
0078   rtems_print_printer  printer;
0079 };
0080 
0081 /**
0082  * @brief check if the printer is valid.
0083  *
0084  * @param[in] printer Pointer to the printer structure.
0085  *
0086  * @return true The printer is valid else false is returned.
0087  */
0088 static inline bool rtems_print_printer_valid(const rtems_printer *printer)
0089 {
0090   return printer != NULL && printer->printer != NULL;
0091 }
0092 
0093 /**
0094  * @brief Initializes the printer to print nothing.
0095  *
0096  * An empty printer prints nothing. You can use this to implement an enable and
0097  * disable type print implementation.
0098  *
0099  * @param[in] printer Pointer to the printer structure.
0100  */
0101 static inline void rtems_print_printer_empty(rtems_printer *printer)
0102 {
0103   printer->context = NULL;
0104   printer->printer = NULL;
0105 }
0106 
0107 /**
0108  * @brief Initializes the printer to print via printk().
0109  *
0110  * @param[in] printer Pointer to the printer structure.
0111  */
0112 void rtems_print_printer_printk(rtems_printer *printer);
0113 
0114 /**
0115  * @brief Initializes the printer to print via printf().
0116  *
0117  * @param[in] printer Pointer to the printer structure.
0118  */
0119 void rtems_print_printer_printf(rtems_printer *printer);
0120 
0121 /**
0122  * @brief Initializes the printer to print via fprintf() using the specified
0123  * file stream.
0124  *
0125  * @param[in] printer Pointer to the printer structure.
0126  */
0127 void rtems_print_printer_fprintf(rtems_printer *printer, FILE *file);
0128 
0129 /**
0130  * @brief Initializes the printer to print via fprintf() using an unbuffered
0131  * FILE stream with output through rtems_putc().
0132  *
0133  * @param[in] printer Pointer to the printer structure.
0134  */
0135 void rtems_print_printer_fprintf_putc(rtems_printer *printer);
0136 
0137 typedef struct {
0138   rtems_id                     task;
0139   RTEMS_INTERRUPT_LOCK_MEMBER( lock )
0140   rtems_chain_control          free_buffers;
0141   rtems_chain_control          todo_buffers;
0142   size_t                       task_stack_size;
0143   rtems_task_priority          task_priority;
0144   int                          fd;
0145   void                        *buffer_table;
0146   size_t                       buffer_count;
0147   size_t                       buffer_size;
0148 } rtems_printer_task_context;
0149 
0150 static inline void rtems_printer_task_initialize(
0151   rtems_printer_task_context *context
0152 )
0153 {
0154   /*
0155    * Some C++ compiler think that the structure is complex enough to need a
0156    * proper constructor. Cast to void * to silence a warning.
0157    */
0158   memset( (void *) context, 0, sizeof( *context ) );
0159 }
0160 
0161 static inline void rtems_printer_task_set_stack_size(
0162   rtems_printer_task_context *context,
0163   size_t                    stack_size
0164 )
0165 {
0166   context->task_stack_size = stack_size;
0167 }
0168 
0169 static inline void rtems_printer_task_set_priority(
0170   rtems_printer_task_context *context,
0171   rtems_task_priority       priority
0172 )
0173 {
0174   context->task_priority = priority;
0175 }
0176 
0177 static inline void rtems_printer_task_set_file_descriptor(
0178   rtems_printer_task_context *context,
0179   int                       fd
0180 )
0181 {
0182   context->fd = fd;
0183 }
0184 
0185 static inline void rtems_printer_task_set_buffer_table(
0186   rtems_printer_task_context *context,
0187   void                     *buffer_table
0188 )
0189 {
0190   context->buffer_table = buffer_table;
0191 }
0192 
0193 static inline void rtems_printer_task_set_buffer_count(
0194   rtems_printer_task_context *context,
0195   size_t                    buffer_count
0196 )
0197 {
0198   context->buffer_count = buffer_count;
0199 }
0200 
0201 static inline void rtems_printer_task_set_buffer_size(
0202   rtems_printer_task_context *context,
0203   size_t                    buffer_size
0204 )
0205 {
0206   context->buffer_size = buffer_size;
0207 }
0208 
0209 /**
0210  * @brief Creates a printer task.
0211  *
0212  * Print requests via rtems_printf() or rtems_vprintf() using a printer task
0213  * printer are output to a buffer and then placed on a work queue in FIFO
0214  * order.  The work queue is emptied by the printer task.  The printer task
0215  * writes the buffer content to the file descriptor specified by the context.
0216  * Buffers are allocated from a pool of buffers as specified by the context.
0217  *
0218  * @param[in] printer Pointer to the printer structure.
0219  * @param[in] context The initialized printer task context.
0220  *
0221  * @retval 0 Successful operation.
0222  * @retval EINVAL Invalid context parameters.
0223  * @retval ENOMEM Not enough resources.
0224  */
0225 int rtems_print_printer_task(
0226   rtems_printer              *printer,
0227   rtems_printer_task_context *context
0228 );
0229 
0230 /**
0231  * @brief Drains the work queue of the printer task.
0232  *
0233  * Waits until all output buffers in the work queue at the time of this
0234  * function call are written to the file descriptor and an fsync() completed.
0235  *
0236  * The printer task must be successfully started via rtems_print_printer_task()
0237  * before this function can be used.  Otherwise, the behaviour is undefined.
0238  *
0239  * @param[in] context The printer task context of a successfully started
0240  *   printer task.
0241  */
0242 void rtems_printer_task_drain(rtems_printer_task_context *context);
0243 
0244 /** @} */
0245 
0246 #ifdef __cplusplus
0247 }
0248 #endif
0249 
0250 #endif /* _RTEMS_PRINTER_H */