Developing with GNUPro Toolkit

Using GNUPro Toolkit for development typically involves the following process.

  1. Create a project and edit its source code.
  2. See The C Run-time Environment (crt0).

  3. Compile your source code with the GNU compiler into intermediate object files.
  4. See crt0, the Main Startup File.

  5. Link object files together with the GNU linker to produce an executable file.
  6. See The Linker Script.

  7. Debug the executable file to find any problems.
  8. See Using RedBoot for Remote Debugging.

  9. Build the executable file.

This chapter describes those steps in more detail.

What Embedded Development Means

When developing with a cross-configuration, you work with the tools on the host by using a toolchain . For example, working with a SPARCstation, you generate and debug code for a Power PC-based board by calling a specific tool with a specific embedded target's toolchain (this is described in more detail in Tools, Toolchains and Usage). The toolchain method has routines for providing a specific type of compiled output, others for preprocessing, and others for controlling assembling, linking, optimizing, debugging, and other target-specific functions.

When compiling, the following routines are for optimization:

When compiling, the following routines are for dynamic memory allocation:

newlib calls the following support routines, although not for embedded targets:

Most applications use calls to the standard C library. To link libc.a when you are developing with a target that has no operating system, you must first define several I/O functions, such as the open() and close() functions; for more information, see "System Calls" in GNUPro C Library in GNUPro Libraries .

When debugging, set up the tools as follows:

  1. Set up the C run-time environment; see The C Run-time Environment (crt0).
  2. Create stubs , or minimal versions of operating system subroutines for the C subroutine library; see Using RedBoot for Remote Debugging , and also "System Calls" in GNUPro C Library in GNUPro Libraries .
  3. Connect to the debugger; see "Specifying a Debugging Target" in Debugging with GDB in GNUPro Debugger Tools, and see also Debug with Insight.

WARNING!

This type of embedded development may be inappropriate for real-time operating systems as embedded operating systems may provide their own configuration of tools.

Tools, Toolchains and Usage

When you use GNUPro tools, you typically use a standard convention for toolchain names. A toolchain name is a combination of a host name and a target name as a prefix to the tool name. The tables that follow provide the specific host and target names that you require. If you are not already familiar with the names of specific tools, review Compiler and Development Tools.

Toolchain names for Microsoft Windows NT 4.0 embedded targets

Target

Name

StrongARM

i686-cygwin-x-strongarm-elf

Hitachi SH1/2/3/4

i686-cygwin-x-sh-elf

MIPS 64

i686-cygwin-x-vr5xxx-elf

PowerPC

i686-cygwin-x-powerpc-eabi

x 86

i686-cygwin-x-i386-elf

Toolchain names for Red Hat Linux 6.0, 6.1, 6.2 and 7.0 embedded targets

Target

Name

StrongARM

i686-pc-linux-gnulibc2.1-x-strongarm-elf

Hitachi SH1/2/3/4

i686-pc-linux-gnulibc2.1-x-sh-elf

MIPS 64

i686-pc-linux-gnulibc2.1-x-vr5xxx-elf

PowerPC

i686-pc-linux-gnulibc2.1-x-powerpc-eabi

x 86

i686-pc-linux-gnulibc2.1-x-i386-elf

Toolchain names for Sun SPARC Solaris 2.6 embedded targets

Target

Name

StrongARM

sparc-sun-solaris2.6-x-strongarm-elf

Hitachi SH1/2/3/4

sparc-sun-solaris2.6-x-sh-elf

MIPS 64

sparc-sun-solaris2.6-x-vr5xxx-elf

Motorola 68K

sparc-sun-solaris2.6-x-m68k-elf

PowerPC

sparc-sun-solaris2.6-x-powerpc-eabi

x 86

sparc-sun-solaris2.6-x-i386-elf

IMPORTANT!

Before developing, use the configure command with the --exec= toolchain or --exec-prefix= toolchain option to specify in the Makefile the sources for the development environment.

The C Run-time Environment (crt0)

To link and run C or C++ programs and to ensure that the system hardware initializes for C conventions before calling main , define a small module, crt0 (usually written in assembler as crt0.s ) to serve as your startup code. The startup code defines a special start symbol, the default address for your application, as well as the first symbol in the executable image. If you will use any routines from the standard C library, implement the functions upon which the library depends. To write your own crt0.s module, you need the following information about your target.

There are some examples available in the sources of GNUPro Toolkit for crt0.s code (along with examples of system calls with subroutines); look in the installdir /src/newlib/libc/sys path ( installdir refers to your installation directory; for example, look in .../sys/h8300hms for Hitachi H8/300 boards). More examples are in the installdir /src/newlib/stub directory.

At a minimum, your crt0.s module must provide the following processes to link and run your programs:

Choose where to store your stack within the constraints of your target's memory map, the simplest choice being a fixed-size area somewhere in the uninitialized data section (often bss ). Whether you choose a low address or a high address in this area depends on the direction your stack grows.

Use a linker script (see The Linker Script and "Linker Scripts" in Using ld in GNUPro Development Tools ) to define symbols such as bss_start and bss_end to record the boundaries of this section; then you can use a for loop to initialize all memory between them in the crt0.s module.

A more complete crt0.s module might also do the following:

crt0 , the Main Startup File

The crt0 (C RunTime 0) file contains the initial startup code for embedded development; its object is linked in first and bootstraps the rest of your application. A crt0 file is available for most platforms, although you may want your own crt0 file for each target. The crt0 file is usually written in assembler and named crt0.s .

