source: rtems-docs/bsp_howto/frame_buffer.rst @ 9aafb39

4.115
Last change on this file since 9aafb39 was 6d7a4d2, checked in by Chris Johns <chrisj@…>, on 06/17/16 at 05:05:41

Update the BSP howto.

Closes #2590.

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