Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: Add out of tree RIOT app documentation #19324

Merged
merged 1 commit into from
Feb 27, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions doc/doxygen/src/creating-an-application.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,114 @@ target used.

**Testrunner:** when using the `make generate-test`, you can also automatically
add a testrunner Python script. Just answer 'y' when prompted.

# Creating an out of tree application structure

Applications written for RIOT do not have to reside in the RIOT tree. Out of
tree applications, modules and boards are supported.

For a full application with custom board and modules, the following directory
tree can be used:

```
├── apps
│   └── my_app
│   └── Makefile
├── boards
│   └── my_board
├── modules
│   └── my_module
│   ├── include
│   │   └── my_module.h
│   ├── Makefile
│   ├── Makefile.include
│   └── my_module.c
└── RIOT
```

In this example tree, the `apps` directory contains a collection of applications
for the project. The modules directory could contain extra modules for the
applications.

The make file inside the application needs at least the following as bare minimum:

```
APPLICATION = my_app
PROJECT_BASE ?= $(CURDIR)/../..
RIOTBASE ?= $(PROJECT_BASE)/RIOT

# Optionally, provide paths to where external boards and/or modules
# reside, so that they can be included in the app
EXTERNAL_MODULE_DIRS += $(PROJECT_BASE)/modules
EXTERNAL_BOARD_DIRS += $(PROJECT_BASE)/boards

include $(RIOTBASE)/Makefile.include
```

The `RIOTBASE` variable tells the build system where to find the RIOT source
tree and to need to point to the RIOT source tree used for the application for
the application to work.

The RIOT directory contains the sources of RIOT here. This can be either a
direct checkout of the sources or a git submodule, whichever has your
preference.

If your project has separate modules or separate boards, these can be contained
inside a modules os boards directory. The RIOT build system has both
`EXTERNAL_MODULE_DIRS` and `EXTERNAL_BOARD_DIRS` variables to specify
directories that contain extra modules and extra boards.

## External Boards

External boards can be ported in an identical way as porting a regular board to
RIOT, see @ref porting-boards.

One approach can be to copy over an existing board and modify it to suit the
needs. Boards in the RIOT tree can be included and used as dependency in the
custom boards. In case you connect additional hardware to an upstream board
(such as e.g. an Arduino shield) or you require a different hardware
configuration (e.g. configuring some of the pins configured as ADC as
additional PWM outputs instead) a copy of the upstream board that is then
customized to the application needs is the best course of action.

## External Modules

Similar to the external boards, external modules can be written in a similar way
as regular in-tree modules.

One modification is the include directory inside the module directory. For this
include directory to be added to the include path during compilation, the
following snippet is required in the modules `Makefile.include`:

```
USEMODULE_INCLUDES_my_module := $(LAST_MAKEFILEDIR)/include
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_my_module)
```

Note that the make variable (here `USEMODULE_INCLUDES_my_module`) must be unique
for every module to make this work. Including the module name here is usually
sufficient.

## Extra Makefile Scaffolding

A bit of extra, but optional, Makefile scaffolding can help to keep the project
easy to maintain. An extra `Makefile.include` in the root directory of the
project that sets the necessary variables can help to deduplicate settings.
This includes the `RIOTBASE` variable and the include to the RIOT
`Makefile.include`:

```
EXTERNAL_MODULE_DIRS += $(PROJECT_BASE)/modules
EXTERNAL_BOARD_DIRS += $(PROJECT_BASE)/boards
RIOTBASE ?= $(PROJECT_BASE)/RIOT
include $(RIOTBASE)/Makefile.include
```
Applications then just have to set the `PROJECT_BASE` variable and include this
maribu marked this conversation as resolved.
Show resolved Hide resolved
makefile and don't have to each add the external board and module directories.

The application makefile would then look like this:
```
APPLICATION = my_app
PROJECT_BASE ?= $(CURDIR)/../..
include $(PROJECT_BASE)/Makefile.include
```