The crt0 file defines a special symbol such as _start , which is both the default base address for the application and the first symbol in the executable binary image.

If you plan to use any routines from the standard C library, you will also need to implement the functions on which newlib depends.

The crt0 file initializes everything that your program requires for the host and target. This initialization section varies for some systems:

    The following shows a basic initialization of a crt0.s file; your file may differ, although there will be a similar initialization process.

      1. Set up concatenation macros:

        #define CONCAT1(a, b) CONCAT2(a, b)
        #define CONCAT2(a, b) a ## b

      2. Set up label macros:

        #ifndef _ _USER_LABEL_PREFIX_ _
        #define _ _USER_LABEL_PREFIX_ _
        #endif

        #define SYM(x) CONCAT1 (_ _USER_LABEL_PREFIX_ _, x)

      These macros make the code portable between COFF and a.out ; COFF has _ _ (two underlines) before its global symbol names, while a.out has none.

      3. Set up register names (with the appropriate prefix):

        #ifndef _ _ REGISTER_PREFIX _ _
        #define _ _ REGISTER_PREFIX _ _
        #endif
        /* Use the right prefix for registers. */
        #define REG(x) CONCAT1 _ _ REGISTER_PREFIX _ _ , x)
        #define d0 REG (d0)
        #define d1 REG (d1)
        #define d2 REG (d2)
        #define d3 REG (d3)
        #define d4 REG (d4)
        #define d5 REG (d5)
        #define d6 REG (d6)
        #define d7 REG (d7)
        #define a0 REG (a0)
        #define a1 REG (a1)
        #define a2 REG (a2)
        #define a3 REG (a3)
        #define a4 REG (a4)
        #define a5 REG (a5)
        #define a6 REG (a6)
        #define fp REG (fp)
        #define sp REG (sp)

      Register names are for portability between assemblers. Some register names have % or $ prepended to them.

      4. Set up space for the stack by assigning part of memory. (Although you can also set this allocation in the linker script, it typically is done at this point.)

        .set stack_size, 0x2000 .
        comm SYM (stack), stack_size

      5. Define empty space for an environment:

        .data
        .align 2
        SYM (environ):
        .long 0

      This call is unlike most for a ROM monitor. Generally it is best to set up a valid address and then pass the address to main() . In this way if an application checks for an empty environment, it finds one.

      6. Set up a few global symbols:

        .align 2
        .text
        .global SYM (stack) .global SYM (main)
        .global SYM (exit)
        .global _ _ bss_start

      The last line really should not be SYM (_ _bss_start) , since declaring _ _bss_start this way ensures the appropriate setting of its value in the linker script.

      7. Set up the start global symbol for the linker to use as the default address for the .text section. This helps your program run.

        SYM (start):
        link a6, #-8
        moveal #SYM (stack) + stack_size, sp

    • crt0 zeroes the .bss section.
      Clear the .bss section for uninitialized data using the following example. Initialize all of the addresses in the .bss section to zero so programs will get predictable results when there is no check for the default values of new variables.

        moveal # _ _ bss_start, a0
        moveal #SYM (end), a1
        1:
        movel #0, (a0)
        leal 4(a0), a0
        cmpal a0, a1
        bne 1b

      Applications can get unpredictable effects with the .bss section left uncleared, causing particular problems with some implementations of malloc() calls.

    • crt0 calls main() .
      If your ROM monitor supports it, set up argc and argv for command line arguments and an environment pointer before the call to main() . F or GNU C++ compiling, the code generator inserts a branch to _ _main at the top of your main() routine, while the GNU C++ compiler uses _ _main to initialize its internal tables and then returns control to your main() routine. For crt0 to call your main() routine, use the following example. Set up the environment pointer and jump to main() and call the main routine from the application with main (argc, argv, environ) , using argv as a pointer to NULL .

        pea 0
        pea SYM (environ)
        pea sp@(4)
        pea 0
        jsr SYM (main)
        movel d0, sp@-4

    • crt0 calls (exit)
      After main() runs, the crt0 file then returns control of the hardware from the application. On some hardware there is nothing to return to, especially if your program is in ROM. If that is the case, you need to do a hardware reset or branch back to the original start address. Using a ROM monitor you can usually call a user trap to provide the ROM control. Pick a safe vector with no sides effects. Some ROMs have a built-in trap handler for just this case. Exit from the application with _exit ; normally, this causes a user trap to return to the ROM monitor for another run. Proceed by using the following example:

        SYM (exit):
        trap #0

    Both rom68k and bug can handle an exception of 0 with no side effects; although the bug monitor has a user-caused trap that returns control to the ROM monitor, the bug monitor is more portable.

The Linker Script

In the /usr/redhat/host/target/lib/ldscripts/ path, find the example linker scripts (host signifies your host configuration and target signifies the embedded configuration that you target). In that directory there will be files with the .x , .xbn , .xn , .xr , .xs , and .xu extensions serving as examples of linker scripts.

The linker script does the following:

When your application loads into memory, it allocates some RAM, some disk space for I/O, and some registers. The linker script makes a memory map of this memory allocation. This is important to embedded systems because you gain the ability to manage the behavior of the chip, even though they have no OS.

Actual section names vary depending on your object file format. For a.out and COFF formats, .text , .data , and .bss are the three main sections.

There are two ways to ensure the memory map is correct.

