source: rtems/cpukit/libcsupport/include/rtems/termiostypes.h @ 55e0be36

5
Last change on this file since 55e0be36 was 55e0be36, checked in by Sebastian Huber <sebastian.huber@…>, on 09/16/16 at 10:58:06

termios: Use IMFS nodes for new Termios devices

This makes the new Termios devices independent of device major/minor
numbers. It enables BSP independent Termios device drivers which may
reside in the cpukit domain. These drivers require an IMFS and do not
work with the device file system. However, the device file system
should go away in the future.

  • Property mode set to 100644
File size: 13.3 KB
Line 
1/**
2 * @file rtems/termiostypes.h
3 *
4 * RTEMS termios device support internal data structures
5 */
6
7/*
8 *  COPYRIGHT (c) 1989-2011.
9 *  On-Line Applications Research Corporation (OAR).
10 *
11 *  The license and distribution terms for this file may be
12 *  found in the file LICENSE in this distribution or at
13 *  http://www.rtems.org/license/LICENSE.
14 */
15
16#ifndef  __TERMIOSTYPES_H
17#define  __TERMIOSTYPES_H
18
19#include <rtems.h>
20#include <rtems/libio.h>
21#include <rtems/assoc.h>
22#include <rtems/chain.h>
23#include <stdint.h>
24#include <termios.h>
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30/**
31 *  @defgroup TermiostypesSupport RTEMS Termios Device Support
32 *
33 *  @ingroup libcsupport
34 *
35 *  @brief RTEMS Termios Device Support Internal Data Structures
36 */
37
38/*
39 * Wakeup callback data structure
40 */
41struct ttywakeup {
42  void      (*sw_pfn)(struct termios *tty, void *arg);
43  void      *sw_arg;
44};
45
46/*
47 * Variables associated with the character buffer
48 */
49struct rtems_termios_rawbuf {
50  char *theBuf;
51  volatile unsigned int  Head;
52  volatile unsigned int  Tail;
53  volatile unsigned int  Size;
54  rtems_id    Semaphore;
55};
56
57typedef enum {
58  TERMIOS_POLLED,
59  TERMIOS_IRQ_DRIVEN,
60  TERMIOS_TASK_DRIVEN
61} rtems_termios_device_mode;
62
63struct rtems_termios_tty;
64
65/**
66 * @brief Termios device context.
67 *
68 * @see RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER(),
69 * rtems_termios_device_context_initialize() and
70 * rtems_termios_device_install().
71 */
72typedef struct rtems_termios_device_context {
73  rtems_interrupt_lock interrupt_lock;
74} rtems_termios_device_context;
75
76/**
77 * @brief Initializes a device context.
78 *
79 * @param[in] context The Termios device context.
80 * @param[in] name The name for the interrupt lock.  This name must be a
81 *   string persistent throughout the life time of this lock.  The name is only
82 *   used if profiling is enabled.
83 */
84RTEMS_INLINE_ROUTINE void rtems_termios_device_context_initialize(
85  rtems_termios_device_context *context,
86  const char                   *name
87)
88{
89  rtems_interrupt_lock_initialize( &context->interrupt_lock, name );
90}
91
92/**
93 * @brief Initializer for static initialization of Termios device contexts.
94 *
95 * @param name The name for the interrupt lock.  It must be a string.  The name
96 *   is only used if profiling is enabled.
97 */
98#define RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( name ) \
99  { RTEMS_INTERRUPT_LOCK_INITIALIZER( name ) }
100
101/**
102 * @brief Termios device handler.
103 *
104 * @see rtems_termios_device_install().
105 */
106typedef struct {
107  /**
108   * @brief First open of this device.
109   *
110   * @param[in] tty The Termios control.  This parameter may be passed to
111   *   interrupt service routines since it must be provided for the
112   *   rtems_termios_enqueue_raw_characters() and
113   *   rtems_termios_dequeue_characters() functions.
114   * @param[in] context The Termios device context.
115   * @param[in] term The current Termios attributes.
116   * @param[in] args The open/close arguments.  This is parameter provided to
117   *   support legacy drivers.  It must not be used by new drivers.
118   *
119   * @retval true Successful operation.
120   * @retval false Cannot open device.
121   *
122   * @see rtems_termios_get_device_context() and rtems_termios_set_best_baud().
123   */
124  bool (*first_open)(
125    struct rtems_termios_tty      *tty,
126    rtems_termios_device_context  *context,
127    struct termios                *term,
128    rtems_libio_open_close_args_t *args
129  );
130
131  /**
132   * @brief Last close of this device.
133   *
134   * @param[in] tty The Termios control.
135   * @param[in] context The Termios device context.
136   * @param[in] args The open/close arguments.  This is parameter provided to
137   *   support legacy drivers.  It must not be used by new drivers.
138   */
139  void (*last_close)(
140    struct rtems_termios_tty      *tty,
141    rtems_termios_device_context  *context,
142    rtems_libio_open_close_args_t *args
143  );
144
145  /**
146   * @brief Polled read.
147   *
148   * In case mode is TERMIOS_IRQ_DRIVEN or TERMIOS_TASK_DRIVEN, then data is
149   * received via rtems_termios_enqueue_raw_characters().
150   *
151   * @param[in] context The Termios device context.
152   *
153   * @retval char The received data encoded as unsigned char.
154   * @retval -1 No data currently available.
155   */
156  int (*poll_read)(rtems_termios_device_context *context);
157
158  /**
159   * @brief Polled write in case mode is TERMIOS_POLLED or write support
160   * otherwise.
161   *
162   * @param[in] context The Termios device context.
163   * @param[in] buf The output buffer.
164   * @param[in] len The output buffer length in characters.
165   */
166  void (*write)(
167    rtems_termios_device_context *context,
168    const char *buf,
169    size_t len
170  );
171
172  /**
173   * @brief Set attributes after a Termios settings change.
174   *
175   * @param[in] context The Termios device context.
176   * @param[in] term The new Termios attributes.
177   *
178   * @retval true Successful operation.
179   * @retval false Invalid attributes.
180   */
181  bool (*set_attributes)(
182    rtems_termios_device_context *context,
183    const struct termios         *term
184  );
185
186  /**
187   * @brief Termios device mode.
188   */
189  rtems_termios_device_mode mode;
190} rtems_termios_device_handler;
191
192/**
193 * @brief Termios device flow control handler.
194 *
195 * @see rtems_termios_device_install().
196 */
197typedef struct {
198  /**
199   * @brief Indicate to stop remote transmitter.
200   *
201   * @param[in] context The Termios device context.
202   */
203  void (*stop_remote_tx)(rtems_termios_device_context *context);
204
205  /**
206   * @brief Indicate to start remote transmitter.
207   *
208   * @param[in] context The Termios device context.
209   */
210  void (*start_remote_tx)(rtems_termios_device_context *context);
211} rtems_termios_device_flow;
212
213/**
214 * @brief Termios device node for installed devices.
215 *
216 * @see rtems_termios_device_install().
217 */
218typedef struct rtems_termios_device_node {
219  rtems_chain_node                    node;
220  rtems_device_major_number           major;
221  rtems_device_minor_number           minor;
222  const rtems_termios_device_handler *handler;
223  const rtems_termios_device_flow    *flow;
224  rtems_termios_device_context       *context;
225  struct rtems_termios_tty           *tty;
226} rtems_termios_device_node;
227
228/*
229 * Variables associated with each termios instance.
230 * One structure for each hardware I/O device.
231 */
232typedef struct rtems_termios_tty {
233  /*
234   * Linked-list of active TERMIOS devices
235   */
236  struct rtems_termios_tty  *forw;
237  struct rtems_termios_tty  *back;
238
239  /*
240   * How many times has this device been opened
241   */
242  int    refcount;
243
244  /*
245   * This device
246   */
247  rtems_device_major_number  major;
248  rtems_device_minor_number  minor;
249
250  /*
251   * Mutual-exclusion semaphores
252   */
253  rtems_id  isem;
254  rtems_id  osem;
255
256  /*
257   * The canonical (cooked) character buffer
258   */
259  char    *cbuf;
260  int    ccount;
261  int    cindex;
262
263  /*
264   * Keep track of cursor (printhead) position
265   */
266  int    column;
267  int    read_start_column;
268
269  /*
270   * The ioctl settings
271   */
272  struct termios  termios;
273  rtems_interval  vtimeTicks;
274
275  /*
276   * Raw input character buffer
277   */
278  struct rtems_termios_rawbuf rawInBuf;
279  uint32_t                    rawInBufSemaphoreOptions;
280  rtems_interval              rawInBufSemaphoreTimeout;
281  rtems_interval              rawInBufSemaphoreFirstTimeout;
282  unsigned int                rawInBufDropped;  /* Statistics */
283
284  /*
285   * Raw output character buffer
286   */
287  struct rtems_termios_rawbuf rawOutBuf;
288  int  t_dqlen; /* count of characters dequeued from device */
289  enum {rob_idle, rob_busy, rob_wait }  rawOutBufState;
290
291  /*
292   * Callbacks to device-specific routines
293   */
294  rtems_termios_callbacks  device;
295
296  /**
297   * @brief Context for legacy devices using the callbacks.
298   */
299  rtems_termios_device_context legacy_device_context;
300
301  /**
302   * @brief The device handler.
303   */
304  rtems_termios_device_handler handler;
305
306  /**
307   * @brief The device flow control handler.
308   */
309  rtems_termios_device_flow flow;
310
311  volatile unsigned int    flow_ctrl;
312  unsigned int             lowwater,highwater;
313
314  /*
315   * I/O task IDs (for task-driven drivers)
316   */
317  rtems_id                rxTaskId;
318  rtems_id                txTaskId;
319
320  /*
321   * line discipline related stuff
322   */
323  int t_line;   /* id of line discipline                       */
324  void *t_sc;   /* hook for discipline-specific data structure */
325
326  /*
327   * Wakeup callback variables
328   */
329  struct ttywakeup tty_snd;
330  struct ttywakeup tty_rcv;
331  int              tty_rcvwakeup;
332
333  /**
334   * @brief Corresponding device node.
335   */
336  rtems_termios_device_node *device_node;
337
338  /**
339   * @brief Context for device driver.
340   */
341  rtems_termios_device_context *device_context;
342} rtems_termios_tty;
343
344/**
345 * @brief Installs a Termios device.
346 *
347 * The installed Termios device may be removed via unlink().
348 *
349 * @param[in] device_file The device file path.
350 * @param[in] handler The device handler.  It must be persistent throughout the
351 *   installed time of the device.
352 * @param[in] flow The device flow control handler.  The device flow control
353 *   handler are optional and may be @c NULL.  If present must be persistent
354 *   throughout the installed time of the device.
355 * @param[in] context The device context.  It must be persistent throughout the
356 *   installed time of the device.
357 *
358 * @retval RTEMS_SUCCESSFUL Successful operation.
359 * @retval RTEMS_NO_MEMORY Not enough memory to create a device node.
360 * @retval RTEMS_UNSATISFIED Creation of the device file failed.
361 * @retval RTEMS_INCORRECT_STATE Termios is not initialized.
362 *
363 * @see rtems_termios_get_device_context().
364 */
365rtems_status_code rtems_termios_device_install(
366  const char                         *device_file,
367  const rtems_termios_device_handler *handler,
368  const rtems_termios_device_flow    *flow,
369  rtems_termios_device_context       *context
370);
371
372/**
373 * @brief Returns the device context of an installed Termios device.
374 *
375 * @param[in] tty The Termios control.
376 */
377RTEMS_INLINE_ROUTINE void *rtems_termios_get_device_context(
378  const rtems_termios_tty *tty
379)
380{
381  return tty->device_context;
382}
383
384/**
385 * @brief Acquires the device lock.
386 *
387 * @param[in] context The device context.
388 * @param[in] lock_context The local interrupt lock context for an acquire and
389 *   release pair.
390 */
391RTEMS_INLINE_ROUTINE void rtems_termios_device_lock_acquire(
392  rtems_termios_device_context *context,
393  rtems_interrupt_lock_context *lock_context
394)
395{
396  rtems_interrupt_lock_acquire( &context->interrupt_lock, lock_context );
397}
398
399/**
400 * @brief Releases the device lock.
401 *
402 * @param[in] context The device context.
403 * @param[in] lock_context The local interrupt lock context for an acquire and
404 *   release pair.
405 */
406RTEMS_INLINE_ROUTINE void rtems_termios_device_lock_release(
407  rtems_termios_device_context *context,
408  rtems_interrupt_lock_context *lock_context
409)
410{
411  rtems_interrupt_lock_release( &context->interrupt_lock, lock_context );
412}
413
414/**
415 * @brief Sets the best baud value in the Termios control.
416 *
417 * The valid Termios baud values are between 0 and 460800.  The Termios baud
418 * value is chosen which minimizes the difference to the value specified.
419 *
420 * @param[in] term The Termios attributes.
421 * @param[in] baud The current baud setting of the device.
422 */
423void rtems_termios_set_best_baud(
424  struct termios *term,
425  uint32_t        baud
426);
427
428struct rtems_termios_linesw {
429  int (*l_open) (struct rtems_termios_tty *tp);
430  int (*l_close)(struct rtems_termios_tty *tp);
431  int (*l_read )(struct rtems_termios_tty *tp,rtems_libio_rw_args_t *args);
432  int (*l_write)(struct rtems_termios_tty *tp,rtems_libio_rw_args_t *args);
433  int (*l_rint )(int c,struct rtems_termios_tty *tp);
434  int (*l_start)(struct rtems_termios_tty *tp);
435  int (*l_ioctl)(struct rtems_termios_tty *tp,rtems_libio_ioctl_args_t *args);
436  int (*l_modem)(struct rtems_termios_tty *tp,int flags);
437};
438
439/*
440 * FIXME: this should move to termios.h!
441 */
442void rtems_termios_rxirq_occured(struct rtems_termios_tty *tty);
443
444/*
445 * FIXME: this should move to termios.h!
446 * put a string to output ring buffer
447 */
448void rtems_termios_puts (
449  const void               *buf,
450  size_t                    len,
451  struct rtems_termios_tty *tty
452);
453
454/*
455 * global hooks for line disciplines
456 */
457extern struct rtems_termios_linesw rtems_termios_linesw[];
458extern int   rtems_termios_nlinesw;
459
460#define TTYDISC   0    /* termios tty line discipline */
461#define TABLDISC  3    /* tablet discipline */
462#define SLIPDISC  4    /* serial IP discipline */
463#define PPPDISC   5    /* PPP discipline */
464#define MAXLDISC  8
465
466/* baudrate xxx integer type */
467typedef uint32_t rtems_termios_baud_t;
468
469/**
470 *  @brief RTEMS Termios Baud Table
471 */
472extern const rtems_assoc_t rtems_termios_baud_table [];
473
474/**
475 *  @brief Converts the Integral Baud value @a baud to the Termios Control Flag
476 *  Representation
477 *
478 *  @retval B0 Invalid baud value or a baud value of 0.
479 *  @retval other Baud constant according to @a baud.
480 */
481tcflag_t rtems_termios_number_to_baud(rtems_termios_baud_t baud);
482
483/**
484 *  @brief Convert Baud Part of Termios control flags to an integral Baud Value
485 *
486 *  There is no need to mask the @a c_cflag with @c CBAUD.
487 *
488 *  @retval 0 Invalid baud value or a baud value of @c B0.
489 *  @retval other Integral baud value.
490 */
491rtems_termios_baud_t rtems_termios_baud_to_number(tcflag_t c_cflag);
492
493/**
494 *  @brief Convert Bxxx Constant to Index
495 */
496int  rtems_termios_baud_to_index(rtems_termios_baud_t termios_baud);
497
498/**
499 * @brief Sets the initial @a baud in the Termios context @a tty.
500 *
501 * @retval 0 Successful operation.
502 * @retval -1 Invalid baud value.
503 */
504int rtems_termios_set_initial_baud(
505  struct rtems_termios_tty *tty,
506  rtems_termios_baud_t baud
507);
508
509#ifdef __cplusplus
510}
511#endif
512
513#endif  /* TERMIOSTYPES_H */
Note: See TracBrowser for help on using the repository browser.