This will replace the current goal of 'make qemu' with 'make run' and moves Qemu handling into its own file and into the boards instead of being architecture specific. We should be able to add new boards that support some other type of emulation (by adding scripts/Makefile.<emu type>) and allow the board to define their own options for the use type of emulation. 'make qemu' will still work, however it will be deprecated, starting with this commit it is recommended to use 'make run'. Jira: ZEP-359 Change-Id: I1cacd56b4ec09421a58cf5d010e22e9035214df6 Signed-off-by: Anas Nashif <anas.nashif@intel.com>
778 lines
25 KiB
ReStructuredText
778 lines
25 KiB
ReStructuredText
.. _application:
|
|
|
|
Application Development Primer
|
|
##############################
|
|
|
|
|
|
Overview
|
|
========
|
|
The Zephyr Kernel's build system is based on the Kbuild system used in the
|
|
Linux kernel.
|
|
|
|
The build system is an application-centric system and requires an application
|
|
build to initiate building the kernel source tree. The application build drives
|
|
the configuration and build process of both the application and kernel,
|
|
compiling them into a single binary.
|
|
|
|
The Zephyr Kernel's base directory hosts the kernel source code, the
|
|
configuration options, and the kernel build definitions.
|
|
|
|
The files in the application directory links the kernel with the
|
|
application. It hosts the definitions of the application, for example,
|
|
application-specific configuration options and the application's source code.
|
|
|
|
An application in the simplest form has the following structure:
|
|
|
|
* **Application source code files**: An application typically provides one
|
|
or more application-specific files, written in C or assembly language. These
|
|
files are usually located in a sub-directory called :file:`src`.
|
|
|
|
* **Kernel configuration files**: An application typically provides
|
|
a configuration file (:file:`.conf`) that specifies values for one or more
|
|
kernel configuration options. If omitted, the application's existing kernel
|
|
configuration option values are used; if no existing values are provided,
|
|
the kernel's default configuration values are used.
|
|
|
|
* **Makefile**: This file tells the build system where to find the files
|
|
mentioned above, as well as the desired target board configuration.
|
|
|
|
Once the application has been defined, it can be built with a single ``make``
|
|
call.
|
|
The results of the build process are located in a sub-directory called
|
|
:file:`outdir/BOARD`. This directory contains the files generated by the build
|
|
process, the most notable of which are listed below.
|
|
|
|
* The :file:`.config` file that contains the configuration settings
|
|
used to build the application.
|
|
|
|
* The various object files (:file:`.o` files and :file:`.a` files) containing
|
|
custom-built kernel and application-specific code.
|
|
|
|
* The :file:`zephyr.elf` file that contains the final combined application and
|
|
kernel binary.
|
|
|
|
|
|
|
|
Application Structure
|
|
=====================
|
|
|
|
|
|
Create one directory for your application and a sub-directory for the
|
|
application's source code; this makes it easier to organize directories and
|
|
files in the structure that the kernel expects.
|
|
|
|
#. Create an application directory structure outside of the kernel's
|
|
installation directory tree. Often this is your workspace directory.
|
|
|
|
#. In a console terminal, navigate to a location where you want your
|
|
application to reside.
|
|
|
|
#. Create the application's directory, enter:
|
|
|
|
.. code-block:: console
|
|
|
|
$ mkdir app
|
|
|
|
.. note::
|
|
|
|
This directory and the path to it, are referred to in the documentation
|
|
as :file:`~/app`.
|
|
|
|
#. Create a source code directory in your :file:`~/app`, enter:
|
|
|
|
.. code-block:: console
|
|
|
|
$ cd app
|
|
$ mkdir src
|
|
|
|
The source code directory :file:`~/app/src` is created.
|
|
|
|
.. code-block:: console
|
|
|
|
-- app
|
|
|-- src
|
|
|
|
|
|
Application Definition
|
|
======================
|
|
|
|
An application is integrated into the build system by including the Makefile.inc
|
|
file provided.
|
|
|
|
.. code-block:: make
|
|
|
|
include $(ZEPHYR_BASE)/Makefile.inc
|
|
|
|
The following predefined variables configure the development project:
|
|
|
|
* :makevar:`ZEPHYR_BASE`: Sets the path to the kernel's base directory.
|
|
This variable is usually set by the :file:`zephyr_env.sh` script.
|
|
It can be used to get the kernel's base directory, as used in the
|
|
Makefile.inc inclusion above, or it can be overridden to select an
|
|
specific instance of the kernel.
|
|
|
|
* :makevar:`PROJECT_BASE`: Provides the developer's application project
|
|
directory path. It is set by the :file:`Makefile.inc` file.
|
|
|
|
* :makevar:`SOURCE_DIR`: Overrides the default value for the application's
|
|
source code directory. The developer source code directory is set to
|
|
:file:`$(PROJECT_BASE/)src/` by default. This directory name should end
|
|
with slash **'/'**.
|
|
|
|
* :makevar:`BOARD`: Selects the board that the application's
|
|
build will use for the default configuration.
|
|
|
|
* :makevar:`CONF_FILE`: Indicates the name of a configuration fragment file.
|
|
This file includes the kconfig configuration values that override the
|
|
default configuration values.
|
|
|
|
* :makevar:`O`: Optional. Indicates the output directory that Kconfig uses.
|
|
The output directory stores all the files generated during the build
|
|
process. The default output directory is the :file:`$(PROJECT_BASE)/outdir`
|
|
directory.
|
|
|
|
|
|
Makefiles
|
|
=========
|
|
|
|
Overview
|
|
--------
|
|
|
|
The build system defines a set of conventions for the correct use of Makefiles
|
|
in the kernel source directories. The correct use of Makefiles is driven by the
|
|
concept of recursion.
|
|
|
|
In the recursion model, each Makefile within a directory includes the source
|
|
code and any subdirectories to the build process. Each subdirectory follows
|
|
the same principle. Developers can focus exclusively in their own work. They
|
|
integrate their module with the build system by adding a very simple Makefile
|
|
following the recursive model.
|
|
|
|
.. _makefile_conventions:
|
|
|
|
Makefile Conventions
|
|
--------------------
|
|
|
|
The following conventions restrict how to add modules and Makefiles to the
|
|
build system. These conventions ensure the correct implementation of the
|
|
recursive model.
|
|
|
|
* Each source code directory must contain a single Makefile. Directories
|
|
without a Makefile are not considered source code directories.
|
|
|
|
* The scope of every Makefile is restricted to the contents of that directory.
|
|
A Makefile can only make a direct reference to files and subdirectories on the
|
|
same level or below.
|
|
|
|
* Makefiles list the object files that are included in the link process. The
|
|
build system finds the source file that generates the object file by matching
|
|
the object file name to the source file.
|
|
|
|
* Parent directories add their child directories into the recursion model.
|
|
|
|
* The root Makefile adds the directories in the kernel base directory into the
|
|
recursion model.
|
|
|
|
Adding Source Files
|
|
-------------------
|
|
|
|
The Makefile must refer the source build indirectly, specifying the object file
|
|
that results from the source file using the :literal:`obj-y` variable. For
|
|
example, if the file that we want to add is a C file named :file:`<file>.c` the
|
|
following line should be added in the Makefile:
|
|
|
|
.. code-block:: make
|
|
|
|
obj-y += <file>.o
|
|
|
|
.. note::
|
|
|
|
The same method applies for assembly files with the .S extension.
|
|
|
|
Source files can be added conditionally using configuration options. For
|
|
example, if the option ``CONFIG_VAR`` is set and it implies that a source
|
|
file must be added in the compilation process, then the following line adds the
|
|
source code conditionally:
|
|
|
|
.. code-block:: none
|
|
|
|
obj-$(CONFIG_VAR) += <file>.o
|
|
|
|
Adding Directories
|
|
------------------
|
|
|
|
Add a subdirectory to the build system by editing the Makefile in its
|
|
directory. The subdirectory is added using the :literal:`obj-y` variable. The
|
|
correct syntax to add a subdirectory into the build queue is:
|
|
|
|
.. code-block:: make
|
|
|
|
obj-y += <directory_name>/
|
|
|
|
The backslash at the end of the directory name signals the build system that a
|
|
directory, and not a file, is being added to the build queue.
|
|
|
|
The conventions require us to add only one directory per line and never to mix
|
|
source code with directory recursion in a single :literal:`obj-y` line. This
|
|
helps keep the readability of the Makefile by making it clear when an item adds
|
|
an additional lever of recursion.
|
|
|
|
Directories can also be conditionally added:
|
|
|
|
.. code-block:: none
|
|
|
|
obj-y-$(CONFIG_VAR) += <directory_name>/
|
|
|
|
The subdirectory must contain its own Makefile following the rules described in
|
|
:ref:`makefile_conventions`.
|
|
|
|
|
|
Application Makefile
|
|
====================
|
|
|
|
Create an application Makefile to define basic information, such as the board
|
|
configuration used by the application. The build system uses the Makefile to
|
|
build a :file:`zephyr.elf` image that contains both the application and the
|
|
kernel libraries.
|
|
|
|
#. Open the :file:`Makefile` and add the following mandatory
|
|
entries using any standard text editor.
|
|
|
|
.. note::
|
|
|
|
Ensure that there is a space before and after each ``=``.
|
|
|
|
#. Add the name of the default board configuration for your application on a
|
|
new line:
|
|
|
|
.. code-block:: make
|
|
|
|
BOARD = board_configuration_name
|
|
|
|
The supported boards can be found in :ref:`boards`.
|
|
|
|
#. Add the name of the default kernel configuration file for your
|
|
application on a new line:
|
|
|
|
.. code-block:: make
|
|
|
|
CONF_FILE ?= kernel_configuration_name
|
|
|
|
#. Include the mandatory :file:`Makefile` on a new line:
|
|
|
|
.. code-block:: make
|
|
|
|
include ${ZEPHYR_BASE}/Makefile.inc
|
|
|
|
#. Save and close the :file:`Makefile`.
|
|
|
|
|
|
Below is an example Makefile:
|
|
|
|
.. code-block:: make
|
|
|
|
BOARD = qemu_x86
|
|
CONF_FILE = prj.conf
|
|
|
|
include ${ZEPHYR_BASE}/Makefile.inc
|
|
|
|
Application Configuration
|
|
=========================
|
|
|
|
The application's kernel is configured using a set of configuration options
|
|
that can be customized for application-specific purposes.
|
|
The Zephyr build system takes a configuration option's value from the first
|
|
source in which it is specified.
|
|
|
|
The available sources are (in order):
|
|
|
|
#. The application's current configuration. (i.e. The :file:`.config` file.)
|
|
|
|
#. The application's default configuration. (i.e. The :file:`.conf` file.)
|
|
|
|
#. The board configuration used by the application.
|
|
(i.e. The board's :file:`.defconfig` file.)
|
|
|
|
#. The kernel's default configuration.
|
|
(i.e. One of the kernel's :file:`Kconfig` files.)
|
|
|
|
For information on available kernel configuration options, including
|
|
inter-dependencies between options, see the :ref:`configuration`.
|
|
|
|
Default Board Configuration
|
|
---------------------------
|
|
|
|
An application's :file:`.conf` file defines its default kernel configuration.
|
|
The settings in this file override or augment the board configuration settings.
|
|
|
|
The board configuration settings can be viewed
|
|
in :file:`\$ZEPHYR_BASE/boards/ARCHITECTURE/BOARD/BOARD_defconfig`.
|
|
|
|
.. note::
|
|
|
|
When the default board configuration settings are sufficient for your
|
|
application, a :file:`.conf` file is not needed. Skip ahead to
|
|
:ref:`override_kernel_conf`.
|
|
|
|
|
|
#. Navigate to the :file:`app`, and create the :file:`prj.conf` file. Enter:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ vim prj.conf
|
|
|
|
The default name is :file:`prj.conf`. The filename must match the
|
|
``CONF_FILE`` entry in the application :file:`Makefile`.
|
|
|
|
#. Edit the file and add the appropriate configuration entries.
|
|
|
|
a) Add each configuration entry on a new line.
|
|
|
|
b) Begin each entry with ``CONFIG_``.
|
|
|
|
c) Ensure that each entry contains no spaces
|
|
(including on either side of the = sign).
|
|
|
|
d) Use a # followed by a space to comment a line.
|
|
|
|
The example below shows a comment line and a board
|
|
configuration override in the :file:`prj.conf`.
|
|
|
|
.. code-block:: c
|
|
|
|
# Enable printk for debugging
|
|
CONFIG_PRINTK=y
|
|
|
|
#. Save and close the file.
|
|
|
|
.. _override_kernel_conf:
|
|
|
|
Overriding Default Configuration
|
|
--------------------------------
|
|
|
|
Override the default board and kernel configuration to temporarily alter the
|
|
application's configuration, perhaps to test the effect of a change.
|
|
|
|
.. note::
|
|
|
|
If you want to permanently alter the configuration you
|
|
should revise the :file:`.conf` file.
|
|
|
|
Configure the kernel options using a menu-driven interface. While you can add
|
|
entries manually, using the configuration menu is a preferred method.
|
|
|
|
|
|
#. Run the :command:`make menuconfig` rule to launch the menu-driven interface.
|
|
|
|
a) In a terminal session, navigate to the application directory
|
|
(:file:`~/app`).
|
|
|
|
b) Enter the following command:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ make [BOARD=<type>] menuconfig
|
|
|
|
A question-based menu opens that allows you to set individual configuration
|
|
options.
|
|
|
|
.. image:: figures/app_kernel_conf_1.png
|
|
:width: 400px
|
|
:align: center
|
|
:height: 375px
|
|
:alt: Main Configuration Menu
|
|
|
|
#. Set kernel configuration values using the following
|
|
key commands:
|
|
|
|
* Use the arrow keys to navigate within any menu or list.
|
|
|
|
* Press :kbd:`Enter` to select a menu item.
|
|
|
|
* Type an upper case :kbd:`Y` or :kbd:`N` in the
|
|
square brackets :guilabel:`[ ]` to
|
|
enable or disable a kernel configuration option.
|
|
|
|
* Type a numerical value in the round brackets :guilabel:`( )`.
|
|
|
|
* Press :kbd:`Tab` to navigate the command menu at the bottom of the display.
|
|
|
|
.. note::
|
|
|
|
When a non-default entry is selected for options that are nonnumerical,
|
|
an asterisk :kbd:`*` appears between the square brackets in the display.
|
|
There is nothing added added the display when you select the option's
|
|
default.
|
|
|
|
#. For information about any option, select the option and tab to
|
|
:guilabel:`<Help >` and press :kbd:`Enter`.
|
|
|
|
Press :kbd:`Enter` to return to the menu.
|
|
|
|
#. After configuring the kernel options for your application, tab to
|
|
:guilabel:`< Save >` and press :kbd:`Enter`.
|
|
|
|
The following dialog opens with the :guilabel:`< Ok >` command selected:
|
|
|
|
.. image:: figures/app_kernel_conf_2.png
|
|
:width: 400px
|
|
:align: center
|
|
:height: 100px
|
|
:alt: Save Configuration Dialog
|
|
|
|
|
|
#. Press :kbd:`Enter` to save the kernel configuration options to the default
|
|
file name; alternatively, type a file name and press :kbd:`Enter`.
|
|
|
|
Typically, you will save to the default file name unless you are
|
|
experimenting with various configuration scenarios.
|
|
|
|
An :file:`outdir` directory is created in the application directory. The
|
|
outdir directory contains symbolic links to files under
|
|
:file:`\$ZEPHYR_BASE`.
|
|
|
|
.. note::
|
|
|
|
At present, only a :file:`.config` file can be built. If you have saved
|
|
files with different file names and want to build with one of these,
|
|
change the file name to :file:`.config`. To keep your original
|
|
:file:`.config`, rename it to something other than :file:`.config`.
|
|
|
|
Kernel configuration files, such as the :file:`.config` file, are saved
|
|
as hidden files in :file:`outdir`. To list all your kernel configuration
|
|
files, enter :command:`ls -a` at the terminal prompt.
|
|
|
|
The following dialog opens, displaying the file name the configuration
|
|
was saved to.
|
|
|
|
.. image:: figures/app_kernel_conf_3.png
|
|
:width: 400px
|
|
:align: center
|
|
:height: 150px
|
|
:alt: Saved Configuration Name Dialog
|
|
|
|
#. Press :kbd:`Enter` to return to the options menu.
|
|
|
|
#. To load any saved kernel configuration file, tab to :guilabel:`< Load >` and
|
|
press :kbd:`Enter`.
|
|
|
|
The following dialog opens with the :guilabel:`< Ok >` command selected:
|
|
|
|
.. image:: figures/app_kernel_conf_4.png
|
|
:width: 400px
|
|
:align: center
|
|
:height: 175px
|
|
:alt: Configuration File Load Dialog
|
|
|
|
#. To load the last saved kernel configuration file, press :guilabel:`< Ok >`,
|
|
or to load another saved configuration file, type the file name, then select
|
|
:guilabel:`< Ok >`.
|
|
|
|
#. Press :kbd:`Enter` to load the file and return to the main menu.
|
|
|
|
#. To exit the menu configuration, tab to :guilabel:`< Exit >` and press
|
|
:kbd:`Enter`.
|
|
|
|
The following confirmation dialog opens with the :guilabel:`< Yes >`
|
|
command selected.
|
|
|
|
.. image:: figures/app_kernel_conf_5.png
|
|
:width: 400px
|
|
:align: center
|
|
:height: 100px
|
|
:alt: Exit Dialog
|
|
|
|
#. Press :kbd:`Enter` to retire the menu display and return to the console
|
|
command line.
|
|
|
|
Application-Specific Code
|
|
=========================
|
|
|
|
Application-specific source code files are normally added to the application's
|
|
:file:`src` directory. If the application adds a large number of files the
|
|
developer can group them into sub-directories under :file:`src`, to whatever
|
|
depth is needed. The developer must supply a :file:`Makefile` for the
|
|
:file:`src` directory, as well as for each sub-directory under :file:`src`.
|
|
|
|
.. note::
|
|
|
|
These Makefiles are distinct from the top-level application Makefile
|
|
that appears in :file:`~/app`.
|
|
|
|
Application-specific source code should not use symbol name prefixes that have
|
|
been reserved by the kernel for its own use. For more information, see
|
|
|
|
`Naming Conventions <https://wiki.zephyrproject.org/view/Coding_conventions#Naming_Conventions>`_.
|
|
|
|
|
|
The following requirements apply to all Makefiles in the :file:`src`
|
|
directory, including any sub-directories it may have.
|
|
|
|
* During the build process, Kbuild identifies the source files to compile
|
|
into object files by matching the file names identified in
|
|
the application's Makefile(s).
|
|
|
|
.. important::
|
|
|
|
A source file that is not referenced by any Makefile is not included
|
|
when the application is built.
|
|
|
|
* A Makefile cannot directly reference source code. It can only
|
|
reference object files (:file:`.o` files) produced from source code files.
|
|
|
|
* A Makefile can only reference files in its own directory or in the
|
|
sub-directories of that directory.
|
|
|
|
* A Makefile may reference multiple files from a single-line entry.
|
|
However, a separate line must be used to reference each directory.
|
|
|
|
|
|
|
|
#. Create a directory structure for your source code in :file:`src`
|
|
and add your source code files to it.
|
|
|
|
#. Create a :file:`Makefile` in the :file:`src` directory. Then create
|
|
an additional :file:`Makefile` in each of the sub-directories under
|
|
the :file:`src` directory, if any.
|
|
|
|
a) Use the following syntax to add file references:
|
|
|
|
.. code-block:: make
|
|
|
|
obj-y += file1.o file2.o
|
|
|
|
b) Use the following syntax to add directory references:
|
|
|
|
.. code-block:: make
|
|
|
|
obj-y += directory_name/**
|
|
|
|
|
|
This example is taken from the Philosopher's Sample. To examine this file in
|
|
context, navigate to: :file:`\$ZEPHYR_BASE/samples/philosophers/src`.
|
|
|
|
.. code-block:: make
|
|
|
|
obj-y = main.o
|
|
|
|
|
|
|
|
Build an Application
|
|
====================
|
|
|
|
The Zephyr build system compiles and links all components of an application
|
|
into a single application image that can be run on simulated hardware or real
|
|
hardware.
|
|
|
|
|
|
#. Navigate to the application directory :file:`~/app`.
|
|
|
|
#. Enter the following command to build the application's :file:`zephyr.elf`
|
|
image using the configuration settings for the board type specified
|
|
in the application's :file:`Makefile`.
|
|
|
|
.. code-block:: console
|
|
|
|
$ make
|
|
|
|
If desired, you can build the application using the configuration settings
|
|
specified in an alternate :file:`.conf` file using the :code:`CONF_FILE`
|
|
parameter. These settings will override the settings in the application's
|
|
:file:`.config` file or its default :file:`.conf` file. For example:
|
|
|
|
.. code-block:: console
|
|
|
|
$ make CONF_FILE=prj.alternate.conf
|
|
|
|
If desired, you can build the application for a different board type than the
|
|
one specified in the application's :file:`Makefile` using the :code:`BOARD`
|
|
parameter. For example:
|
|
|
|
.. code-block:: console
|
|
|
|
$ make BOARD=arduino_101
|
|
|
|
Both the :code:`CONF_FILE` and :code:`BOARD` parameters can be specified
|
|
when building the application.
|
|
|
|
Rebuilding an Application
|
|
=========================
|
|
|
|
Application development is usually fastest when changes are continually tested.
|
|
Frequently rebuilding your application makes debugging less painful
|
|
as the application becomes more complex. It's usually a good idea to
|
|
rebuild and test after any major changes to the application's source files,
|
|
Makefiles, or configuration settings.
|
|
|
|
.. important::
|
|
|
|
The Zephyr build system rebuilds only the parts of the application image
|
|
potentially affected by the changes. Consequently, rebuilding an application
|
|
is often significantly faster than building it the first time.
|
|
|
|
Sometimes the build system doesn't rebuild the application correctly
|
|
because it fails to recompile one or more necessary files. You can force
|
|
the build system to rebuild the entire application from scratch with the
|
|
following procedure:
|
|
|
|
|
|
#. Navigate to the application directory :file:`~/app`.
|
|
|
|
#. Enter the following command to delete the application's generated files
|
|
for the specified board type, except for the :file:`.config` file that
|
|
contains the application's current configuration information.
|
|
|
|
.. code-block:: console
|
|
|
|
$ make [BOARD=<type>] clean
|
|
|
|
Alternatively, enter the following command to delete *all* generated files
|
|
for *all* board types, including the :file:`.config` files that contain
|
|
the application's current configuration information for those board types.
|
|
|
|
.. code-block:: console
|
|
|
|
$ make pristine
|
|
|
|
#. Rebuild the application normally following the steps specified
|
|
in `Build an Application`_ above.
|
|
|
|
|
|
|
|
Run an Application
|
|
==================
|
|
|
|
An application image can be run on real or emulated hardware. The kernel has
|
|
built-in emulator support for QEMU. It allows you to run and test an application
|
|
virtually, before (or in lieu of) loading and running it on actual target
|
|
hardware.
|
|
|
|
#. Open a terminal console and navigate to the application directory
|
|
:file:`~/app`.
|
|
|
|
#. Enter the following command to build and run the application
|
|
using a QEMU-supported board configuration, such as qemu_cortex_m3 or
|
|
qemu_x86.
|
|
|
|
.. code-block:: console
|
|
|
|
$ make [BOARD=<type> ...] run
|
|
|
|
The Zephyr build system generates a :file:`zephyr.elf` image file
|
|
and then begins running it in the terminal console.
|
|
|
|
#. Press :kbd:`Ctrl A, X` to stop the application from running
|
|
in QEMU.
|
|
|
|
The application stops running and the terminal console prompt
|
|
redisplays.
|
|
|
|
Application Debugging
|
|
=====================
|
|
|
|
This section is a quick hands-on reference to start debugging your
|
|
application with QEMU. Most content in this section is already covered on
|
|
`QEMU`_ and `GNU_Debugger`_ reference manuals.
|
|
|
|
.. _QEMU: http://wiki.qemu.org/Main_Page
|
|
|
|
.. _GNU_Debugger: http://www.gnu.org/software/gdb
|
|
|
|
In this quick reference you find shortcuts, specific environmental variables and
|
|
parameters that can help you to quickly set up your debugging environment.
|
|
|
|
The simplest way to debug an application running in QEMU is using the GNU
|
|
Debugger and setting a local GDB server in your development system through QEMU.
|
|
|
|
You will need an ELF binary image for debugging purposes. The build system
|
|
generates the image in the output directory. By default, the kernel binary name
|
|
is :file:`zephyr.elf`. The name can be changed using a Kconfig option.
|
|
|
|
We will use the standard 1234 TCP port to open a :abbr:`GDB (GNU Debugger)`
|
|
server instance. This port number can be changed for a port that best suits the
|
|
development environment.
|
|
|
|
You can run Qemu to listen for a "gdb connection" before it starts executing any
|
|
code to debug it.
|
|
|
|
.. code-block:: bash
|
|
|
|
qemu -s -S <image>
|
|
|
|
will setup Qemu to listen on port 1234 and wait for a GDB connection to it.
|
|
|
|
The options used above have the following meaning:
|
|
|
|
* ``-S`` Do not start CPU at startup; rather, you must type 'c' in the
|
|
monitor.
|
|
* ``-s`` Shorthand for :literal:`-gdb tcp::1234`: open a GDB server on
|
|
TCP port 1234.
|
|
|
|
To debug with QEMU and to start a GDB server and wait for a remote connect, run
|
|
the following inside an application:
|
|
|
|
.. code-block:: bash
|
|
|
|
make BOARD=qemu_x86 debugserver
|
|
|
|
The build system will start a QEMU instance with the CPU halted at startup
|
|
and with a GDB server instance listening at the TCP port 1234.
|
|
|
|
Using a local GDB configuration :file:`.gdbinit` can help initialize your GDB
|
|
instance on every run.
|
|
In this example, the initialization file points to the GDB server instance.
|
|
It configures a connection to a remote target at the local host on the TCP
|
|
port 1234. The initialization sets the kernel's root directory as a
|
|
reference.
|
|
|
|
The :file:`.gdbinit` file contains the following lines:
|
|
|
|
.. code-block:: bash
|
|
|
|
target remote localhost:1234
|
|
dir ZEPHYR_BASE
|
|
|
|
.. note::
|
|
|
|
Substitute ZEPHYR_BASE for the current kernel's root directory.
|
|
|
|
Execute the application to debug from the same directory that you chose for
|
|
the :file:`gdbinit` file. The command can include the ``--tui`` option
|
|
to enable the use of a terminal user interface. The following commands
|
|
connects to the GDB server using :file:`gdb`. The command loads the symbol
|
|
table from the elf binary file. In this example, the elf binary file name
|
|
corresponds to :file:`zephyr.elf` file:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ gdb --tui zephyr.elf
|
|
|
|
.. note::
|
|
|
|
The GDB version on the development system might not support the --tui
|
|
option.
|
|
|
|
If you are not using a .gdbinit file, issue the following command inside GDB to
|
|
connect to the remove GDB server on port 1234:
|
|
|
|
.. code-block:: bash
|
|
|
|
(gdb) target remote localhost:1234
|
|
|
|
Finally, The command below connects to the GDB server using the Data
|
|
Displayer Debugger (:file:`ddd`). The command loads the symbol table from the
|
|
elf binary file, in this instance, the :file:`zephyr.elf` file.
|
|
|
|
The :abbr:`DDD (Data Displayer Debugger)` may not be installed in your
|
|
development system by default. Follow your system instructions to install
|
|
it.
|
|
|
|
.. code-block:: bash
|
|
|
|
ddd --gdb --debugger "gdb zephyr.elf"
|
|
|
|
|
|
Both commands execute the :abbr:`gdb (GNU Debugger)`. The command name might
|
|
change depending on the toolchain you are using and your cross-development
|
|
tools.
|