The following example shows how to set up a linker script for a Motorola 68000 target.

  1. Load the file so that it executes first with the STARTUP(crt0.o) command.
  2. By default, the Motorola 68000 configuration using the COFF object file format does not link in crt0.o because it assumes that you have a crt0 file. A config file controls this behavior in each architecture in a STARTFILE_SPEC macro. If you have STARTFILE_SPEC set to NULL , the GNU compiler formats its command line and does not add crt0.o . You can specify any filename with STARTUP , although the default is always crt0.o . If you use only ld to link, you control whether or not to link in crt0.o on the command line.
    If you have multiple crt0 files, you can omit STARTUP and link in crt0.o in a makefile or by using different linker scripts (this option is useful when initializing floating point values or when adding device support).

  3. Use GROUP to load a file:
    1. GROUP(-lgcc-liop-lc)

    In this case, the file is a relocated library containing the definitions for the low-level functions that the libc.a file requires.

  4. Use SEARCH_DIR to specify the path in which to look for files:
    1. SEARCH_DIR(.)


  5. Use _DYNAMIC to specify whether or not there are shared dynamic libraries. In the following example, the value of zero provides no shared libraries:
    1. _ _ DYNAMIC = 0;


  6. Set _stack , the variable for specifying RAM for the ROM monitor.


  7. Specify a name for a section to which you can refer later in the script.
  8. In the following example, it is only a pointer to the beginning of free RAM space with an upper limit at 2MB. If the output file exceeds the upper limit, MEMORY produces an error message.

      MEMORY{
      ram : ORIGIN = 0x10000, LENGTH = 2M
      }

    In this example, you set up the memory map of the board's stack for high memory for both the rom68k and mon68k monitors.

  9. For the GNU C++ compiler, set up constructor and destructor tables. Set up the .text section, using the following example:
    1. SECTIONS
      {
      .text :
      {
      CREATE_OBJECT_SYMBOLS
      *(.text)
      etext = .;
      _ _ CTOR_LIST _ _ = .;
      LONG(( _ _ CTOR_END _ _ - _ _ CTOR_LIST _ _ ) / 4 - 2)
      *(.ctors)
      LONG(0)
      _ _ CTOR_END _ _ = .;
      _ _ DTOR_LIST _ _ = .;

      LONG(( _ _ DTOR_END _ _ - _ _ DTOR_LIST _ _ ) / 4 - 2)
      *(.dtors)
      LONG(0)
      _ _ DTOR_END _ _ = .;
      *(.lit)
      *(.shdata) }
      > ram
      .shbss SIZEOF(.text) + ADDR(.text) : {
      *(.shbss)
      }

    In a COFF file, all of the actual instructions for setting up the constructor and destructor tables for the GNU C++ compiler are in .text . The section description redirects itself to the RAM variable that you previously set (see Set _stack, the variable for specifying RAM for the ROM monitor.) with the _stack variable.

  10. Set up the .data section.
    1. .talias : { } > ram
      .data : {
      *(.data)
      CONSTRUCTORS
      _edata = .;
      } > ram

    A COFF file is where all of the initialized data goes. CONSTRUCTORS is a special command that the GNU linker, ld , uses.

  11. Set up default values for _bss_start and _end variables by setting up the .bss section.
  12. The default values for _bss_start and _end are for use by the crt0 file when it zeros the .bss section.

      .bss SIZEOF(.data) + ADDR(.data) :
      {
      _ _ bss_start = ALIGN(0x8);
      *(.bss)
      *(COMMON)
      end = ALIGN(0x8);
      _end = ALIGN(0x8);
      _ _ end = ALIGN(0x8);
      }
      .mstack : { } > ram
      .rstack : { } > ram
      .stab . (NOLOAD) :
      {
      [ .stab ]
      }
      .stabstr . (NOLOAD) :
      {
      [ .stabstr ]
      }
      }

    For more information on linking, see Using ld in GNUPro Development Tools .

Using Cygwin

This section discusses the architecture underlying the Cygwin tools for porting UNIX applications to Windows 32-bit environments. For more information, see:

http://sources.redhat.com/cygwin/

GNUPro Toolkit provides the following packages for Cygwin:

Cygwin emulates a standard UNIX directory structure. To emulate the /etc directory (so that the ls -l UNIX directory contents listing command works), use the following example's declarations as a guide:

mkdir /etc/
cd /etc
mkpasswd > /etc/passwd
mkgroup > /etc/group

Cygwin comes with both bash.exe and sh.exe shells. sh.exe is based on ash . In case of trouble with ash , make sh.exe point to the bash.exe shell.

When executing a binary linked against the library, the Cygwin dynamically linked library (DLL) loads into the application's text segment. To emulate a UNIX kernel for allowing access to all processes that can run with it, use the Cygwin DLL. The Cygwin DLL will create shared memory areas so that other processes using separate instances of the DLL can access the kernel. The DLL keeps track of open file descriptors and, among other purposes, assists fork and exec calls. In addition to the shared memory regions, every process also has a per-process structure that contains information such as process ID, user ID, signal masks, and other similar process-specific information.

The DLL uses the Win32 API. Because processes run under the standard Win32 subsystem, they can access both the UNIX compatibility calls provided by Cygwin as well as any of the Win32 API calls. This gives the programmer complete flexibility in designing the structure of their program in terms of the API in use; for example, a project might require a Win32-specific GUI using Win32 API calls on top of a UNIX back-end that uses Cygwin.

The CYGWIN environment variable helps to override the Win32 default behavior and force POSIX1 standards compliance.

