This appendix includes the following:
This appendix makes the following assumptions:
The Photon microGUI is an embedded Graphical User Interface (GUI). This GUI is made up of numerous processes that use Neutrino message passing in order to create a highly responsive user experience. Photon is made up of these main components:
The io-display manager provides support for direct rendering to graphics devices using the QNX Graphics Framework and OpenGL ES.
The Photon server is the core server process for the GUI. This process must be the first graphical process run in the system. It is responsible for handling region creation and destruction, clipping, and managing the Photon event space.
This process, io-graphics, handles the Photon draw stream and loads the hardware driver. This process runs before any user application processes. The graphics subsystem queries the QNX graphics framework (io-display) for the display's settings rather than its own command-line settings.
This process (phfont.so) and associated libraries are used to render and gather metrics about fonts. Photon can render the following types of fonts:
Photon can render any Unicode encoded TrueType font. However, Photon does not provide support for complex languages such as Hebrew or Arabic. In order to render fonts for complex languages, you must obtain a third-party font rendering engine. For more information about supported fonts, see Appendix: Unicode Multilingual Support.
This process (devi-*) is responsible for handling user input from a mouse, keyboard, or touchscreen. This process communicates with your input hardware and then emits Photon events, which are collected and delivered to graphical processes in the system.
Once all of the other processes are running you can start user applications.
Here's an outline of the steps required to start Photon yourself, in the context of an embedded, closed system:
Each of these steps requires certain files be installed in your target system. By predetermining exactly what graphics hardware you have and what fonts your application needs, you can keep the number of files (and size of the image) to an absolute minimum. This reduction in size may in turn have a positive impact on your system's startup time.
We'll go through all the steps in detail and discuss the files needed for each step. At the end of this process, you should know exactly what Photon files you'll need to run your embedded application.
The QNX graphics framework server must be loaded before the graphics driver.
For more information about the QNX graphics framework server refer to io-display.
The PHOTON_PATH environment variable points to the base directory of the Photon installation. By default, this directory is /usr/photon. This location is expected to hold at least the following subdirectories:
You should set the PHOTON_PATH environment variable in the buildfile where you set other environment variables such as PATH:
PHOTON_PATH=/usr/photon
The LD_LIBRARY_PATH points the default system search path for libraries. The procnto process uses its setting of LD_LIBRARY_PATH to initialize the privileged configuration string _CS_LIBPATH, which limits the paths that programs running as root can load libraries from.
To avoid problems starting phfont, LD_LIBRARY_PATH must be set properly on the procnto line. This is especially true when using the IDE. LD_LIBRARY_PATH needs to be set on the procnto line in the project properties. |
The PATH environment variable points to the default system search path for binaries. You should set it to include the directories in your build image that contain binaries. These settings apply to any boot image.
If you don't need to pass any command-line arguments to the Photon server, you can start it as follows:
Photon
If you start Photon as a background process (that is, with the ampersand & after the command) you can tell that Photon started correctly by checking that /dev/photon appears in the filesystem. Use waitfor /dev/photon in your buildfile to check that the directory exists. |
If your boot image is too large because you've included Photon or other executables, you can place them in another filesystem that you can mount at boot-time. For more information, see mkifs in the QNX Neutrino Utilities Reference.
If you do include any of the Photon executables in your boot image, you should also include /usr/photon/bin in MKIFS_PATH so mkifs can find them.
/usr/photon/bin/Photon
If you're working on a board that has network access and can mount a network filesystem on your host machine, we recommend that you mount ${QNX_TARGET}/usr/photon/font_repository as /usr/photon/font_repository via NFS or CIFS. Although this approach uses the full Photon font system, it simplifies development significantly, and you can customize the embedded fonts later using the information in “Configuring Fonts” in the “Advanced topics” section.
For information about using NFS and CIFS to mount a network filesystem, see “CIFS filesystem” and “NFS filesystem” in the Working with Filesystems chapter of the Neutrino User's Guide.
Include the following libraries in your build file; io-graphics will load the font libraries for you when it starts:
These plugins are used to render specific fonts on the system. Use the use utility to view specific support information for these plugins, and to determine which font families are rendered by this plugin. If you don't plan to use any of the fonts that this plugin supports, then you can remove this plugin to decrease the footprint of your installation. |
The graphics subsystem consists of io-graphics, a hardware-specific driver DLL, and a collection of helper libraries. You need the following components to run the graphics subsystem on the target:
Additionally, you need a hardware-specific library (or graphics driver). By convention, graphics driver names begin with devg-, for example, devg-rage.so.
Most graphics drivers depend on the following shared libraries:
Make sure that all required libraries are accessible by the dynamic loader before you start io-graphics. Use the LD_LIBRARY_PATH environment variable or _CS_LIBPATH configuration string to point to the location of the shared libraries.
Normally in a desktop environment, you use the inputtrap utility to automatically generate the correct command line and to invoke the appropriate devi-* driver. For example, it might invoke devi-hirun like this:
devi-hirun kbd fd -d/dev/kbd msoft fd &
See devi-hirun in the Neutrino Utilities Reference for more examples.
You typically run inputtrap because you don't know in advance what the appropriate command line should be.
In an embedded system, however, you typically specify the command line to the devi-* driver manually. This is because the input devices are often found at unusual locations, are incapable of PnP identification, or are simply not supported by an existing devi-* driver. In addition, the inputtrap utility tends to be quite large and could waste precious storage and memory in a constrained environment. If figuring out the appropriate command to run proves difficult, you can temporarily install inputtrap in your image (or mount a networked filesystem that contains the binary) and use it to generate the correct command line. See inputtrap and its query option in the Neutrino Utilities Reference.
If none of the shipped input drivers are able to work with your input hardware, you can customize the input drivers by using the Input Driver Development Kit (Input DDK). For example, you can change the size of the memory footprint, or you can create a custom module to support new devices.
The appropriate devi-* driver in /usr/photon/bin
The appropriate .kbd keyboard mapping file in /usr/photon/keyboard
The Photon window manager (pwm) is an optional component that provides your system with windowing functionality you may not need. If your application user interface consists of one (or more than one) program that always fills the screen, uses a “card” or “slide” paradigm (that is, a UI composed of a series of stacked cards or slides that the program flips through), or uses dialogs that your application controls itself, then you probably don't require the window manager. On the other hand, if your UI is built using one (or more than one) program that relies on windowing behavior (such as windows or dialogs that you don't want to manage yourself), then pwm is probably a good fit for your system.
/usr/photon/bin/pwm
If your application is a single executable and doesn't require the window manager, you may link statically against the Photon-related libraries (such as libAp.a, libph.a, and libphexlib.a). Linking statically avoids the need to include the corresponding shared components in your image, and will pull in only the symbols needed by your program, making the overall image smaller. Also, linking statically has an added benefit of slightly reducing runtime overhead. If you have multiple applications in your image (including pwm), you should always link against the shared libraries and include them in your image.
You can use the pidin utility on a host system to view the libraries that an application or OS component requires. For example, if you wanted to see the libraries required by phcalc, run it on a host system, and then run pidin -p phcalc mem.
The QNX IDE includes a tool called the Dietician that shrinks shared libraries by analyzing the executables in your system and removing the symbols that aren't needed. This realizes most of the benefits of linking statically while still allowing the libraries to be shared. However, if your system only consists of one application (and no window manager), linking statically is probably the better way to go.
The libraries in /usr/photon/lib (*.so.1) are provided for runtime compatibility with Photon for QNX Neutrino 6.0 (x86 only). The libraries for QNX Neutrino 6.1 and later are located in /usr/lib. |
The following are observations that some customers have encountered when moving Photon to an embedded system.
The following flash filesystem properties affect how you configure Photon:
$(ABOBJ) $(MYOBJ) $(LD) $(LDFLAGS) $(ABOBJ) $(MYOBJ) -M -o mine usemsg mine ../Usemsg phabbind mine $(ABMOD)
to:
$(ABOBJ) $(MYOBJ) $(LD) $(LDFLAGS) $(ABOBJ) $(MYOBJ) -M -o mine usemsg mine ../Usemsg phabbind mine.res $(ABMOD)
When your executable is launched, the PhAB library (libAp.so) automatically finds the resource file, provided the following criteria are met:
If you want to group your resource files in a separate directory, you can. Place them in the directory specified by the exported AB_RESOVRD environment variable, and the PhAB library will look for them there. The naming of the resource files must meet the first criterion, listed above.
Many embedded systems lack components that are typical on an x86 desktop machine, such as BIOS ROMs. Because many of the modeswitchers that Photon supports require a video BIOS to allow them to switch graphics modes, you might need a BIOS on the board. Check with us to see if a non-BIOS version is available.
Here are some other considerations:
Photon -D1000 &
Let's look at the steps involved in embedding Photon for use in an embedded system by creating a simple buildfile that contains a few simple Photon applications.
Our goal is to build a Photon system with the following minimal capabilities that satisfies our system's requirements:
Note that a window manager isn't strictly required for an embedded system, but we'll include one to make our example easier to use.
We'll follow these steps:
The first step involves figuring out all the binaries required to run Photon. You can see everything that's running on a full system. Run Photon on your PC, and look at the output of the pidin arg command.
From that list, you need only a few of the programs:
Save the argument list for your system in a file. We'll need that output later.
On this embedded system you want only the components listed above, plus you'll run a couple of simple applications:
Run the applications, then look at the output of the pidin mem command. The resulting listing tells you every library that you need to make available to the embedded system. For a graphics driver, you'll use the generic SVGA driver (devg-svga.so).
So you need the following libraries (at least):
Now let's look at fonts. Sometimes an application expects a specific font, and codes directly to that font. If this is the case, you need to explicitly include every font that your application needs. If you standardize on a certain family/style of fonts or if you don't care what exact font you have (as long as the size is okay), then you can cut down on the number of fonts and use one font to replace several other families of fonts. For example, you can use Times as a replacement for Helvetica and Courier.
In this example, because you're using a few simple applications, and because you're trying to create the smallest image possible, you need only two fonts: a monospace and regular TrueType version of Prima Sans.
Now's a good time to create a play area on your system to begin testing the embedded system, and collecting required files.
Create a subdirectory called phembed in your home directory (or whichever directory you wish to keep your source files). Within that directory, create these subdirectories:
Now back to the fonts. In this example, you want to use the primasansmonobts TrueType font for everything. You'll also want to use a mouse, so you'll include the phcursor.phf file.
Here are the files you need:
Copy these files (except fontdir) from /usr/photon/font_repository to /phembed/font_repository, then change directories to /phembed/font_repository.
You need to modify the fontmap and fontopts files to reflect the fonts, options and mappings you want for your embedded system. You can edit these files by hand (see phfont for more information on the structure of these files). In our case lets make sure that the fontmap file contains:
? = primasansmonobts
This ensures that all unknown fonts will be replaced with the primasansmonobts font, provided in the tt2009m_.ttf file.
To generate fontdir, use the mkfontdir like this:
mkfontdir -d /phembed/font_repository
Make sure that the LD_LIBRARY_PATH string in your build file contains the string /lib/dll. |
Now let's put all the pieces you need in place and create a buildfile for your embedded Photon system. Run mkifs to create an image.
|
[image=0x88010000] [virtual=shle/binary +compress] .bootstrap = { startup-sdk7785 -Dscif..115200.1843200.16 -f600000000 -v [+keeplinked] PATH=/proc/boot:/bin:/sbin:/usr/bin:/opt/bin: \ /usr/sbin:/usr/photon/bin \ LD_LIBRARY_PATH=/proc/boot:/lib::/usr/lib:/lib/dll:/opt/lib: \ /usr/photon/lib:/usr/photon/dll \ PHOTON_PATH=/usr/photon procnto -v } [+script] .script = { procmgr_symlink ../../proc/boot/libc.so.3 /usr/lib/ldqnx.so.2 display_msg Welcome to QNX Neutrino 6.4.0 on the Renesas SDK7785 ############################################################## ## SERIAL driver ############################################################## display_msg Starting serial driver devc-sersci -e -F -x -b115200 -c1843200/16 scif1 & waitfor /dev/ser1 reopen /dev/ser1 slogger pipe ############################################################## ## NOR FLASH driver SDK 7785 ############################################################## # Flash only recognized as a single bank 4*2 array. Single driver # Used to access both banks. Care must be taken when toggling # bank select as the base address will switch between banks. ############################################################## # devf-edosk7780 -s0x0,128M ############################################################## ## NETWORK driver SDK 7785 ############################################################## display_msg "Starting the core network stack..." io-pkt-v4 -dsmc9118 ioport=0x15800000,irq=6 -ptcpip waitfor /dev/socket 15 waitfor /dev/io-net/en0 if_up -r 10 -p en0 display_msg "Setting ip address to XXX.XX.X.XX..." ifconfig en0 XXX.XX.X.XX up netmask 0xffffff00 if_up -a en0 lo0 display_msg Starting fs-nfs2 setconf DOMAIN domain.name.com ############################################################## ## PCI server ############################################################## display_msg "Starting pci-edosk7780..." pci-edosk7780 display_msg "Starting devc-pty..." devc-pty waitfor /dev/ptyp0 4 waitfor /dev/socket 4 qconn port=8000 display_msg "Setting enviroment variables..." SYSNAME=nto TERM=qansi HOSTNAME=gsdk7785 HOME=/root PATH=:/proc/boot:/bin:/sbin:/opt/bin:/usr/sbin:/usr/bin:/usr/photon/bin LD_LIBRARY_PATH=:/proc/boot:/lib:/usr/lib:/lib/dll:/opt/lib:/usr/photon/ \ lib:/usr/photon/dll PHOTON=/dev/photon PHOTON_PATH=/usr/photon PHOTON_PATH2=/usr/photon PHFONT=/dev/phfont MMEDIA_MIDI_CFG=/etc/config/media/midi.cfg display_msg "Starting io-display..." io-display -dvid=0x10cf,did=0x201e waitfor /dev/io-display display_msg "Starting Photon..." Photon & waitfor /dev/photon 10 display_msg "Starting io-graphics..." io-graphics & waitfor /dev/phfont 10 display_msg "Starting Window Manager..." pwm & devc-pty & display_msg "Starting Terminal" pterm /proc/boot/ksh & # inetd & [+session] ksh & } [type=link] /bin/sh=/proc/boot/ksh [type=link] /dev/console=/dev/ser1 [type=link] /tmp=/dev/shmem libc.so libc.so.2 libm.so ################################################################### ## uncomment for NETWORK driver ################################################################### devn-smc9118.so devnp-shim.so libsocket.so [data=c] devc-sersci setconf ################################################################### ## uncomment for NOR FLASH driver ################################################################### devf-edosk7780 flashctl ################################################################### ## uncomment for PCI server ################################################################### pci-edosk7780 pci pipe ################################################################### ## uncomment for NETWORK driver ################################################################### io-pkt-v4 ping cat ifconfig netstat nicinfo sleep ################################################################### ## uncomment for REMOTE_DEBUG (gdb or Momentics) ################################################################### devc-pty qconn /usr/bin/pdebug=pdebug ################################################################### ## general commands ################################################################### ls ksh pipe pidin uname slogger sloginfo slay fs-nfs3 fs-nfs2 if_up fs-cifs mount umount ########################################################################### ## uncomment for GF io-display ########################################################################### /sbin/io-display=io-display /etc/system/config/display.conf=/usr/qnx640/target/qnx6/etc/system/config/ \ display.conf /etc/system/config/img.conf=/usr/qnx640/target/qnx6/etc/system/config/ \ img.conf ########################################################################### ## uncomment for GF libraries ########################################################################### /lib/dll/devg-soft3d.so=devg-soft3d.so /lib/dll/devg-coral.so=devg-coral.so /lib/libFF-T2K.a=libFF-T2K.a /lib/libFF-T2K.so.2=libFF-T2K.so.2 /lib/libimg.so=libimg.so /usr/lib/libGLES_CM.so.1=libGLES_CM.so.1 /usr/lib/libffb.so.2=libffb.so.2 /usr/lib/libgf.so=libgf.so ########################################################################### ## uncomment for GF image support ########################################################################### /lib/dll/img_codec_bmp.so=img_codec_bmp.so /lib/dll/img_codec_gif.so=img_codec_gif.so /lib/dll/img_codec_jpg.so=img_codec_jpg.so /lib/dll/img_codec_png.so=img_codec_png.so /lib/dll/img_codec_sgi.so=img_codec_sgi.so /lib/dll/img_codec_tga.so=img_codec_tga.so ########################################################################### ## uncomment for GF binaries ########################################################################### /bin/egl-gears=egl-gears /bin/vsync=vsync /lib/dll/font/ttfFFcore.so = ${QNX_TARGET}/shle/lib/dll/font/ttfFFcore.so /lib/dll/font/PHFcore.so = ${QNX_TARGET}/shle/lib/dll/font/PHFcore.so /lib/dll/font/FCcore.so = ${QNX_TARGET}/shle/lib/dll/font/FCcore.so libfontutils.so libblkcache.so libFF-T2K.so libfont.so phfont.so ###################################### ## Photon LIbs ###################################### Photon [+raw] /usr/photon/bin/pterm = pterm [+raw] /usr/photon/bin/phcalc = phcalc io-graphics pwm libph.so libAp.so libphexlib.so libdisputil.so libffb.so libphrender.so ########################################################################## ## font config ########################################################################## /usr/photon/font_repository/tt2009m_.ttf = \ /usr/photon/font_repository/tt2009m_.ttf /usr/photon/font_repository/phcursor.phf = \ /usr/photon/font_repository/phcursor.phf /usr/photon/font_repository/pcterm12.phf = \ /usr/photon/font_repository/pcterm12.phf /usr/photon/font_repository/fontopts = /usr/photon/font_repository/fontopts /usr/photon/config/wm/wm.menu = /usr/photon/config/wm/wm.menu /usr/photon/font_repository/fontdir = { ; ; fontdir config file ; pcterm12,.phf,PC Terminal,12,,0000-00FF,Nf,6x12,13K phcursor,.phf,Photon Cursor,0,,E900-E921,Np,32x32,3K primasansmonobts,0@tt2009m_.ttf,PrimaSansMono BT,0,,0020-F002,f,79x170,109K } /usr/photon/font_repository/fontext = { ; ; fontext config file ; +normal = primasansmonobts, phcursor } /usr/photon/font_repository/fontmap = { ; ; fontmap config file ; ? = primasansmonobts } /usr/photon/config/coral.conf=${QNX_TARGET}/usr/photon/config/coral.conf /etc/system/config/crtc-settings=/etc/system/config/crtc-settings /usr/photon/palette/default.pal=/usr/photon/palette/default.pal # allow pterm to save its configuration to RAM, if the user changes it. [type=link] /.ph/pterm = /dev/shmem [type=link] /.ph/wm/wm.cfg = /dev/shmem
Note the following about the buildfile:
Once you've built your image using mkifs, you can transfer it to a test machine to see how it works. See “Transferring an OS image onto your board” in the Working with a BSP chapter of Building Embedded Systems for more information.
Check the system log; io-graphics may have sent error messages to the system logger, slogger. In order to debug the problem, make sure slogger is running before starting the graphics driver. Use sloginfo to display the system log messages.
Make sure both the Photon server and the font manager are running. You can determine if they're running by making sure that /dev/photon and /dev/phfont exist.
If you include an application that was built by PhAB in an image created by mkifs, some information will be stripped out, since mkifs does a very aggressive binary strip. You can avoid this by using the +raw attribute; see the mkifs documentation for more information. Since setting the attribute will cause the application not to be stripped, you may want to use the strip utility to manually strip the binary before building the image, to reduce the image size.
Building an embedded OS image that includes Photon using the IDE is similar to writing a buildfile and using the command line. You need to perform the same analysis (described in the example above) of the required binaries, libraries and fonts. The difference is that you don't write a buildfile; instead you create a project in the IDE's System Builder.
This example assumes that you're familiar with the IDE's System Builder. See the Building OS and Flash Images chapter in the IDE User's Guide for more information.
Instead of building a new System Builder project from scratch, you can import the buildfile from the command-line example above. You can then modify the resulting System Builder project to suit your needs. |
Here are the general steps required to make a System Builder project that's identical to the previous buildfile example:
You need to use the equivalent of [+raw] on pterm and phcalc by selecting them, and setting the Strip File property to No.
Standard libraries:
Advanced Graphics libraries:
Photon libraries:
Graphics libraries:
Font libraries:
Fonts and the font configuration files:
Other required configuration files:
You can now build the image, transfer it to your target, and run it.
This section covers some of the more advanced topics in embedding Photon. It covers:
Configuring fonts and installing the font server components in the correct location is the most difficult part of embedding Photon.
To configure the font system, you need to:
The first decision you must make about the font service is how the server is started. It can run as a stand alone process (we refer to this as an external server) or as a plugin to io-graphics (which we call an internal server).
We recommend to run an external server in these conditions:
To run an external font server, start phfont before io-graphics. To run an internal font server, simply start io-graphics using the -f local option.
When building an embedded system, you also need to make careful decisions about the level of font support, including which fonts you need, and whether or not you need scalable fonts, since extra fonts make for a larger image size and potentially longer startup time.
Unlike bitmap fonts, scalable fonts are defined mathematically, and can be rendered at any font size. Scalable fonts elminate the need to store large numbers of glyphs that are required to render bitmap fonts at different font sizes. |
The first step is to decide which fonts you need:
Check the browser's configuration to see which fonts are expected, and use those fonts, modifying the configuration to reflect what you've installed, or use the fontmap file to map them at runtime.
You can map, or substitute, font names by using the fontmap file. For more information on the format of fontmap and other font configuration files, see phfont in the QNX Neutrino Utilities Reference.
You may be able to reduce the number of binaries required by the Photon font system, depending on the types of fonts you need to render on your target. Each font type has an associated plugin that supports that type, and each plugin in turn requires additional libraries. Each plugin requires libblkcache.so and libc.so. The following table summarizes additional, plugin-specific, requirements:
Fonts supported | Plugin | Required libs |
---|---|---|
Bitstream TrueDoc (.pfr) TrueType collections (.ttc) |
FCcore.so | libFF-T2K.so |
Photon bitmap (.phf) | PHFcore.so | libfontutils.so |
TrueType (.ttf), Adobe Type1 (.pfa), Adobe Type2 (.cff), Bitstream Stroke (.ffs), Bitstream Speedo (.spd, public encryption only), Bitstream T2K (.t2k) | ttfFFcore.so |
libFF-T2K.so |
You can use the -b commandline option for phfont or io-graphics to generate a font usage report. The report file contains information about font names and font files used by your application while the font server was running. This allows you to put the only required fonts and DLLs on your target system. Note that the font usage report doesn't contain a record of dynamically loaded fonts (see the PfDynamicLoad*() set of functions).
The font system is configured with various files. The minimum configuration requires:
Recommended additional configuration files are:
For more information about the format of each of these files, see phfont.
You can configure the fonts on the embedded system itself, but it's easier to use your development system to configure the fonts to mimic the desired configuration for the embedded system, then assemble the font data and configuration files in the appropriate Embedded File System (EFS) build image directory.
If you're using a self-hosted development system to mimic your target, then the font server can aid in determining which fonts you need by logging failed requests for fonts that aren't mapped (explicitly or otherwise). See phfont for more information. |
In an embedded system with only a few applications, chances are you'll need far fewer fonts than a desktop system requires. In this situation, you can provide minimal configuration files (all located in /usr/photon/font_repository):
This file can consist of a single line:
?=primasansbts
(If you aren't including PrimaSans BT in your image, change this to the name of the font you want to use as a default).