source: rtems-docs/bsp-howto/frame_buffer.rst @ 362ae68

5
Last change on this file since 362ae68 was e52906b, checked in by Sebastian Huber <sebastian.huber@…>, on 01/09/19 at 15:14:06

Simplify SPDX-License-Identifier comment

  • Property mode set to 100644
File size: 8.4 KB
Line 
1.. SPDX-License-Identifier: CC-BY-SA-4.0
2
3.. Copyright (C) 1988, 2002 On-Line Applications Research Corporation (OAR)
4
5Frame Buffer Driver
6*******************
7
8In this chapter, we present the basic functionality implemented by a frame
9buffer driver:
10
11- ``frame_buffer_initialize()``
12- ``frame_buffer_open()``
13- ``frame_buffer_close()``
14- ``frame_buffer_read()``
15- ``frame_buffer_write()``
16- ``frame_buffer_control()``
17
18Introduction
19============
20
21The purpose of the frame buffer driver is to provide an abstraction for
22graphics hardware.  By using the frame buffer interface, an application can
23display graphics without knowing anything about the low-level details of
24interfacing to a particular graphics adapter. The parameters governing the
25mapping of memory to displayed pixels (planar or linear, bit depth, etc) is
26still implementation-specific, but device-independent methods are provided to
27determine and potentially modify these parameters.
28
29The frame buffer driver is commonly located in the ``console`` directory of the
30BSP and registered by the name :file:`/dev/fb0`.  Additional frame buffers (if
31available) are named :file:`/dev/fb1*,*/dev/fb2`, etc.
32
33To work with the frame buffer, the following operation sequence is
34used:``open()``, ``ioctls()`` to get the frame buffer info, ``read()``
35and/or ``write()``, and ``close()``.
36
37Driver Function Overview
38========================
39
40Initialization
41--------------
42
43The driver initialization is called once during the RTEMS initialization
44process and returns ``RTEMS_SUCCESSFUL`` when the device driver is successfully
45initialized. During the initialization, a name is assigned to the frame buffer
46device.  If the graphics hardware supports console text output, as is the case
47with the pc386 VGA hardware, initialization into graphics mode may be deferred
48until the device is ``open()`` ed.
49
50The ``frame_buffer_initialize()`` function may look like this:
51
52.. code-block:: c
53
54    rtems_device_driver frame_buffer_initialize(
55      rtems_device_major_number  major,
56      rtems_device_minor_number  minor,
57      void                      *arg)
58    {
59      rtems_status_code status;
60
61      printk( "frame buffer driver initializing..\n" );
62
63      /*
64       * Register the device
65       */
66      status = rtems_io_register_name("/dev/fb0", major, 0);
67      if (status != RTEMS_SUCCESSFUL)
68      {
69        printk("Error registering frame buffer device!\n");
70        rtems_fatal_error_occurred( status );
71      }
72
73      /*
74       * graphics hardware initialization goes here for non-console
75       * devices
76       */
77
78      return RTEMS_SUCCESSFUL;
79    }
80
81Opening the Frame Buffer Device
82-------------------------------
83
84The ``frame_buffer_open()`` function is called whenever a frame buffer device
85is opened.  If the frame buffer is registered as :file:`/dev/fb0`, the
86``frame_buffer_open`` entry point will be called as the result of an
87``open("/dev/fb0", mode)`` in the application.
88
89Thread safety of the frame buffer driver is implementation-dependent.  The VGA
90driver shown below uses a mutex to prevent multiple open() operations of the
91frame buffer device.
92
93The ``frame_buffer_open()`` function returns ``RTEMS_SUCCESSFUL`` when the
94device driver is successfully opened, and ``RTEMS_UNSATISFIED`` if the device
95is already open:
96
97.. code-block:: c
98
99    rtems_device_driver frame_buffer_close(
100      rtems_device_major_number  major,
101      rtems_device_minor_number  minor,
102      void                      *arg
103    )
104    {
105      if (pthread_mutex_unlock(&mutex) == 0) {
106        /* restore previous state.  for VGA this means return to text mode.
107         * leave out if graphics hardware has been initialized in
108         * frame_buffer_initialize()
109         */
110        ega_hwterm();
111        printk( "FBVGA close called.\n" );
112        return RTEMS_SUCCESSFUL;
113      }
114      return RTEMS_UNSATISFIED;
115    }
116
117In the previous example, the function ``ega_hwinit()`` takes care of
118hardware-specific initialization.
119
120Closing the Frame Buffer Device
121-------------------------------
122
123The ``frame_buffer_close()`` is invoked when the frame buffer device is closed.
124It frees up any resources allocated in ``frame_buffer_open()``, and should
125restore previous hardware state.  The entry point corresponds to the device
126driver close entry point.
127
128Returns ``RTEMS_SUCCESSFUL`` when the device driver is successfully closed:
129
130.. code-block:: c
131
132    rtems_device_driver frame_buffer_close(
133      rtems_device_major_number  major,
134      rtems_device_minor_number  minor,
135      void                      *arg)
136    {
137      pthread_mutex_unlock(&mutex);
138
139      /* TODO check mutex return value, RTEMS_UNSATISFIED if it failed.  we
140       * don't want to unconditionally call ega_hwterm()... */
141      /* restore previous state.  for VGA this means return to text mode.
142       * leave out if graphics hardware has been initialized in
143       * frame_buffer_initialize() */
144      ega_hwterm();
145      printk( "frame buffer close called.\n" );
146      return RTEMS_SUCCESSFUL;
147    }
148
149Reading from the Frame Buffer Device
150------------------------------------
151
152The ``frame_buffer_read()`` is invoked from a ``read()`` operation on the frame
153buffer device.  Read functions should allow normal and partial reading at the
154end of frame buffer memory.  This method returns ``RTEMS_SUCCESSFUL`` when the
155device is successfully read from:
156
157.. code-block:: c
158
159    rtems_device_driver frame_buffer_read(
160      rtems_device_major_number  major,
161      rtems_device_minor_number  minor,
162      void                      *arg
163    )
164    {
165      rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
166      rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ?
167                               (fb_fix.smem_len - rw_args->offset) : rw_args->count;
168      memcpy(rw_args->buffer,
169             (const void *) (fb_fix.smem_start + rw_args->offset),
170             rw_args->bytes_moved);
171      return RTEMS_SUCCESSFUL;
172    }
173
174Writing to the Frame Buffer Device
175----------------------------------
176
177The ``frame_buffer_write()`` is invoked from a ``write()`` operation on the
178frame buffer device.  The frame buffer write function is similar to the read
179function, and should handle similar cases involving partial writes.
180
181This method returns ``RTEMS_SUCCESSFUL`` when the device is successfully
182written to:
183
184.. code-block:: c
185
186    rtems_device_driver frame_buffer_write(
187      rtems_device_major_number  major,
188      rtems_device_minor_number  minor,
189      void                      *arg
190    )
191    {
192      rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
193      rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ?
194                               (fb_fix.smem_len - rw_args->offset) : rw_args->count;
195      memcpy((void *) (fb_fix.smem_start + rw_args->offset),
196             rw_args->buffer,
197             rw_args->bytes_moved);
198      return RTEMS_SUCCESSFUL;
199    }
200
201Frame Buffer IO Control
202-----------------------
203
204The frame buffer driver allows several ioctls, partially compatible with the
205Linux kernel, to obtain information about the hardware.
206
207All ``ioctl()`` operations on the frame buffer device invoke
208``frame_buffer_control()``.
209
210Ioctls supported:
211
212- ioctls to get the frame buffer screen info (fixed and variable).
213
214- ioctl to set and get palette.
215
216.. code-block:: c
217
218    rtems_device_driver frame_buffer_control(
219      rtems_device_major_number  major,
220      rtems_device_minor_number  minor,
221      void                      *arg
222    )
223    {
224      rtems_libio_ioctl_args_t *args = arg;
225
226      printk( "FBVGA ioctl called, cmd=%x\n", args->command  );
227
228      switch( args->command ) {
229        case FBIOGET_FSCREENINFO:
230          args->ioctl_return =  get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer );
231          break;
232        case FBIOGET_VSCREENINFO:
233          args->ioctl_return =  get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer );
234          break;
235        case FBIOPUT_VSCREENINFO:
236          /* not implemented yet*/
237          args->ioctl_return = -1;
238          return RTEMS_UNSATISFIED;
239        case FBIOGETCMAP:
240          args->ioctl_return =  get_palette( ( struct fb_cmap * ) args->buffer );
241          break;
242        case FBIOPUTCMAP:
243          args->ioctl_return =  set_palette( ( struct fb_cmap * ) args->buffer );
244          break;
245        default:
246          args->ioctl_return = 0;
247          break;
248      }
249
250      return RTEMS_SUCCESSFUL;
251    }
252
253See ``rtems/fb.h`` for more information on the list of ioctls and data
254structures they work with.
Note: See TracBrowser for help on using the repository browser.