UNIX applications that have to switch the user context have the setuid and seteuid calls, which are not part of the Microsoft Windows API. Nevertheless these calls are supported under Windows Microsoft Windows NT and Microsoft Windows 2000 with Cygwin.

Before Using Cygwin

Before using Cygwin tools, see descriptions of Mount Table and the mount Utility (below), Text and Binary Modes with Cygwin, File Permissions With Cygwin, Special Cygwin File Names, Building and Using DLLs with Cygwin, and Defining Windows Resources for Cygwin.

Mount Table and the mount Utility

The mount utility controls a mount table for emulating a POSIX view of a Windows file system space. To change a Windows path that uses / and mount arbitrary Win32 paths into the POSIX file system space, use mount to mount each drive letter under a slash partition (such as C:\ to /c or D:\ to /d , and so forth).

Executing the mount command without any arguments prints the current mount table to a screen. Alternatively, provide the intended Win32 path to mount as a first argument and the POSIX path as the second argument.

Using the following command will remove all mount points.

    mount --remove-all-mounts

Using mount demonstrates mounting C:/cygwin/H-i686-pc-cygwin/bin to /bin (assuming /bin exists), as well as mounting \\pollux\home\joe\data to a /data network directory, making /bin/sh a valid shell, to satisfy make .

IMPORTANT!

With a bash shell, the forward slash will not work; substitute / or use single quotes.

Using mount

ls /bin /data
ls: /data: No such file or directory
mount C:\cygwin\H-i686-pc-cygwin\bin /bin
mount \\pollux\home\joe\data /data
Warning: /data does not exist!
mount
Device Directory Type Flags
\\pollux\home\joe\data /data native text!=binary
C:\cygwin\H-i686-pc-cygwin\bin /bin native text!=binary
D: /d native text!=binary
C: / native text!=binary
ls /bin/sh
/bin/sh

 

Text and Binary Modes with Cygwin

This section discusses the main distinctions between text and binary modes with UNIX and Microsoft Windows interoperability, and how Cygwin solves the problems.

On a UNIX system, when an application reads from a file it gets exactly what is in the file on disk and the same is true for writing to the file. The situation is different in the DOS and Microsoft Windows world where a file can be opened in one of two modes, either binary or text. In the binary mode, the system behaves exactly as in UNIX. However in text mode there are major differences:

  • On writing in text mode, a new line, NL ( \n , ^J ), is transformed into a carriage return/new line sequence, or CR ( \r , ^M ) NL.
  • On reading in text mode, a carriage return followed by a new line is deleted and a ^Z character signals the end of file.

The mode can be specified explicitly. In an ideal DOS and Microsoft Windows world, all programs using lines as records (such as bash , make , or sed ) would open files (changing the mode of their standard input and output) as text. All other programs (such as cat , cmp , or tr ) would use binary mode. In practice with Cygwin, programs that deal explicitly with object files specify binary mode (as is the case of od , which is helpful to diagnose CR problems). Most other programs (such as cat , cmp , tr ) use the default mode. The Cygwin system gives us some flexibility in deciding how files are to open when the mode is not specified explicitly:

  • If the file appears to reside on a file system that is mounted (that is, if its pathname starts with a directory displayed by mount ), then the default is specified by the mount flag.
  • The CYGWIN environment variable will affect a disk file when you are using stdio redirection from the Microsoft Windows prompt. Otherwise, the mode of the file is based on the mode specified by a --change-cygdrive-prefix call, as the following example shows (which makes the default mode be binary).

      mount -b --change-cygdrive-prefix /cygdrive

    If the file is a symbolic link, the mode of the target file system applies.

  • Pipes and non-file devices are always opened in binary mode.
  • When a Cygwin program is launched by a shell, its standard input, output, and error are in text mode by default. This can be overridden by setting the CYGWIN environment variable to 'binmode'.

    When redirecting, the Cygwin shells uses the first three rules. For these shells, the relevant value of CYGWIN is that at the time the shell was launched and not that at the time the program is executed.

    Non-Cygwin shells always pipe and redirect with binary mode. With non-Cygwin shells, the cat filename | program and program < filename commands are not equivalent when filename is on a text-mounted partition. To illustrate the various rules, the following example's script deletes carriage returns (CRs) from files by using the tr program, which can write only to standard output:

      #!/bin/sh
      # Remove \r from the files given as arguments
      for file in "$@"
      do
        CYGWIN=binmode sh -c "tr -d \\\"\\\r\\\" < '$file' > c:tmpfile.tmp"
        if [ "$?" = "0" ]
        then
          rm "$file"
          mv c:tmpfile.tmp "$file"
        fi
        done

    The script works irrespective of the mount because the second rule applies for the path, c:tmpfile.tmp . According to the fourth rule, CYGWIN must be set before invoking the shell. These precautions are necessary because tr does not set its standard output to binary mode. It would thus reintroduce \r when writing to a file on a text mounted partition. The desired behavior can also be obtained by using tr -d \r in a .bat file.

UNIX programs that have been written for maximum portability will know the difference between text and binary files and act appropriately under Cygwin. For those programs, the text mode default is a good choice. Programs included in official distributions should work well in the default mode.

Text mode makes it much easier to mix files between Cygwin and Microsoft Windows programs, since Microsoft Windows programs will usually use the carriage return/line feed (CR/LF) format. Unfortunately you may still have some problems with text mode. First, some of the utilities included with Cygwin do not yet specify binary mode when they should; cat will not work, for instance, with binary files (input will stop at ^Z , CRs will be introduced in the output). Second, you will introduce CRs in text files you write, causing problems when moving them back to a UNIX system.

