source: rtems/cpukit/libcsupport/src/consolesimpletask.c @ 337a186

5
Last change on this file since 337a186 was 337a186, checked in by Sebastian Huber <sebastian.huber@…>, on 02/21/18 at 11:40:18

Add a simple task console driver

Close #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
144static const rtems_filesystem_file_handlers_r _Console_simple_task_Handlers = {
145  .open_h = rtems_filesystem_default_open,
146  .close_h = rtems_filesystem_default_close,
147  .read_h = _Console_simple_Read,
148  .write_h = _Console_simple_task_Write,
149  .ioctl_h = rtems_filesystem_default_ioctl,
150  .lseek_h = rtems_filesystem_default_lseek,
151  .fstat_h = IMFS_stat,
152  .ftruncate_h = rtems_filesystem_default_ftruncate,
153  .fsync_h = _Console_simple_task_Fsync,
154  .fdatasync_h = _Console_simple_task_Fsync,
155  .fcntl_h = rtems_filesystem_default_fcntl,
156  .readv_h = rtems_filesystem_default_readv,
157  .writev_h = rtems_filesystem_default_writev,
158  .mmap_h = rtems_filesystem_default_mmap
159};
160
161static const IMFS_node_control
162_Console_simple_task_Node_control = IMFS_GENERIC_INITIALIZER(
163  &_Console_simple_task_Handlers,
164  IMFS_node_initialize_generic,
165  IMFS_node_destroy_default
166);
167
168static void _Console_simple_task_Task( rtems_task_argument arg )
169{
170  Console_simple_task_Control *cons;
171
172  cons = (Console_simple_task_Control *) arg;
173
174  while ( true ) {
175    rtems_event_set events;
176
177    rtems_event_system_receive(
178      RTEMS_EVENT_SYSTEM_SERVER,
179      RTEMS_WAIT | RTEMS_EVENT_ALL,
180      RTEMS_NO_TIMEOUT,
181      &events
182    );
183
184    _Console_simple_task_Put_chars( cons );
185  }
186}
187
188void _Console_simple_task_Initialize( void )
189{
190  Console_simple_task_Control *cons;
191
192  cons = &_Console_simple_task_Instance;
193
194  rtems_interrupt_lock_initialize( &cons->buf_lock, "Console" );
195  rtems_mutex_init( &cons->output_mutex, "Console" );
196
197  IMFS_make_generic_node(
198    CONSOLE_DEVICE_NAME,
199    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
200    &_Console_simple_task_Node_control,
201    cons
202  );
203
204  rtems_task_create(
205    rtems_build_name('C', 'O', 'N', 'S'),
206    RTEMS_MAXIMUM_PRIORITY - 1,
207    RTEMS_MINIMUM_STACK_SIZE,
208    RTEMS_DEFAULT_ATTRIBUTES,
209    RTEMS_DEFAULT_MODES,
210    &cons->task
211  );
212
213  rtems_task_start(
214    cons->task,
215    _Console_simple_task_Task,
216    (rtems_task_argument) cons
217  );
218}
Note: See TracBrowser for help on using the repository browser.