source: rtems/cpukit/libcsupport/src/consolesimpletask.c @ 196ce18

5
Last change on this file since 196ce18 was 196ce18, checked in by Sebastian Huber <sebastian.huber@…>, on 06/21/18 at 10:54:06

console: Add missing return status

Update #3320.

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 * Copyright (c) 2018 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#include <rtems/console.h>
16#include <rtems/bspIo.h>
17#include <rtems/imfs.h>
18#include <rtems/thread.h>
19
20#include "consolesimple.h"
21
22#define CONSOLE_SIMPLE_TASK_BUFFER_SIZE 2048
23
24#define CONSOLE_SIMPLE_TASK_MAX_JUNK_SIZE 80
25
26typedef struct {
27  RTEMS_INTERRUPT_LOCK_MEMBER( buf_lock )
28  rtems_mutex output_mutex;
29  rtems_id task;
30  size_t head;
31  size_t tail;
32  char buf[ CONSOLE_SIMPLE_TASK_BUFFER_SIZE ];
33} Console_simple_task_Control;
34
35static Console_simple_task_Control _Console_simple_task_Instance;
36
37static size_t _Console_simple_task_Capacity(
38  const Console_simple_task_Control *cons
39)
40{
41  return ( cons->tail - cons->head - 1 ) % CONSOLE_SIMPLE_TASK_BUFFER_SIZE;
42}
43
44static size_t _Console_simple_task_Available(
45  const Console_simple_task_Control *cons
46)
47{
48  return ( cons->head - cons->tail ) % CONSOLE_SIMPLE_TASK_BUFFER_SIZE;
49}
50
51static ssize_t _Console_simple_task_Write(
52  rtems_libio_t *iop,
53  const void    *buffer,
54  size_t         count
55)
56{
57  Console_simple_task_Control *cons;
58  const char                  *buf;
59  size_t                       todo;
60
61  cons = IMFS_generic_get_context_by_iop( iop );
62  buf = buffer;
63  todo = count;
64
65  while ( todo > 0 ) {
66    rtems_interrupt_lock_context lock_context;
67    size_t                       junk;
68    size_t                       head;
69    size_t                       i;
70
71    rtems_interrupt_lock_acquire( &cons->buf_lock, &lock_context );
72
73    junk = _Console_simple_task_Capacity( cons );
74
75    if ( junk > todo ) {
76      junk = todo;
77    }
78
79    if ( junk > CONSOLE_SIMPLE_TASK_MAX_JUNK_SIZE ) {
80      junk = CONSOLE_SIMPLE_TASK_MAX_JUNK_SIZE;
81    }
82
83    head = cons->head;
84
85    for ( i = 0; i < junk; ++i ) {
86      cons->buf[ head ] = *buf;
87      head = ( head + 1 ) % CONSOLE_SIMPLE_TASK_BUFFER_SIZE;
88      --todo;
89      ++buf;
90    }
91
92    cons->head = head;
93
94    rtems_interrupt_lock_release( &cons->buf_lock, &lock_context );
95
96    if ( junk == 0 ) {
97      break;
98    }
99  }
100
101  rtems_event_system_send( cons->task, RTEMS_EVENT_SYSTEM_SERVER );
102
103  return (ssize_t) ( count - todo );
104}
105
106static void _Console_simple_task_Put_chars( Console_simple_task_Control *cons )
107{
108  rtems_interrupt_lock_context lock_context;
109  size_t                       available;
110  size_t                       tail;
111  size_t                       i;
112
113  rtems_mutex_lock( &cons->output_mutex );
114
115  rtems_interrupt_lock_acquire( &cons->buf_lock, &lock_context );
116
117  available = _Console_simple_task_Available( cons );
118  tail = cons->tail;
119
120  rtems_interrupt_lock_release( &cons->buf_lock, &lock_context );
121
122  for ( i = 0; i < available; ++i) {
123    rtems_putc( cons->buf[ tail ] );
124    tail = ( tail + 1 ) % CONSOLE_SIMPLE_TASK_BUFFER_SIZE;
125  }
126
127  rtems_interrupt_lock_acquire( &cons->buf_lock, &lock_context );
128
129  cons->tail = tail;
130
131  rtems_interrupt_lock_release( &cons->buf_lock, &lock_context );
132
133  rtems_mutex_unlock( &cons->output_mutex );
134}
135
136static int _Console_simple_task_Fsync( rtems_libio_t *iop )
137{
138  Console_simple_task_Control *cons;
139
140  cons = IMFS_generic_get_context_by_iop( iop );
141  _Console_simple_task_Put_chars( cons );
142
143  return 0;
144}
145
146static const rtems_filesystem_file_handlers_r _Console_simple_task_Handlers = {
147  .open_h = rtems_filesystem_default_open,
148  .close_h = rtems_filesystem_default_close,
149  .read_h = _Console_simple_Read,
150  .write_h = _Console_simple_task_Write,
151  .ioctl_h = rtems_filesystem_default_ioctl,
152  .lseek_h = rtems_filesystem_default_lseek,
153  .fstat_h = IMFS_stat,
154  .ftruncate_h = rtems_filesystem_default_ftruncate,
155  .fsync_h = _Console_simple_task_Fsync,
156  .fdatasync_h = _Console_simple_task_Fsync,
157  .fcntl_h = rtems_filesystem_default_fcntl,
158  .readv_h = rtems_filesystem_default_readv,
159  .writev_h = rtems_filesystem_default_writev,
160  .mmap_h = rtems_filesystem_default_mmap
161};
162
163static const IMFS_node_control
164_Console_simple_task_Node_control = IMFS_GENERIC_INITIALIZER(
165  &_Console_simple_task_Handlers,
166  IMFS_node_initialize_generic,
167  IMFS_node_destroy_default
168);
169
170static void _Console_simple_task_Task( rtems_task_argument arg )
171{
172  Console_simple_task_Control *cons;
173
174  cons = (Console_simple_task_Control *) arg;
175
176  while ( true ) {
177    rtems_event_set events;
178
179    rtems_event_system_receive(
180      RTEMS_EVENT_SYSTEM_SERVER,
181      RTEMS_WAIT | RTEMS_EVENT_ALL,
182      RTEMS_NO_TIMEOUT,
183      &events
184    );
185
186    _Console_simple_task_Put_chars( cons );
187  }
188}
189
190void _Console_simple_task_Initialize( void )
191{
192  Console_simple_task_Control *cons;
193
194  cons = &_Console_simple_task_Instance;
195
196  rtems_interrupt_lock_initialize( &cons->buf_lock, "Console" );
197  rtems_mutex_init( &cons->output_mutex, "Console" );
198
199  IMFS_make_generic_node(
200    CONSOLE_DEVICE_NAME,
201    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
202    &_Console_simple_task_Node_control,
203    cons
204  );
205
206  rtems_task_create(
207    rtems_build_name('C', 'O', 'N', 'S'),
208    RTEMS_MAXIMUM_PRIORITY - 1,
209    RTEMS_MINIMUM_STACK_SIZE,
210    RTEMS_DEFAULT_ATTRIBUTES,
211    RTEMS_DEFAULT_MODES,
212    &cons->task
213  );
214
215  rtems_task_start(
216    cons->task,
217    _Console_simple_task_Task,
218    (rtems_task_argument) cons
219  );
220}
Note: See TracBrowser for help on using the repository browser.