If you are mounting a remote file system from a UNIX machine, or moving files back and forth to a UNIX machine, you can access them in binary mode since text files found there will normally be NL format anyway, and you would want any files put there by Cygwin programs to be stored in a format that the UNIX machine will understand. Remove CRs from all Makefiles and shell scripts and make sure that you only edit the files with DOS/Windows editors that can cope with binary mode files.

IMPORTANT!

You can decide this on a disk by disk basis (for example, mounting local disks in text mode and network disks in binary mode). You can also partition a disk, for example by mounting c: in text mode, and c:\home in binary mode.
File Permissions With Cygwin

On Windows 98 systems, files are always readable, and Cygwin uses the native read-only mode to determine if they are writable. Files are executable if the filename ends with a .bat, .com, or .exe file extension, or if #! starts. Consequently, chmod can only affect the w mode, whereas it silently ignores actions involving the other modes. Under NT, file permissions default to the same behavior as Windows 98 systems. However, there is optional functionality in Cygwin that can make file systems behave more like files for UNIX systems; for instance, use the ntea option to the CYGWIN environment variable (see Environment Variables for Cygwin). When using ntea , Cygwin will start with basic permissions, storing POSIX file permissions in NT Extended Attributes . On NTFS partitions, the attributes can be stored sensibly inside the normal NTFS filesystem structure. However, on a FAT partition, NT stores extended attributes in a flat file at the root of the EA DATA. SF. file partition, which can grow to extremely large sizes if you have a large number of files on the partition, slowing the system processes. In addition, the EA DATA. SF. file can only be deleted outside of Windows because of its in use status. For these reasons, the use of NT Extended Attributes is off by default in Cygwin. Specifying ntea in CYGWIN has no effect for Windows 98 systems. Under NT, the [ -w filename ] test is only true if filename is writable across the board, such as with a chmod +w filename call.

Special Cygwin File Names

This section discusses some special file naming usage by Cygwin.

  • DOS devices: Windows filenames invalid under Windows are also invalid under Cygwin. This means that base filenames such as AUX , COM1 , LPT1 or PRN cannot be used in a regular Cygwin Windows or POSIX path, even with an extension (prn.txt). However, the special names can be used as filename extensions (file.aux). You can use the special names as you would under DOS; for example, you can print on your default printer with the cat filename > PRN command (making sure to end with a Form Feed).
  • POSIX devices: do not create a POSIX /dev directory as it is automatically simulated within Cygwin. It supports the following devices: /dev/null , /dev/tty and /dev/comX (the serial ports). These devices cannot be seen with the ls /dev command, although commands such as ls /dev/tty work fine.
  • The .exe extension for executable program filenames end with .exe although the .exe extension is not necessary in a command, so that traditional UNIX names can be used. On the contrary, you cannot omit .bat and .com extensions. As a side effect, the ls filename declaration gives information about filename .exe if filename .exe exists and filename does not. In the same situation, call stat(" filename " ...) to give information about the filename .exe file.

    Differentiate any two files by examining their inodes.

    The GCC compiler produces a filename .exe executable when asked to produce filename , allowing many makefiles written for UNIX systems to work well under Cygwin. Unfortunately the install and strip commands do distinguish between filename and a filename .exe file. They fail when working on a non-existing filename even if filename .exe exists, thus breaking some makefiles. To solve this problem, write install and strip shell scripts to provide the .exe extension.

  • @pathname circumvents the limitations on shell line length in the native Windows command shells, allowing Cygwin programs to expand their arguments by starting with @ in a special way. If a file pathname exists, the @pathname argument expands recursively to the content of the program's pathname. Use double quotes in the file's content to delimit strings containing blank space.
Defining Windows Resources for Cygwin

windres reads a Windows resource file ( *.rc ) and converts it to a .res COFF file. The syntax and semantics of the input file are the same as for any other resource compiler; see any publication describing the Windows resource format for details.

windres compiles a .res file to include all the bitmaps, icons, and other resources you need, into one object file. Omitting the -O coff declaration would create a Windows .res format file without linkable COFF objects. Instead, windres produces a COFF object, for compatibility with how a linker can handle Windows resource files directly, maintaining the .res naming convention.

For more information on windres , see Using binutils in GNUPro Auxiliary Development Tools .

Building and Using DLLs with Cygwin

The following documentation provides an example of how to build a .dll file, using a single file, myprog .c , for the program, myprog .exe , and a single file, mydll .c , for the contents of the .dll file, mydll .dll , then compiling everything as objects.

gcc -shared myprog.c -o mydll .dll -e _ mydll _init@12

Now, when you build your program, you link against the import library, with declaration's like the following example's commands.

gcc myprog .o mydll .dll -o myprog .exe

Using GCC with Cygwin

This section discusses using the GNUPro compiler with Cygwin to compile as you would on UNIX.

To run the GNUPro compiler, use the following command in a shell console:

gcc hello.c -o hello.exe
hello.exe
Hello, World

Cygwin allows you to build programs with full access to the standard Windows 32-bit API, including the GUI functions (as defined in Microsoft publications); however, the process of building those applications is slightly different using the GNU tools instead of the Microsoft tools. Your sources will not need to change; just remove all __export attributes from functions and replace them as follows:

int foo (int) __ attribute __ (( __ dllexport __ ));

int
foo (int i)

For most cases, remove the __export attributes.

The Makefile is similar to any other UNIX-like or Cygwin Makefile. The only difference is that you use a gcc -mwindows declaration to link your program ( myapp .exe in the following example's script) into a GUI application instead of into a command line application.

myapp.exe : myapp.o myapp.res
       gcc -mwindows myapp.o myapp.res -o $@

myapp.res : myapp.rc resource.h
       windres $< -O coff -o $@

Debugging Cygwin Programs

Before you can debug your program, you need to prepare your program for debugging. Add a -g declaration to all the other flags you use when compiling your sources to objects, in order to add extra information to the objects (making them much bigger), and to provide critical information to the debugger regarding line numbers, variable names, and other useful things. These extra symbols and debugging data give your program information about the original sources so that the debugger can resolve the problems. Use declarations similar to the following:

gcc -g -O2 -c myapp.c
gcc -g myapp.c -o myapp

To invoke gdb , use the gdb myapp.exe declaration (substituting the executable file's name for myapp). The copyright text displays followed by the (gdb) prompt, from which you can enter commands such as run or help .

If your program crashes and you are trying to determine why it crashed, the best thing to do is type run and let your program run. After it crashes, you can use the where command to determine where it crashed, or the info locals call to see the values of all the local variables. The print declaration lets you examine individual variables or a line to which pointers point. If your program is doing something unexpected, use the break command to tell the debugger to stop your program when the debugging process gets to a specific function or line number.

Using the run command, stop your program at a breakpoint, and use other gdb commands to look at the state of your program at that point, to modify variables, and to step through your program's statements one at a time.

Use the help command to get a list of all the commands to use, or see Debugging with GDB in GNUPro Debugger Tools .

Environment Variables for Cygwin

Before starting bash , you must set some environment variables, some of which can also be set or modified inside bash . You have a .bat file where the most important ones are set before initially invoking bash. The fully editable .bat file installs by default in \..\cygwin\cygnus.bat and the Start menu points to it.

The most important environment variable is the CYGWIN variable. The CYGWIN variable is used to configure many global settings for the Cygwin runtime system. Initially you can leave CYGWIN unset or set it to tty using input like the following example's syntax in a DOS shell, before launching bash .

C:\..\> set CYGWIN=tty notitle

The PATH environment variable is used by Cygwin applications as a list of directories in which to search for executable files to run. Convert this environment variable, when a Cygwin process first starts, from a Microsoft Windows format ( C:\WinNT\system32;C:\WinNT ) to UNIX format ( /WinNT/system32:/WinNT ).

Set the PATH environment variable so that, before launching bash , it contains at least a bin directory: C:\..\cygwin\H-i686-pc-cygwin\bin .

make uses an environment variable, MAKE_MODE , for determining the use of Command.com or /bin/sh to run command lines. If you get errors from make with the /c not found message, set MAKE_MODE to UNIX with the following example's form.

C:\> set MAKE_MODE=UNIX
export MAKE_MODE=UNIX

The HOME environment variable is used by UNIX shells to determine the location of your home directory. This environment variable is converted from the Microsoft Windows format ( C:\home\bob ) to UNIX format ( /home/bob ) when a Cygwin process first starts. To prevent confusion, ensure that HOME and /etc/passwd agree on your home directory.

The TERM environment variable specifies your terminal type. It is set it to cygwin by default.

The LD_LIBRARY_PATH environment variable is used by the Cygwin function, dlopen () , as a list of directories to search for .dll files to load. This environment variable is converted from the Microsoft Windows format (that is, C:\WinNT\system32;C:\WinNT ) to UNIX format (that is, /WinNT/system32:/WinNT ) when a Cygwin process first starts.

The CYGWIN environment variable is used to configure many global settings for the Cygwin runtime system, using the following options.

IMPORTANT!

Each option is separated by others with a space. Many options can be turned off by prefixing with no (such as nobar or bar options).
  • ( no ) binmode
    If set, unspecified file opens by default to binary mode (no CR / LF or Ctrl+Z translations) instead of text mode. This option must be set before starting a Cygwin shell to have an effect on redirection. On by default.
  • ( no ) envcache
    If set, environment variable conversions between Win32 and POSIX are cached. Note that this is may cause problems if the mount table changes, as the cache is not invalidated and may contain values that depend on the previous mount table contents. Defaults to set.
  • ( no ) export
    If set, the final values of these settings are re-exported to the environment as $CYGWIN again.
  • ( no ) title
    If set, the title bar reflects the currently running program's name. Off by default.
  • ( no ) glob
    If set, command line arguments containing UNIX-style file wildcard characters (brackets, question mark, asterisk) are expanded into lists of files that match those wildcards. This is applicable only to programs running from a windows command line prompt. Set by default.
  • ( no ) tty
    If set, Cygwin enables extra support (such as termios ) for UNIX-like tty calls. Off by default.
  • ( no ) ntea
    If set, use the full Microsoft Windows NT Extended Attributes to store UNIX-like inode information.

WARNING!

ntea may create additional large files on non-NTFS partitions. ntea only operates under Microsoft Windows NT. Off by default.
  • ( no ) smbntsec
    If smbntsec is set, use ntsec on remote drives as well (this is the default). If you encounter problems with Microsoft Windows NT shares or Samba drives, setting this to nosmbntsec could help. In that case the permission and owner/group information is faked as on FAT partitions. A reason for a non-working ntsec on remote drives could be insufficient permissions of the users. Since the needed user rights are somewhat dangerous, it is not always an option to grant those rights to users. However, this should not be a problem in Microsoft Windows NT domain environments. Default is smbntsec .
  • ( no ) reset_com
    If reset_com is set, serial ports are reset to 9600-8-N-1 with no flow control when used. This is done at open time and when handles are inherited. Default is reset_com .
  • ( no ) strip_title
    If strip_title is set, strips directory part off the window title, if any. Defaults to strip_title .
  • ( no ) title
    If title is set, the title bar reflects the name of the program currently running. Under Microsoft Microsoft Windows 98, the title bar is always enabled and it is stripped by default, but this is because of the way Microsoft Windows 98 works. In order not to strip, specify title or title nostrip_title . Defaults to nostrip_title .
  • ( no ) ntsec
    If ntsec is set, use the Microsoft Windows NT security model to set UNIX-like permissions on files and processes. The file permissions can only be set on NTFS partitions. FAT does not support the Microsoft Windows NT file security (for more information, see http://sources.redhat.com/cygwin/ ). Defaults to be not set.
Special Options with the CYGWIN Environment Variable

The CYGWIN environment variable uses the following options. Each option is separated by others with a space. To turn off any option, prefix it with no (such as the nobinmode for the binmode option).

  • binmode
    Opens an unspecified file by default in binary mode, with no CR / LF or Ctrl+Z ( ^Z ) translations, instead of text mode. binmode must be set before starting a Cygwin shell to have an effect on redirection.
  • envcache
    Caches environment variable conversions (between Win32 and POSIX); this may cause problems if the mount table changes, as the cache is not invalidated and may contain values that depend on the previous mount table contents.
  • export
    Re-exports the final values of these settings to the environment as $CYGWIN again.
  • title
    Makes the title bar provide the currently running program's name.
  • strip_title
    Strips the directory part off the window title.
  • glob
    Expands command line arguments containing UNIX-style file wildcard characters (brackets, question mark, asterisk) into lists of files that match those wildcards. Applicable only to programs running from a Windows command line prompt.
  • tty
    Enables extra support (such as termios ) for UNIX-like tty calls. Off by default.
  • strace= n [: cache ][, filename ]
    Configures system tracing. Off by default, setting various bits in n (a bit flag) enables various types of system messages. Setting n to 1 enables most messages. Other values can be found in the sys/strace.h directory. : cache lets you specify how many lines to cache before flushing the output; for example, type strace=1:20 to cache 20 lines. filename lets you send messages to a file instead of to the shell's buffer.
  • ntea
    Allows use of full NT Extended Attributes to store UNIX-like inode information.

WARNING!

The ntea option only operates under Windows NT. It may create additional large files on non-NTFS partitions.
  • reset_com
    If set, serial ports are reset to 9600-8-N-1 with no flow control when used. This is done at open time and when handles are inherited.

Using RedBoot for Remote Debugging

If you are trying to debug a program running the GNU debugger, GDB, you can use remote debugging with RedBoot. For details about debugging with RedBoot, a wide set of tools for downloading and executing programs on embedded target systems, see: http://sources.redhat.com/ecos/docs-latest/redboot/redboot.html RedBoot helps with manipulating a target system's environment, for both product development (debug support) and for end product deployment (flash and network booting).

Debug with Insight

The following documentation serves as a general reference for debugging with GNUPro Toolkit's graphical user interface, Insight; for more information, see Insight's Help menu for discussion of general functionality and use of menus, buttons or other features; see also "Insight, GDB's Alternative Interface" and the "Examples of Debugging with Insight" documentation in GNUPro Debugger Tools (see http://www.redhat.com/docs/manuals/gnupro/ ).

IMPORTANT!

Insight works as the default means for debugging; to disable the GUI, use the gdb -nw command for non-windowing command line work.
  1. From a shell window, enter the following input:
    1. gdb

    Insight launches, displaying the Source Window (Source Window, the main window interface for Insight).

    Source Window , the main window interface for Insight

     

    The menu selections in the Source Window are File , Run , View , Control , Preferences , and Help . To work with the other windows for debugging purposes specific to your project, use the View menu or the buttons in the toolbar.

  2. To open a specific file as a project for debugging, select File Open in the Source Window . The file's contents will then pass to the GDB interpreter.
  3. To start debugging, click the Run button (Run button) from the Source Window.
  4. Run button

       

    When the debugger runs, the button turns into the Stop button (Stop button).

    Stop button

       

    The Stop button interrupts the debugging process for a project, provided that the underlying hardware and protocols support such interruptions. Generally, machines that are connected to boards cannot interrupt programs on those boards. In such cases, a dialog box appears as a prompt asking if you want to abandon the session and if the debugger should detach from the target.

    For an embedded project, click Run ; then click Continue (Continue button); this ensures configuration between the target and the host is clear so that the debugging tools will work effectively.

    Continue button

       

    WARNING!

    When debugging a target, do not click on the Run button during an active debugging process, since using the Run button will effectively restart the session with all work unrecoverable.

    For more information on Insight, see its Help menu. For examples of debugging session procedures for using Insight, see the following documentation (the content assumes familiarity with debugging procedures).

    To specify how source code appears and to change debugging settings, from the Preferences menu, select Source .

    IMPORTANT!

    To add identification codes to the debugger's table of processors, see the GDB Internals documentation, distributed with the source code.
    Selecting and Examining a Source File

    To select a source file, or to specify what to display when examining a source file when debugging, use the following processes.

    1. Select a source file from the file drop-down list with the Source Window ( hello.c in Source file selection ).
    2. Source file selection

       
    3. Select a function from the function drop-down list to the right of the file drop-down list, or type its name in the text field above the list to locate the function (in Search for functions , see the executable line 11, where the main function displays).
    4. Search for functions

       
    5. Use the Enter key to repeat a previous search. Use the Shift and Enter keys simultaneously to search backwards.
    6. Type @ with a number in the search text box in the top right of the Source Window . Press Enter . Searching for a specific line in source code shows a jump to line 8 in the hello.c source file.
    7. Searching for a specific line in source code

       
    Setting Breakpoints and Viewing Local Variables

    A breakpoint can be set at any executable line in a source file.

    Executable lines are marked by a minus sign in the left margin of the Source Window . When the cursor is over a minus sign for an executable line, the cursor changes to a circle. When the cursor is in this state, a breakpoint can be set. The Breakpoints window is for managing the breakpoints: disabling them, enabling them, or erasing them; an enabled breakpoint is one for which the debugging session will stop, a disabled breakpoint is one which the debugging session ignores.

    The following exercise steps you through setting four breakpoints in a function, as well as running the program and viewing changed values in local variables.

    1. To set a breakpoint, have an active the hello.c source file open in the Source Window , and, with the cursor over a minus sign on a line, click the left mouse button. When you click on the minus sign, a red square appears for the line, signifying a set breakpoint (see the highlighted line 15 in Results of setting breakpoint for line 17 for a set breakpoint).
    2. Clicking the line again will remove the breakpoint.

      Results of setting breakpoint for line 17

       
    3. Open the Breakpoints window ( Breakpoints window ) using the Breakpoints button from the Source Window. See a line with a check box in the window appears showing that you set a breakpoint for a corresponding line in the Source Window frame. With the cursor over a breakpoint, a breakpoint information balloon displays in the Source Window (the information details the breakpoint, its address, its associated source file and line, its state, whether enabled, temporary, or erased, and the association to all threads for which the breakpoint will cause a stop; see also Setting Breakpoints on Multiple Threads for details about threads).
    4. Breakpoints window

       
    5. The debugger ignores disabled breakpoints, lines indicated having a black square over them in the Source Window frame (see line 17 in Results of setting breakpoint for line 17). Click on a breakpoint to disable the breakpoint. Results of disabling a breakpoint at line 17 shows the results in the Breakpoints window of disabling a breakpoint. Re-enable a breakpoint at a line by clicking on the check box in the Breakpoints window. Once a breakpoint is enabled for a line, it will again have a red square in the Source Window frame.
    6. Results of disabling a breakpoint at line 17

       
    7. Repeat the process to set breakpoints at specific lines.
    8. Click Run in the Source Window to start the executable. The debugger runs until it finds a breakpoint. When the target stops at a breakpoint, the debugger highlights a line (see highlighted line 17 in Executable after changing local variable's values, where the debugging stopped). For more information about breakpoints, see the standard documentation for Insight: "Insight, GDB's Alternative Interface" and the "Examples of Debugging with Insight" documentation in GNUPro Debugger Tools ; see http://www.redhat.com/docs/manuals/gnupro/ ).
    9. Open the Local Variables window by clicking its button in the tool bar for the Source Window ; the Local Variables window displays the values of the variables (see Local Variables window for the b variable in hello.c).
    10. Local Variables window

       
    11. Click the Continue button in the Source Window tool bar to move to the next breakpoint. The variables that changed value turn color in the Local Variables window (see results in Local Variables window after setting breakpoints for the b variable in hello.c ).
    12. Local Variables window after setting breakpoints

       
    13. Click the Continue button two more times to step through the next two breakpoints (until execution stops at line 17) and see the values of the local variables change (compare results from hello.c in Results of setting breakpoint for line 17 and results in Executable after changing local variable's values ).
    14. Executable after changing local variable's values

       
    Setting Breakpoints on Multiple Threads

    Select threads and set breakpoints on one or more threads when debugging a multi-threaded application with Insight.

    WARNING!

    Working with multiple threads does not function similarly on all embedded targets. When debugging C++ code, for instance, breakpoints and exceptions may not work on multiple threads.

    A process can have multiple threads running concurrently, each performing a different task, such as waiting for events or something time-consuming that a program does not need to complete before resuming. The thread debugging facility allows you to observe all threads while your program runs. However, whenever the debugging process is active, one thread in particular is always the focus of debugging. This thread is called the current thread. The precise semantics of threads and the use of threads differs depending on operating systems. In general, the threads of a single program are like multiple processes, except that they share one address space (that is, they can all examine and modify the same variables). Additionally, each thread has its own registers and execution stack and, perhaps, private memory.

    1. In the Source Window , right click on an executable line without a breakpoint to open the breakpoint pop-up menu (Breakpoint pop-up menu in the Source Window).
    2. Breakpoint pop-up menu in the Source Window

       
    3. Select Set Breakpoint on Thread(s) to display a window allowing you to choose the threads with which you set breakpoints. The Processes window (see Processes window with threads), available from the Source Window 's View Threads List menu, displays all the available threads in the system and allows you to switch the current thread. See Debugging with GDB in GNUPro Debugger Tools (see http://www.redhat.com/docs/manuals/gnupro/ ) for more general information about threads.
    4. Processes window with threads

       

       


1. ISO/IEC 9945-1:1996 (ANSI/IEEE Std 1003.1, 1996 Edition); POSIX Part 1: System Application Program Interface (API) [C Language].