doc/guides: fix headings and improve code blocks, other small things
@ -132,7 +132,7 @@ ifneq (,$(filter native native32 native64,$(BOARD)))
|
||||
endif
|
||||
```
|
||||
|
||||
# Helper Tools
|
||||
## Helper Tools
|
||||
|
||||
To help you start writing an application within RIOT, the build system provides
|
||||
the `generate-example` and `generate-test` make targets. These targets are wrappers
|
||||
@ -143,8 +143,6 @@ on the module implementation.
|
||||
For applications, the `Makefile` is generated with the dependencies (modules,
|
||||
packages, required features) included.
|
||||
|
||||
## Usage
|
||||
|
||||
To generate an example application, e.g in the `examples` directory, from the
|
||||
RIOT base directory, run:
|
||||
```sh
|
||||
@ -181,7 +179,7 @@ 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
|
||||
## 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.
|
||||
@ -237,7 +235,7 @@ 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
|
||||
|
||||
External boards can be ported in an identical way as porting a regular board to
|
||||
RIOT, see [Porting Boards](/advanced_tutorials/porting_boards/).
|
||||
@ -250,7 +248,7 @@ 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
|
||||
### External Modules
|
||||
|
||||
Similar to the external boards, external modules can be written in a similar way
|
||||
as regular in-tree modules.
|
||||
@ -268,7 +266,7 @@ 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
|
||||
### 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
|
||||
|
||||
@ -170,7 +170,7 @@ See `sys/ztimer/Makefile` for an example in code.
|
||||
`SUBMODULES` can also be true-pseudomodules, or become one by conditionally excluding
|
||||
the source files by adding them to `SUBMODULES_NO_SRC`.
|
||||
|
||||
# Helper Tools
|
||||
## Helper Tools
|
||||
|
||||
To help you start writing a module, the RIOT build system provides the
|
||||
`generate-module` make target. It is a wrapper around the
|
||||
@ -180,8 +180,6 @@ copyright headers, doxygen groups, etc, so you can concentrate on the module
|
||||
implementation.
|
||||
The module source files are created in the `sys` directory.
|
||||
|
||||
## Usage
|
||||
|
||||
From the RIOT base directory, run:
|
||||
```sh
|
||||
make generate-module
|
||||
|
||||
@ -11,7 +11,7 @@ peripherals itself are in RIOT not considered to be device drivers, but
|
||||
peripheral or low-level drivers. Typical devices are network devices like
|
||||
radios, Ethernet adapters, sensors, and actuators.
|
||||
|
||||
# General Design Objectives
|
||||
## General Design Objectives
|
||||
|
||||
Device drivers should be as easy to use as possible. This implies an
|
||||
'initialize->ready' paradigm, meaning, that device drivers should be ready to use
|
||||
@ -53,9 +53,9 @@ Sixth, device drivers SHOULD be implemented independent of any CPU/board code.
|
||||
To achieve this, the driver implementations should strictly be based on
|
||||
platform independent interfaces as the peripheral drivers, xtimer, etc.
|
||||
|
||||
# General
|
||||
## General
|
||||
|
||||
## Documentation
|
||||
### Documentation
|
||||
|
||||
Document what your driver does! Most devices come with a very large number of
|
||||
features, while the corresponding device driver only supports a subset of them.
|
||||
@ -63,7 +63,7 @@ This should be clearly stated in the device driver's documentation so that
|
||||
anyone wanting to use the driver can find out the supported features without
|
||||
having to scan through the code.
|
||||
|
||||
## Device Descriptor and Parameter Configuration
|
||||
### Device Descriptor and Parameter Configuration
|
||||
|
||||
Each device MUST supply a data structure, holding the devices state and
|
||||
configuration, using the naming scheme of `DEVNAME_t` (e.g. `dht_t`, or
|
||||
@ -108,7 +108,7 @@ configuration data that is only used once can be read directly from ROM, while
|
||||
often used fields (e.g. used peripherals) are stored directly in the device
|
||||
descriptor and one saves hereby one de-referencing step when accessing them.
|
||||
|
||||
## Default Device Configuration
|
||||
### Default Device Configuration
|
||||
|
||||
Each device driver in RIOT MUST supply a default configuration file, named
|
||||
`DEVNAME_params.h`. This file should be located in the `RIOT/drivers/...`. The
|
||||
@ -201,7 +201,7 @@ Third, we can define more than a single device in the board configuration
|
||||
And finally, we can simply override the `tmpabc_params.h` file as described
|
||||
above.
|
||||
|
||||
## Compile-time Configuration Documentation
|
||||
### Compile-time Configuration Documentation
|
||||
|
||||
The macros that configure the driver during compilation is added to the listing
|
||||
for [Compile time configurations](https://doc.riot-os.org/group__config.html). Refer to the following example
|
||||
@ -230,7 +230,7 @@ to [sensors group](https://doc.riot-os.org/group__config__drivers__sensors.htmls
|
||||
Sub-groups defined for different types of drivers can be found in
|
||||
[drivers/doc.txt](https://github.com/RIOT-OS/RIOT/blob/master/drivers/doc.txt)
|
||||
|
||||
## Initialization
|
||||
### Initialization
|
||||
|
||||
In general, the initialization functions should do the following:
|
||||
|
||||
@ -250,7 +250,7 @@ For more detailed information on how the signature of the init functions should
|
||||
look like, please refer below to the specific requirements for network devices
|
||||
and sensors.
|
||||
|
||||
## Return Values
|
||||
### Return Values
|
||||
|
||||
As stated above, we check communication of a device during initialization and
|
||||
handle error return values from the lower layers, where they exist. To prevent
|
||||
@ -299,7 +299,7 @@ negative return value indicates an error without exceptions. E.g. like this:
|
||||
int foo_humidity(const foo_t *dev);
|
||||
```
|
||||
|
||||
### Documenting Return Values
|
||||
#### Documenting Return Values
|
||||
|
||||
With the exception of functions returning `void`, all return values have to be
|
||||
documented. Use the `return` Doxygen command to describe what is returned. In
|
||||
@ -309,7 +309,7 @@ argument (no spaces in the value allowed!), and a description (spaces allowed
|
||||
here) as second. It is safe to use both `return` and `retval` commands, or just
|
||||
one of them - whatever makes most sense for a given function.
|
||||
|
||||
## General Device Driver Checklist
|
||||
### General Device Driver Checklist
|
||||
|
||||
- *MUST*: the supported feature set and any custom behavior is clearly
|
||||
documented
|
||||
@ -322,9 +322,9 @@ one of them - whatever makes most sense for a given function.
|
||||
- *MUST*: use `const devab_t *dev` when the device descriptor can be access
|
||||
read-only
|
||||
|
||||
## Build System Integration
|
||||
### Build System Integration
|
||||
|
||||
### Internal Include Files
|
||||
#### Internal Include Files
|
||||
|
||||
If the driver contains internal include files, a `Makefile.include` must be
|
||||
added in the driver implementation directory, with the following content
|
||||
@ -335,7 +335,7 @@ USEMODULE_INCLUDES_<driver name> := $(LAST_MAKEFILEDIR)/include
|
||||
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_<driver name>)
|
||||
```
|
||||
|
||||
### External Dependencies
|
||||
#### External Dependencies
|
||||
|
||||
If the driver has other module or CPU features dependencies (like `xtimer` or
|
||||
`periph_i2c`), they must be added in the `$(RIOTBASE)/drivers/Makefile.dep`
|
||||
@ -351,7 +351,7 @@ endif
|
||||
|
||||
**Warning:** Please be careful with alphabetical order when modifying this file.
|
||||
|
||||
## Helper Tools
|
||||
### Helper Tools
|
||||
|
||||
To help you start writing a device driver, the RIOT build system provides the
|
||||
`generate-driver` make target. It is a wrapper around the
|
||||
@ -360,8 +360,6 @@ when starting to implement a driver: all minimum files are generated with
|
||||
copyright headers, doxygen groups, etc, so you can concentrate on the driver
|
||||
implementation.
|
||||
|
||||
**Usage:**
|
||||
|
||||
From the RIOT base directory, run:
|
||||
```
|
||||
make generate-driver
|
||||
@ -379,9 +377,9 @@ Then answer a few questions about the driver:
|
||||
Other global information (author name, email, organization) should be retrieved
|
||||
automatically from your git configuration.
|
||||
|
||||
# Sensors
|
||||
## Sensors
|
||||
|
||||
## SAUL
|
||||
### SAUL
|
||||
|
||||
All sensor drivers SHOULD implement the SAUL interface. It is however
|
||||
recommended, that the drivers are written in a way, that the drivers do not
|
||||
@ -410,7 +408,7 @@ int saul_read(saul_t *dev, phydat_t *data)
|
||||
This ensures the versatility of the device driver, having in mind that one might
|
||||
want to use the driver without SAUL or maybe in a context without RIOT.
|
||||
|
||||
## Initialization
|
||||
### Initialization
|
||||
|
||||
Sensor device drivers are expected to implement a single initialization
|
||||
function, `DEVNAME_init`, taking the device descriptor and the device's
|
||||
@ -422,15 +420,15 @@ int tmpabc_init(tmpabc_t *dev, const tmpabc_params_t *params);
|
||||
|
||||
After this function is called, the device MUST be running and usable.
|
||||
|
||||
## Value Handling
|
||||
### Value Handling
|
||||
|
||||
### Value Semantics
|
||||
#### Value Semantics
|
||||
|
||||
All sensors in RIOT MUST return their reading results as real physical values.
|
||||
When working with sensor data, these are the values of interest, and the
|
||||
overhead of the conversion is normally neglectable.
|
||||
|
||||
### Typing
|
||||
#### Typing
|
||||
|
||||
All values SHOULD be returned using integer types, with `int16_t` being the
|
||||
preferred type where applicable.
|
||||
@ -441,7 +439,7 @@ directly while using their fraction. The recommended way to solve this is by
|
||||
scaling the result value using decimal fixed point arithmetic, in other words,
|
||||
just return centi-degree instead of degree (e.g. 2372c°C instead of 23.72°C).
|
||||
|
||||
## Additional Sensor Driver Checklist
|
||||
### Additional Sensor Driver Checklist
|
||||
|
||||
- *MUST*: mandatory device parameters are configurable through this file, e.g.
|
||||
sampling rate, resolution, sensitivity
|
||||
@ -459,9 +457,9 @@ just return centi-degree instead of degree (e.g. 2372c°C instead of 23.72°C).
|
||||
- *SHOULD*: the driver exports functions for putting it to sleep and waking up
|
||||
the device
|
||||
|
||||
# Network Devices
|
||||
## Network Devices
|
||||
|
||||
## Initialization
|
||||
### Initialization
|
||||
|
||||
The initialization process MUST be split into 2 steps: first, initialize the
|
||||
device descriptor and if applicable the used peripherals, and secondly do the
|
||||
@ -478,7 +476,7 @@ void netabc_setup(netabc_t *dev, const netabc_params_t *params);
|
||||
int netabs_init(netabc_t *dev);
|
||||
```
|
||||
|
||||
## netdev
|
||||
### netdev
|
||||
|
||||
Device driver for network device SHOULD implement the `netdev` interface. It is
|
||||
up to the implementer, if the device driver also offers a device specific
|
||||
@ -486,7 +484,7 @@ interface which is then mapped to the `netdev` interface, or if the device
|
||||
driver can be purely interfaced using `netdev`. While the second option is
|
||||
recommended for efficiency reasons, this is not mandatory.
|
||||
|
||||
## Additional Network Device Driver Checklist
|
||||
### Additional Network Device Driver Checklist
|
||||
|
||||
- *MUST*: a setup function in the style of
|
||||
`int devab_setup(devab_t *dev, const devab_params_t *params);` exists
|
||||
@ -494,7 +492,7 @@ recommended for efficiency reasons, this is not mandatory.
|
||||
exists
|
||||
- *SHOULD*: the driver implements 'netdev' [if applicable]
|
||||
|
||||
# TODO
|
||||
## TODO
|
||||
|
||||
Add some information about how to handle multiple threads, when to use mutexes,
|
||||
and how to deal with interrupts? And especially patterns for being nice from
|
||||
|
||||
@ -19,10 +19,10 @@ We assume here that your `CPU` and `CPU_MODEL` is already supported
|
||||
in `RIOT` so no peripheral or cpu implementation is needed.
|
||||
:::
|
||||
|
||||
# Porting Flowchart
|
||||
## Porting Flowchart
|
||||

|
||||
|
||||
# General Structure
|
||||
## General Structure
|
||||
|
||||
Like [applications](/advanced_tutorials/creating_applications/) or
|
||||
[modules](/advanced_tutorials/creating_modules),
|
||||
@ -47,7 +47,7 @@ board-foo
|
||||
└── Makefile.include
|
||||
```
|
||||
|
||||
## Source Files
|
||||
### Source Files
|
||||
|
||||
Header files in `board-foo/include` define physical mappings or
|
||||
configurations. e.g:
|
||||
@ -86,9 +86,9 @@ void board_init(void)
|
||||
}
|
||||
```
|
||||
|
||||
## Makefiles
|
||||
### Makefiles
|
||||
|
||||
### Makefile
|
||||
#### Makefile
|
||||
|
||||
A board's Makefile just needs to include `Makefile.base` in the RIOT
|
||||
repository and define the `MODULE` as `board` (see
|
||||
@ -100,7 +100,7 @@ MODULE = board
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
```
|
||||
|
||||
### Makefile.dep
|
||||
#### Makefile.dep
|
||||
|
||||
Dependencies on other `MODULES` or `FEATURES` can be defined here. This might
|
||||
specify `MODULES` or dependencies that need to be pulled under specific
|
||||
@ -118,7 +118,7 @@ the dependency block for your board *before* its dependencies pull in their own
|
||||
dependencies.
|
||||
:::
|
||||
|
||||
#### Default Configurations
|
||||
##### Default Configurations
|
||||
There are two pseudomodules that are used to indicate that certain drivers of devices
|
||||
present in the platform should be enabled. Each board (or CPU) has knowledge as
|
||||
to which drivers should be enabled in each case.
|
||||
@ -142,7 +142,7 @@ ifneq (,$(filter saul_default,$(USEMODULE)))
|
||||
endif
|
||||
```
|
||||
|
||||
### Makefile.features
|
||||
#### Makefile.features
|
||||
|
||||
This file defines all the features provided by the BOARD. These features
|
||||
might also need to be supported by the `CPU`. Here, define the `CPU` and
|
||||
@ -161,7 +161,7 @@ FEATURES_PROVIDED += periph_spi
|
||||
FEATURES_PROVIDED += periph_uart
|
||||
```
|
||||
|
||||
### Makefile.include
|
||||
#### Makefile.include
|
||||
|
||||
This file contains BSP or toolchain configurations for the `BOARD`. It
|
||||
should at least define the configuration needed for flashing (i.e. specify a
|
||||
@ -191,7 +191,7 @@ PORT_DARWIN ?= $(firstword $(sort $(wildcard /dev/tty.usbserial*)))
|
||||
PROGRAMMER ?= openocd
|
||||
```
|
||||
|
||||
## Timer Configurations
|
||||
### Timer Configurations
|
||||
|
||||
When using the high level timer `ztimer` there is an overhead in calling the
|
||||
[ztimer_sleep](https://doc.riot-os.org/group__sys__ztimer.html#gade98636e198f2d571c8acd861d29d360)
|
||||
@ -235,7 +235,7 @@ Alternatively, the pseudomodule [ztimer_auto_adjust](https://doc.riot-os.org/gro
|
||||
can be used in an application to enable automatic timer offset compensation at board startup.
|
||||
This however incurs overhead both in the text segment and at bootup time.
|
||||
|
||||
## doc.md
|
||||
### doc.md
|
||||
|
||||
Although not explicitly needed, if upstreamed and as a general good
|
||||
practice, this file holds all `BOARD` documentation. This can include
|
||||
@ -251,15 +251,15 @@ any browser.
|
||||
@brief Support for the foo board
|
||||
@author FooName BarName <foo.bar@baz.com>
|
||||
|
||||
### User Interface
|
||||
#### User Interface
|
||||
|
||||
...
|
||||
|
||||
### Using UART
|
||||
#### Using UART
|
||||
|
||||
...
|
||||
|
||||
### Flashing the device
|
||||
#### Flashing the device
|
||||
|
||||
...
|
||||
```
|
||||
@ -277,7 +277,7 @@ the latest version with
|
||||
pip install --upgrade riotgen
|
||||
```
|
||||
|
||||
# Helper Tools
|
||||
## Helper Tools
|
||||
|
||||
To help you start porting a board, the RIOT build system provides the
|
||||
`generate-board` make target. It is a wrapper around the
|
||||
@ -286,8 +286,6 @@ when starting to port a board: all required files are generated with
|
||||
copyright headers, doxygen groups, etc, so you can concentrate on the port.
|
||||
The board source files are created in the `boards/<board name>` directory.
|
||||
|
||||
## Usage
|
||||
|
||||
From the RIOT base directory, run:
|
||||
|
||||
```bash
|
||||
@ -306,7 +304,7 @@ Then answer a few questions about the driver:
|
||||
Other global information (author name, email, organization) should be retrieved
|
||||
automatically from your git configuration.
|
||||
|
||||
# Using Common Code
|
||||
## Using Common Code
|
||||
|
||||
To avoid code duplication, common code across boards has been grouped in
|
||||
`boards/common`. e.g. `BOARD`s based on the same cpu (`boards/common/nrf52`) or
|
||||
@ -338,7 +336,7 @@ static const timer_conf_t timer_config[] = {
|
||||
/** @} */
|
||||
```
|
||||
|
||||
# Boards Outside of RIOTBASE
|
||||
## Boards Outside of RIOTBASE
|
||||
|
||||
All `BOARD`s in RIOT reside in `RIOTBOARD` (`RIOTBOARD` being a make variable
|
||||
set to `$(RIOTBOARD)/boards`).
|
||||
@ -402,7 +400,7 @@ DIRS += $(RIOTBOARD)/foo-parent
|
||||
An example can be found in
|
||||
[`tests/build_system/external_board_native`](https://github.com/RIOT-OS/RIOT/tree/master/tests/build_system/external_board_native).
|
||||
|
||||
# Board Names and Aliases
|
||||
## Board Names and Aliases
|
||||
|
||||
New boards should be named according to
|
||||
[RDM0003](https://github.com/RIOT-OS/RIOT/blob/master/doc/memos/rdm0003.md).
|
||||
@ -418,7 +416,7 @@ resolves to either [`native32`](https://doc.riot-os.org/group__boards__native32.
|
||||
or [`native64`](https://doc.riot-os.org/group__boards__native64.html)
|
||||
depending on the host architecture.
|
||||
|
||||
# Tools
|
||||
## Tools
|
||||
|
||||
Some scripts and tools available to ease `BOARD` porting and testing:
|
||||
|
||||
@ -430,7 +428,7 @@ Some scripts and tools available to ease `BOARD` porting and testing:
|
||||
- Run `dist/tools/compile_and_test_for_board/compile_and_test_for_board.py . <board> --with-test-only`
|
||||
to run all automated tests on the new board.
|
||||
|
||||
# Further Reference
|
||||
## Further Reference
|
||||
|
||||
- [In her blog](https://blog.martine-lenders.eu/riot-board-en.html), Martine Lenders documented her approach of
|
||||
porting the [Adafruit Feather nRF52840 Express](https://doc.riot-os.org/group__boards__adafruit-feather-nrf52840-express.html)
|
||||
|
||||
@ -3,7 +3,7 @@ title: Flashing via RIOT's Build System
|
||||
description: Guide on how to flash boards using RIOT's build system
|
||||
---
|
||||
|
||||
# General Approach
|
||||
## General Approach
|
||||
|
||||
In general, flashing a board from RIOT is as straight forward as typing in a
|
||||
shell (with the application directory as current working directory):
|
||||
@ -22,7 +22,7 @@ make BOARD=<BOARD-TO-FLASH> PROGRAMMER=stm32flash flash
|
||||
|
||||
To flash without rebuilding use `flash-only` as target instead of `flash`.
|
||||
|
||||
# Supported Tools
|
||||
## Supported Tools
|
||||
|
||||
RIOT supports plenty of flashing tools, that are below grouped into general
|
||||
flashing tools that support multiple MCU families, and specialized tools that
|
||||
@ -36,7 +36,7 @@ the board due to a missing board feature, bootloader, or similar.
|
||||
To ease use the programmers are given by the value to pass via
|
||||
`PROGRAMMER=<value>`, rather than the official spelling of the programmer.
|
||||
|
||||
## Compatibility Matrix of Generic Tools
|
||||
### Compatibility Matrix of Generic Tools
|
||||
|
||||
<!-- Note: Add flashers that theoretically support multiple platforms here,
|
||||
even if RIOT does only have integration for one platform. The missing
|
||||
@ -71,73 +71,73 @@ Remarks:
|
||||
|
||||
1. Requires a patched version of the programmer tool
|
||||
|
||||
## Specialized Flashing Tools Per Platform
|
||||
### Specialized Flashing Tools Per Platform
|
||||
|
||||
The following list only contains single-platform flashing tools. Tools that
|
||||
support multiple platforms are given in section above.
|
||||
|
||||
### AVR
|
||||
#### AVR
|
||||
|
||||
- `avrdude`
|
||||
|
||||
### CC13xx / CC26xx
|
||||
#### CC13xx / CC26xx
|
||||
|
||||
- `uniflash`
|
||||
|
||||
### CC2538
|
||||
#### CC2538
|
||||
|
||||
- `cc2538-bsl`
|
||||
|
||||
### ESP8266 / ESP32 (Xtensa) / ESP32 (RISC-V)
|
||||
#### ESP8266 / ESP32 (Xtensa) / ESP32 (RISC-V)
|
||||
|
||||
- `esptool`
|
||||
|
||||
### LPC23xx
|
||||
#### LPC23xx
|
||||
|
||||
- `lpc2k_pgm`
|
||||
|
||||
### MSP430
|
||||
#### MSP430
|
||||
|
||||
- `mspdebug`
|
||||
- `goodfet`
|
||||
|
||||
### nRF52
|
||||
#### nRF52
|
||||
|
||||
- `adafruit-nrfutil`, `uf2conv` (requires Adafruit bootloader),
|
||||
see [Adafruit nRF52 Bootloader Common](https://doc.riot-os.org/group__boards__common__adafruit-nrf52-bootloader.html)
|
||||
- `nrfutil` (required nRF bootloader)
|
||||
- `nrfjprog` (requires a separate J-Link debugger)
|
||||
|
||||
### RP2040 / RP2350
|
||||
#### RP2040 / RP2350
|
||||
|
||||
- `picotool`
|
||||
|
||||
### SAM
|
||||
#### SAM
|
||||
|
||||
- `bossa`
|
||||
- `edbg`
|
||||
|
||||
### STM32
|
||||
#### STM32
|
||||
|
||||
- `stm32flash`
|
||||
- `stm32loader`
|
||||
- `cpy2remed` (requires integrated ST-Link programmer, e.g. Nucleo boards)
|
||||
- `robotis-loader` (requires robotis bootloader, only one board supported)
|
||||
|
||||
# Programmer Configuration
|
||||
## Programmer Configuration
|
||||
|
||||
This section will list additional configuration options to control the behavior
|
||||
of a programming tool, such as selecting the hardware adapter used for
|
||||
programming.
|
||||
|
||||
## OpenOCD Configuration
|
||||
### OpenOCD Configuration
|
||||
|
||||
### OPENOCD_DEBUG_ADAPTER
|
||||
#### OPENOCD_DEBUG_ADAPTER
|
||||
|
||||
`OPENOCD_DEBUG_ADAPTER` can be set via command line or as environment variable
|
||||
to use non-default flashing hardware.
|
||||
|
||||
### OPENOCD_RESET_USE_CONNECT_ASSERT_SRST
|
||||
#### OPENOCD_RESET_USE_CONNECT_ASSERT_SRST
|
||||
|
||||
`OPENOCD_RESET_USE_CONNECT_ASSERT_SRST` can be set via command line or as
|
||||
environment variable to `0` to disable resetting the board via the `SRST` line.
|
||||
@ -147,19 +147,19 @@ not be possible to attach the debugger while the MCU is in deep sleeping mode.
|
||||
If this is set to `0` by the user, the user may need a carefully timed reset
|
||||
button press to be able to flash the board.
|
||||
|
||||
### OPENOCD_PRE_FLASH_CMDS
|
||||
#### OPENOCD_PRE_FLASH_CMDS
|
||||
|
||||
`OPENOCD_PRE_FLASH_CMDS` can be set as environment variable to pass additional
|
||||
commands to OpenOCD prior to flashing, e.g. to disable flash write protection.
|
||||
|
||||
### OPENOCD_PRE_VERIFY_CMDS
|
||||
#### OPENOCD_PRE_VERIFY_CMDS
|
||||
|
||||
`OPENOCD_PRE_VERIFY_CMDS` can be set as environment variable to pass additional
|
||||
flags to OpenOCD prior to verifying the flashed firmware. E.g. this is used
|
||||
in the `pba-d-01-kw2x` to disable the watchdog to prevent it from disrupting
|
||||
the verification process.
|
||||
|
||||
### OPENOCD_PRE_FLASH_CHECK_SCRIPT
|
||||
#### OPENOCD_PRE_FLASH_CHECK_SCRIPT
|
||||
|
||||
`OPENOCD_PRE_FLASH_CHECK_SCRIPT` can be set via command line or as
|
||||
environment variable to execute a script before OpenOCD starts flashing. It is
|
||||
@ -169,12 +169,12 @@ magic value in the flash configuration field protection bits.
|
||||
The script is expected to exit with code `0` if flashing should resume, or with
|
||||
exit code `1` if flashing should be aborted.
|
||||
|
||||
### OPENOCD_CONFIG
|
||||
#### OPENOCD_CONFIG
|
||||
|
||||
`OPENOCD_DEBUG_ADAPTER` can be set via command line or as environment variable
|
||||
to use non-default OpenOCD configuration file.
|
||||
|
||||
### OPENOCD_TRANSPORT
|
||||
#### OPENOCD_TRANSPORT
|
||||
|
||||
`OPENOCD_TRANSPORT` can be set via command line or as environment variable to
|
||||
select a non-default transport protocol. E.g. to use JTAG rather than SWD for a
|
||||
@ -189,7 +189,7 @@ JTAG. Also JTAG requires more signal lines to be connected compared to SWD and
|
||||
some internal programmers only have the SWD signal lines connected, so that
|
||||
JTAG will not be possible.
|
||||
|
||||
## stm32flash Configuration
|
||||
### stm32flash Configuration
|
||||
|
||||
It is possible to automatically boot the STM32 board into the in-ROM bootloader
|
||||
that `stm32flash` communicates with for flashing by connecting the RST pin to
|
||||
@ -209,7 +209,7 @@ now, `STM32FLASH_RESET_INVERT` is by default `1`. This may change if it
|
||||
becomes evident that non-inverted TTL adapters are in fact more common than
|
||||
inverted adapters.
|
||||
|
||||
## MSPDEBUG Configuration
|
||||
### MSPDEBUG Configuration
|
||||
|
||||
All options can be passed as environment variables or as make arguments.
|
||||
All options except for `DEBUGSERVER_PORT` apply to both debugging and flashing
|
||||
@ -233,7 +233,7 @@ options is typically not needed.
|
||||
`DEBUGSERVER_PORT` is used to specify the TCP port to listen for GDB to
|
||||
connect to. It defaults to 2000.
|
||||
|
||||
## Handling Multiple Boards with UDEV-Rules
|
||||
### Handling Multiple Boards with UDEV-Rules
|
||||
|
||||
When developing and working with multiple boards the default `PORT`
|
||||
configuration for a particular board might not apply anymore, so `PORT` will need
|
||||
@ -247,7 +247,7 @@ boards serial port (`riot/tty-<board-name>`) and the actual serial port
|
||||
`dev` information (`DEBUG_ADAPTER_ID`, `PORT`, etc.) to always flash and open a
|
||||
terminal on the correct port.
|
||||
|
||||
### Procedure
|
||||
#### Procedure
|
||||
|
||||
- use `udevadm info /dev/ttyACM0` to query the udev database for information on
|
||||
device on port `/dev/ttyACM0`.
|
||||
@ -300,7 +300,7 @@ endif
|
||||
```
|
||||
:::
|
||||
|
||||
## Handling Multiple Versions of the same BOARD
|
||||
### Handling Multiple Versions of the same BOARD
|
||||
|
||||
The above procedure works fine when handling different boards, but not
|
||||
multiple times the same board, e.g: multiple `samr21-xpro`.
|
||||
@ -347,7 +347,7 @@ BOARD=samr21-xpro BOARD_NUM=n make flash term
|
||||
In the end, this would be the same as using the serial, but a simple number might
|
||||
be easier to handle.
|
||||
|
||||
## Notes
|
||||
### Notes
|
||||
Udev only parses SUBSYSTEM and one parent. For others, we will rely on ENV
|
||||
variables defined by 60-serial.rules
|
||||
|
||||
@ -356,13 +356,13 @@ So the current filename should be higher than 60-serial.rules
|
||||
If for some reason re-writing the serial is needed there is a windows tool:
|
||||
https://remoteqth.com/wiki/index.php?page=How+to+set+usb+device+SerialNumber
|
||||
|
||||
## Documentation
|
||||
### Documentation
|
||||
* The whole documentation
|
||||
http://reactivated.net/writing_udev_rules.html#udevinfo
|
||||
* Udev manpage
|
||||
http://manpages.ubuntu.com/manpages/eoan/en/man7/udev.7.html
|
||||
|
||||
# Handling Multiple Boards without UDEV-Rules
|
||||
## Handling Multiple Boards without UDEV-Rules
|
||||
|
||||
This is a simpler approach than the above mentioned issue. The solution here only
|
||||
uses a Makefile for selecting the debugger and serial port. No
|
||||
@ -430,7 +430,7 @@ most recently added interface (out of those matching the filtering by vendor,
|
||||
model, etc.). The `--format path` argument will result in only the device path
|
||||
being printed for convenient use in scripts.
|
||||
|
||||
# Handling Multiple Boards: Simplest Approach
|
||||
## Handling Multiple Boards: Simplest Approach
|
||||
|
||||
Passing `MOST_RECENT_PORT=1` as environment variable or as parameter to
|
||||
make will result in the most recently connected board being preferred over the
|
||||
@ -446,7 +446,7 @@ allows to always reliably identify them correctly (e.g. the firmware on the
|
||||
ATmega16U2 used as USB to UART converter on Arduino Mega2560 will provide
|
||||
identification data unique to that board).
|
||||
|
||||
## Adding Board Filters
|
||||
### Adding Board Filters
|
||||
|
||||
After connecting as many variants of the board you target (and maybe some others
|
||||
to test that the filter actually filters out non-matching boards). Then first
|
||||
@ -481,7 +481,7 @@ TTY_BOARD_FILTER := --vendor 'Arduino' --model-db 'Mega 2560|Mega ADK'
|
||||
Note that also matching the `R3` in `Mega 2560 R3` would prevent matching older
|
||||
or newer revisions than R3, so we don't add that to the regex.
|
||||
|
||||
## Advances Board Filters
|
||||
### Advances Board Filters
|
||||
|
||||
In most cases, just adding a simple `TTY_BOARD_FILTER` is sufficient. If we
|
||||
however have wildly different flavors of the same board (e.g. genuine Arduino
|
||||
|
||||
@ -12,9 +12,9 @@ compile-time. This means having a standard way of:
|
||||
- Check valid configuration considering inter-dependencies
|
||||
- Applying the selected configuration
|
||||
|
||||
# Overview
|
||||
## Overview
|
||||
|
||||
## Exposure
|
||||
### Exposure
|
||||
Modules in RIOT expose their configurable parameters via
|
||||
Kconfig files (for more information on Kconfig syntax check
|
||||
[the specification](https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html)).
|
||||
@ -25,21 +25,21 @@ Kconfig files are structured through the file system mirroring the current
|
||||
module distribution. In time, all modules will have Kconfig files to make
|
||||
themselves configurable through this system.
|
||||
|
||||
## Assignment
|
||||
### Assignment
|
||||
The user can assign values to the exposed parameters, either by manually writing
|
||||
'.config' files or using an interface such as Menuconfig. Parameters with no
|
||||
assigned values will take the default ones. For a detailed distinction between
|
||||
Kconfig and '.config' files see [Appendix B](#appendix-b-difference-between-kconfig-and-config-files).
|
||||
|
||||
## Verification and Application
|
||||
### Verification and Application
|
||||
Using '.config' and Kconfig files the build system takes care of doing the
|
||||
necessary checks on the values according to the parameter definition. After
|
||||
that, the `autoconf.h` header file is generated, it contains all the
|
||||
configurations in the form of (`CONFIG_` prefixed) macros.
|
||||
|
||||
# User Guide to Configure with Kconfig
|
||||
## User Guide to Configure with Kconfig
|
||||
|
||||
## Configure using menuconfig
|
||||
### Configure using menuconfig
|
||||
In order to use the graphical interface menuconfig to configure the
|
||||
application, run `make menuconfig` in the application's folder. All available
|
||||
configurations (based on the used modules) for the particular platform will be
|
||||
@ -57,7 +57,7 @@ application's folder as `user.config`, using the 'Save' option in menuconfig.
|
||||
This way it will be persistent after cleaning the application directory
|
||||
(`make clean`).
|
||||
|
||||
## Configure using '.config' Files
|
||||
### Configure using '.config' Files
|
||||
The second way to configure the application is by directly writing '.config'
|
||||
files. Two files will be sources of configuration during the generation of the
|
||||
final header file: `app.config` and `user.config`, which should be placed
|
||||
@ -83,13 +83,13 @@ In this case, there is no need for using menuconfig. It's enough just to call
|
||||
applied. Note that if any dependency issue occurs, warnings will be generated
|
||||
(e.g. not enabling the configuration of a module via Kconfig).
|
||||
|
||||
## Application Configuration with Kconfig
|
||||
### Application Configuration with Kconfig
|
||||
To expose application-specific configuration options a `Kconfig` file can
|
||||
be placed in the application's folder. For an example of this you can check
|
||||
the [tests/build_system/kconfig](https://github.com/RIOT-OS/RIOT/tree/master/tests/build_system/kconfig)
|
||||
application.
|
||||
|
||||
## Configuration via Environment Variables
|
||||
### Configuration via Environment Variables
|
||||
For easy debugging of configurations or testing new modules by compiling them
|
||||
into existing applications, one can also use environment variables prefixed by
|
||||
`RIOT_CONFIG_`. To achieve the same configuration exemplified in
|
||||
@ -106,46 +106,46 @@ All the checks that apply for `.config` files also are done with this approach.
|
||||
Mind that this is only meant to be used during development. In production,
|
||||
please set the configuration via `.config` files.
|
||||
|
||||
## A Note on the Usage of CFLAGS
|
||||
### A Note on the Usage of CFLAGS
|
||||
When a certain module is being configured via Kconfig, the configuration macro
|
||||
will no longer be overridable by means of CFLAGS (e.g. set on the
|
||||
compilation command or on a Makefile). Consider this if you are getting a
|
||||
'redefined warning'.
|
||||
|
||||
---
|
||||
# Integration into the Build System
|
||||
## Integration into the Build System
|
||||
|
||||
The integration of Kconfig into the build system is mainly done in
|
||||
`makefiles/kconfig.mk`.
|
||||
|
||||
## Steps during the Build Process
|
||||
### Steps during the Build Process
|
||||
|
||||

|
||||
|
||||
### 0. Module Dependency Resolution
|
||||
#### 0. Module Dependency Resolution
|
||||
The resolution of module dependencies is performed by the build
|
||||
system where all the used modules and packages end up listed in the `USEMODULE`
|
||||
or `USEPKG` make variables.
|
||||
|
||||
|
||||
#### Input
|
||||
##### Input
|
||||
- Makefiles.
|
||||
|
||||
#### Output
|
||||
##### Output
|
||||
- `USEMODULE` and `USEPKG` variables.
|
||||
|
||||
### 1. Module Listing
|
||||
#### 1. Module Listing
|
||||
The list of modules needed for the particular build is dumped into the
|
||||
`$ (GENERATED_DIR)/Kconfig.dep` file, where each module is translated into a
|
||||
Kconfig symbol as documented in [Appendix A](#appendix-a-check-if-a-module-or-package-is-used).
|
||||
|
||||
#### Input
|
||||
##### Input
|
||||
- `USEMODULE` and `USEPKG` variables
|
||||
|
||||
#### Output
|
||||
##### Output
|
||||
- `$ (GENERATED_DIR)/Kconfig.dep` file
|
||||
|
||||
### 2. Merging all Configuration Sources
|
||||
#### 2. Merging all Configuration Sources
|
||||
In this step configuration values are taken from multiple sources and merged
|
||||
into a single `out.config` configuration file. This file is temporary and is
|
||||
removed on cleanup. If the user needs to save a particular configuration
|
||||
@ -166,15 +166,15 @@ information of all the used Kconfig files in Makefile format. This file is
|
||||
included by the build system and allows to re-trigger the generation of
|
||||
`out.conf` whenever a Kconfig file is modified.
|
||||
|
||||
#### Input
|
||||
##### Input
|
||||
- Optional:
|
||||
- `$ (APPDIR)/app.config`: Application specific default configurations.
|
||||
- `$ (APPDIR)/user.config`: Configurations saved by user.
|
||||
|
||||
#### Output
|
||||
##### Output
|
||||
- `$ (GENERATED_DIR)/out.config` file.
|
||||
|
||||
### 3. Menuconfig Execution (optional)
|
||||
#### 3. Menuconfig Execution (optional)
|
||||
Menuconfig is a graphical interface for software configuration. It is, for example, used for
|
||||
the configuration of the Linux kernel. This section explains the process
|
||||
that occurs when RIOT is being configured using the menuconfig interface.
|
||||
@ -200,18 +200,18 @@ choose to save a backup configuration file for later at a different location
|
||||
If any changes occur to `out.config`, the
|
||||
[generation of autoconf.h](#4-generation-of-the-autoconfh-header) is executed automatically.
|
||||
|
||||
#### Input
|
||||
##### Input
|
||||
- `/Kconfig` file.
|
||||
- Optional:
|
||||
- `$ (APPDIR)/app.config`
|
||||
- `$ (APPDIR)/user.config`
|
||||
- `$ (GENERATED_DIR)/out.config`
|
||||
|
||||
#### Output
|
||||
##### Output
|
||||
- Updated `$ (GENERATED_DIR)/out.config` file.
|
||||
- `$ (GENERATED_DIR)/out.config.old` backup file.
|
||||
|
||||
### 4. Generation of the autoconf.h Header
|
||||
#### 4. Generation of the autoconf.h Header
|
||||
With the addition of Kconfig, a dependency has been added to the build
|
||||
process: the `$ (GENERATED_DIR)/autoconf.h` header file. This header file is
|
||||
the main output from the Kconfig configuration system. It holds all the macros
|
||||
@ -222,17 +222,17 @@ In order to generate the `autoconf.h` file, the `genconfig` script is used.
|
||||
Inputs for this script are the main `Kconfig` file and `out.config`
|
||||
configuration file, which holds the selected values for the exposed parameters.
|
||||
|
||||
#### Input:
|
||||
##### Input:
|
||||
- `$ (GENERATED_DIR)/out.config` file.
|
||||
- Main `Kconfig` file exposing configuration of modules.
|
||||
|
||||
#### Output:
|
||||
##### Output:
|
||||
- `$ (GENERATED_DIR)/autoconf.h` configuration header file.
|
||||
- Optional:
|
||||
- `$ (GENERATED_DIR)/deps/*/*.h` header files that allow incremental builds
|
||||
|
||||
|
||||
### Summary of Files
|
||||
#### Summary of Files
|
||||
These files are defined in `kconfig.mk`.
|
||||
|
||||
| File | Description |
|
||||
@ -245,7 +245,7 @@ These files are defined in `kconfig.mk`.
|
||||
| `out.config.d` | Dependency file of `out.config` containing the list of Kconfig files used to generate it. |
|
||||
| `autoconf.h` | Header file containing the macros that applied the selected configuration. |
|
||||
|
||||
## Kconfig Symbols in Makefiles
|
||||
### Kconfig Symbols in Makefiles
|
||||
As `.config` files have Makefile syntax, they can be included when building,
|
||||
which allows to access the applied configuration from the build system.
|
||||
|
||||
@ -266,9 +266,9 @@ application's Makefile. The symbols will not be defined until after including
|
||||
`Makefile.include`.
|
||||
|
||||
---
|
||||
# Transition Phase
|
||||
## Transition Phase
|
||||
|
||||
## Making Configuration via Kconfig optional
|
||||
### Making Configuration via Kconfig optional
|
||||
During transition to the usage of Kconfig as the main configuration tool for
|
||||
RIOT, the default behavior will be the traditional one: expose configuration
|
||||
options in header files and use CFLAGS as inputs. To allow optional
|
||||
@ -282,11 +282,11 @@ check if a module is being used).
|
||||
|
||||
The module configuration must be enabled via make dependency modelling.
|
||||
|
||||
## Modelling CPUs and Boards
|
||||
### Modelling CPUs and Boards
|
||||
CPUs and boards are being modelled in Kconfig. The following part is a guide on how to
|
||||
organize and name the symbols.
|
||||
|
||||
### CPUs
|
||||
#### CPUs
|
||||
The proposed hierarchy for the classification of CPUs is as follows:
|
||||
|
||||
```
|
||||
@ -347,7 +347,7 @@ multiple files, it is responsibility of file containing the most specific
|
||||
symbols to `source` the less specific. Keep in mind that only the file located
|
||||
in `/cpu/<CPU>/Kconfig` will be included by the root `/Kconfig` file.
|
||||
|
||||
#### Example
|
||||
##### Example
|
||||
|
||||
```
|
||||
# This is the most specific symbol (selected by the board)
|
||||
@ -376,7 +376,7 @@ config CPU_FAM
|
||||
|
||||
```
|
||||
|
||||
### Boards
|
||||
#### Boards
|
||||
Boards must be modelled as hidden boolean symbols with the prefix `BOARD_` which
|
||||
default to `y` and are placed in `/boards/<BOARD>/Kconfig`. This file will be
|
||||
`source`d from the main `/Kconfig` file. The board symbol must select the
|
||||
@ -394,7 +394,7 @@ folder (e.g. `/boards/common/arduino-atmega`) a symbol should be declared to
|
||||
model this in Kconfig. Symbols for common boards must have the `BOARD_COMMON_`
|
||||
prefix, and must select the common provided features.
|
||||
|
||||
#### Example
|
||||
##### Example
|
||||
The samr21-xpro has a `samr21g18a` CPU and provides multiple features. Its
|
||||
symbol is modelled as following:
|
||||
|
||||
@ -410,7 +410,7 @@ config BOARD_SAMR21_XPRO
|
||||
select CPU_MODEL_SAMR21G18A
|
||||
```
|
||||
|
||||
### Default Configurations
|
||||
#### Default Configurations
|
||||
|
||||
Boards, common board directories, CPUs and common CPU directories may need to
|
||||
override default configuration values. Visible configuration symbols are
|
||||
@ -436,7 +436,7 @@ include $(RIOTCPU)/cortexm_common/Makefile.features
|
||||
KCONFIG_CPU_CONFIG += $(RIOTCPU)/stm32/stm32.config
|
||||
```
|
||||
|
||||
## Summary of Reserved Kconfig Prefixes
|
||||
### Summary of Reserved Kconfig Prefixes
|
||||
The following symbol prefixes have been assigned particular semantics and are
|
||||
reserved for the cases described below:
|
||||
|
||||
@ -454,9 +454,9 @@ reserved for the cases described below:
|
||||
| `USEPKG_` | Models an [external package](https://doc.riot-os.org/group__pkg.html). Generated from `USEPKG` variable |
|
||||
|
||||
---
|
||||
# Appendices
|
||||
## Appendices
|
||||
|
||||
## Appendix A: Check if a Module or Package is used
|
||||
### Appendix A: Check if a Module or Package is used
|
||||
In order to show only the relevant configuration parameters to the user with
|
||||
respect to a given application and board selection, Kconfig needs knowledge
|
||||
about all modules and packages to be used for a compilation. The dependency
|
||||
@ -486,7 +486,7 @@ endmenu # Configure Sock Utilities
|
||||
```
|
||||
|
||||
|
||||
## Appendix B: Difference between 'Kconfig' and '.config' Files
|
||||
### Appendix B: Difference between 'Kconfig' and '.config' Files
|
||||
Kconfig files describe a configuration database, which is a collection of
|
||||
configuration options organized in a tree structure. Configuration options may
|
||||
have dependencies (among other attributes), which are used to determine their
|
||||
@ -497,7 +497,7 @@ Kconfig files are written in
|
||||
defined in the Linux kernel. Configuration options have attributes such as
|
||||
types, prompts and default values.
|
||||
|
||||
#### Kconfig File
|
||||
##### Kconfig File
|
||||
|
||||
```
|
||||
menu "Buffer Sizes"
|
||||
@ -513,7 +513,7 @@ On the other hand configuration files contain assignment of values to
|
||||
configuration options and use Makefile syntax. They can also be used to save a
|
||||
set of configuration values as backup.
|
||||
|
||||
#### '.config' File
|
||||
##### '.config' File
|
||||
|
||||
```makefile
|
||||
# enable Kconfig configuration for gcoap
|
||||
@ -525,7 +525,7 @@ CONFIG_GCOAP_PDU_BUF_SIZE=12345
|
||||
In other words: Kconfig files describe configuration options and '.config' files
|
||||
assign their values.
|
||||
|
||||
## Appendix C: Pitfall when using Different Configuration Interfaces
|
||||
### Appendix C: Pitfall when using Different Configuration Interfaces
|
||||
In the current configuration flow the user can choose to configure RIOT using
|
||||
the menuconfig graphical interface or writing '.config' files by hand.
|
||||
|
||||
@ -545,7 +545,7 @@ change `out.config` directly (a backup file `out.config.old` will be kept).
|
||||
configuration sources would re-trigger the merging process and overwrite
|
||||
`out.config`.**
|
||||
|
||||
## Appendix D: A few Key Aspects while Exposing a Macro to Kconfig
|
||||
### Appendix D: A few Key Aspects while Exposing a Macro to Kconfig
|
||||
A macro that holds a 0 or 1 is modelled in Kconfig as a `bool` symbol. References to this macro
|
||||
can then make use of IS_ACTIVE macro from kernel_defines.h with C conditionals
|
||||
for conditional compilation.
|
||||
@ -562,7 +562,7 @@ in such a way that a new macro is introduced to hold the restricted figures
|
||||
while operators are added to arrive at the desired value. The process is
|
||||
documented in this [pull request.](https://github.com/RIOT-OS/RIOT/pull/14086)
|
||||
|
||||
# Useful references
|
||||
## Useful References
|
||||
- [Kconfig language specification](https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html)
|
||||
- [Kconfig macro language specification](https://www.kernel.org/doc/html/latest/kbuild/kconfig-macro-language.html)
|
||||
- [Kconfig - Tips and Best Practices](https://docs.zephyrproject.org/latest/guides/kconfig/tips.html)
|
||||
|
||||
@ -52,10 +52,11 @@ we create a new file called `main.c` and add the following code:
|
||||
* of the program. A return value of 0 indicates that the program has finished
|
||||
* successfully.
|
||||
*/
|
||||
int main(void) {
|
||||
puts("Hello World!");
|
||||
int main(void)
|
||||
{
|
||||
puts("Hello World!");
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -29,6 +29,30 @@ To do this we adapt the `BOARD` variable in our `Makefile` to the board we are u
|
||||
BOARD ?= arduino-feather-nrf52840-sense
|
||||
```
|
||||
|
||||
```makefile title="Makefile" {5}
|
||||
# name of your application
|
||||
APPLICATION = gpio_example
|
||||
|
||||
# Change this to your board if you want to build for a different board
|
||||
BOARD ?= arduino-feather-nrf52840-sense
|
||||
|
||||
# This has to be the absolute path to the RIOT base directory:
|
||||
# If you are following the tutorial, your RIOT base directory will
|
||||
# most likely be something like RIOTBASE ?= $(CURDIR)/RIOT
|
||||
# instead of this
|
||||
RIOTBASE ?= $(CURDIR)/../../..
|
||||
|
||||
# Comment this out to disable code in RIOT that does safety checking
|
||||
# which is not needed in a production environment but helps in the
|
||||
# development process:
|
||||
DEVELHELP ?= 1
|
||||
|
||||
# Change this to 0 show compiler invocation lines by default:
|
||||
QUIET ?= 1
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
```
|
||||
|
||||
:::tip
|
||||
If you ever want to just quickly test something
|
||||
on a board without having to change the `Makefile`,
|
||||
@ -37,8 +61,6 @@ you can also set the `BOARD` variable in the terminal before running `make`.
|
||||
BOARD=arduino-feather-nrf52840-sense make all
|
||||
```
|
||||
|
||||

|
||||
|
||||
First we want to make sure that we can build the code for the board.
|
||||
To do this we can simply run `make all` in the terminal,
|
||||
this will build the code for the board and check if everything is set up correctly.
|
||||
@ -107,7 +129,37 @@ USEMODULE += ztimer
|
||||
USEMODULE += ztimer_msec
|
||||
```
|
||||
|
||||

|
||||
```makefile title="Makefile" {18-24}
|
||||
# name of your application
|
||||
APPLICATION = gpio_example
|
||||
|
||||
# Change this to your board if you want to build for a different board
|
||||
BOARD ?= arduino-feather-nrf52840-sense
|
||||
|
||||
# This has to be the absolute path to the RIOT base directory:
|
||||
# If you are following the tutorial, your RIOT base directory will
|
||||
# most likely be something like RIOTBASE ?= $(CURDIR)/RIOT
|
||||
# instead of this
|
||||
RIOTBASE ?= $(CURDIR)/../../..
|
||||
|
||||
# Comment this out to disable code in RIOT that does safety checking
|
||||
# which is not needed in a production environment but helps in the
|
||||
# development process:
|
||||
DEVELHELP ?= 1
|
||||
|
||||
# Add the gpio module to the build
|
||||
USEMODULE += periph_gpio
|
||||
USEMODULE += periph_gpio_irq
|
||||
|
||||
# Enable the milliseconds timer.
|
||||
USEMODULE += ztimer
|
||||
USEMODULE += ztimer_msec
|
||||
|
||||
# Change this to 0 show compiler invocation lines by default:
|
||||
QUIET ?= 1
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
```
|
||||
|
||||
This allows us to both control the GPIO pins and timers.
|
||||
|
||||
@ -118,7 +170,7 @@ In this case, we also need the `ztimer_msec` module to use the millisecond timer
|
||||
|
||||
Now we need to actually define the pin that we want to control in our code.
|
||||
To do this include the following lines **before** the `main` function.
|
||||
{/*<!--skip ci-->*/}
|
||||
|
||||
```c
|
||||
#include "board.h"
|
||||
#include "periph/gpio.h"
|
||||
@ -134,16 +186,17 @@ and afterwards we turn the LED off by clearing the pin.
|
||||
|
||||
{/*<!--skip ci-->*/}
|
||||
```c
|
||||
int main(void) {
|
||||
/* Initialize the LED0 pin */
|
||||
gpio_init(led0, led0_mode);
|
||||
/* Turn off the LED0 pin */
|
||||
gpio_clear(led0);
|
||||
int main(void)
|
||||
{
|
||||
/* Initialize the LED0 pin */
|
||||
gpio_init(led0, led0_mode);
|
||||
/* Turn off the LED0 pin */
|
||||
gpio_clear(led0);
|
||||
|
||||
/* Loop forever */
|
||||
while (1) {
|
||||
/* Loop forever */
|
||||
while (1) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@ -151,15 +204,41 @@ Turning the LED off when the board starts is quite boring,
|
||||
so let's make it blink by adding a delay and toggling the LED.
|
||||
|
||||
```c
|
||||
/* Loop forever */
|
||||
while (1) {
|
||||
/* Toggle the LED0 pin every 500 milliseconds */
|
||||
gpio_toggle(led0);
|
||||
ztimer_sleep(ZTIMER_MSEC, 500);
|
||||
}
|
||||
/* Loop forever */
|
||||
while (1) {
|
||||
/* Toggle the LED0 pin every 500 milliseconds */
|
||||
gpio_toggle(led0);
|
||||
ztimer_sleep(ZTIMER_MSEC, 500);
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
The full code should now look like this:
|
||||
|
||||
{/*<!--skip ci-->*/}
|
||||
```c title="main.c" {16-21}
|
||||
#include "board.h"
|
||||
#include "periph/gpio.h"
|
||||
#include "ztimer.h"
|
||||
|
||||
/* Define the LED0 pin and mode */
|
||||
gpio_t led0 = GPIO_PIN(1, 9);
|
||||
gpio_mode_t led0_mode = GPIO_OUT;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Initialize the LED0 pin */
|
||||
gpio_init(led0, led0_mode);
|
||||
/* Turn off the LED0 pin */
|
||||
gpio_clear(led0);
|
||||
|
||||
/* Loop forever */
|
||||
while (1) {
|
||||
/* Toggle the LED0 pin every 500 milliseconds */
|
||||
gpio_toggle(led0);
|
||||
ztimer_sleep(ZTIMER_MSEC, 500);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If we now `make flash` and then `make term` we should see the LED blinking.
|
||||
|
||||
@ -183,22 +262,32 @@ that will be called when the button is pressed.
|
||||
|
||||
```c title="Define the button callback function"
|
||||
/* This callback function will be called when the button state changes */
|
||||
void button_callback(void *arg) {
|
||||
/* the argument is not used */
|
||||
(void)arg;
|
||||
void button_callback(void *arg)
|
||||
{
|
||||
/* the argument is not used */
|
||||
(void)arg;
|
||||
|
||||
/* Toggle the LED1 pin based on the button state */
|
||||
if (gpio_read(button)) {
|
||||
gpio_clear(led1);
|
||||
} else {
|
||||
gpio_set(led1);
|
||||
}
|
||||
/* Toggle the LED1 pin based on the button state */
|
||||
if (gpio_read(button)) {
|
||||
gpio_clear(led1);
|
||||
}
|
||||
else {
|
||||
gpio_set(led1);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now we need to define the button and led1 pin and mode and initialize it.
|
||||
|
||||
```c {1-6, 27-33}
|
||||
```c title="main.c" {9-14, 38-44}
|
||||
#include "board.h"
|
||||
#include "periph/gpio.h"
|
||||
#include "ztimer.h"
|
||||
|
||||
/* Define the LED0 pin and mode */
|
||||
gpio_t led0 = GPIO_PIN(1, 9);
|
||||
gpio_mode_t led0_mode = GPIO_OUT;
|
||||
|
||||
/* Define the LED1 pin and mode */
|
||||
gpio_t led1 = GPIO_PIN(1, 10);
|
||||
gpio_mode_t led1_mode = GPIO_OUT;
|
||||
@ -207,46 +296,47 @@ gpio_mode_t led1_mode = GPIO_OUT;
|
||||
gpio_t button = GPIO_PIN(1, 2);
|
||||
|
||||
/* This callback function will be called when the button state changes */
|
||||
void button_callback(void *arg) {
|
||||
/* the argument is not used */
|
||||
(void)arg;
|
||||
void button_callback(void *arg)
|
||||
{
|
||||
/* the argument is not used */
|
||||
(void)arg;
|
||||
|
||||
/* Toggle the LED1 pin based on the button state */
|
||||
if (gpio_read(button)) {
|
||||
gpio_clear(led1);
|
||||
} else {
|
||||
gpio_set(led1);
|
||||
}
|
||||
/* Toggle the LED1 pin based on the button state */
|
||||
if (gpio_read(button)) {
|
||||
gpio_clear(led1);
|
||||
}
|
||||
else {
|
||||
gpio_set(led1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
/* Initialize the LED0 pin */
|
||||
gpio_init(led0, led0_mode);
|
||||
/* Turn off the LED0 pin */
|
||||
gpio_clear(led0);
|
||||
int main(void)
|
||||
{
|
||||
/* Initialize the LED0 pin */
|
||||
gpio_init(led0, led0_mode);
|
||||
/* Turn off the LED0 pin */
|
||||
gpio_clear(led0);
|
||||
|
||||
/* Initialize the LED1 pin */
|
||||
gpio_init(led1, led1_mode);
|
||||
/* Turn off the LED1 pin */
|
||||
gpio_clear(led1);
|
||||
/* Initialize the LED1 pin */
|
||||
gpio_init(led1, led1_mode);
|
||||
/* Turn off the LED1 pin */
|
||||
gpio_clear(led1);
|
||||
|
||||
/* Initialize the button pin */
|
||||
gpio_init_int(button, GPIO_IN_PU, GPIO_BOTH, button_callback, NULL);
|
||||
/* Initialize the button pin */
|
||||
gpio_init_int(button, GPIO_IN_PU, GPIO_BOTH, button_callback, NULL);
|
||||
|
||||
/* Loop forever */
|
||||
while (1) {
|
||||
/* Toggle the LED0 pin every 500 milliseconds */
|
||||
gpio_toggle(led0);
|
||||
ztimer_sleep(ZTIMER_MSEC, 500);
|
||||
}
|
||||
/* Loop forever */
|
||||
while (1) {
|
||||
/* Toggle the LED0 pin every 500 milliseconds */
|
||||
gpio_toggle(led0);
|
||||
ztimer_sleep(ZTIMER_MSEC, 500);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This code will initialize the button pin and call the `button_callback`
|
||||
function whenever the button is pressed.
|
||||
|
||||

|
||||
|
||||
If we now `make flash` and then `make term` we should see the LED turn on
|
||||
when the button is pressed.
|
||||
|
||||
@ -278,18 +368,19 @@ Using this define, we can simplify our code to the following:
|
||||
|
||||
{/*<!--skip ci-->*/}
|
||||
```c title="Using the LED0_TOGGLE define"
|
||||
int main(void) {
|
||||
/* Initialize the LED0 pin */
|
||||
gpio_init(led0, led0_mode);
|
||||
/* Turn off the LED0 pin */
|
||||
gpio_clear(led0);
|
||||
int main(void)
|
||||
{
|
||||
/* Initialize the LED0 pin */
|
||||
gpio_init(led0, led0_mode);
|
||||
/* Turn off the LED0 pin */
|
||||
gpio_clear(led0);
|
||||
|
||||
/* Loop forever */
|
||||
while (1) {
|
||||
/* Toggle the LED0 pin every 500 milliseconds */
|
||||
LED0_TOGGLE;
|
||||
ztimer_sleep(ZTIMER_MSEC, 500);
|
||||
}
|
||||
/* Loop forever */
|
||||
while (1) {
|
||||
/* Toggle the LED0 pin every 500 milliseconds */
|
||||
LED0_TOGGLE;
|
||||
ztimer_sleep(ZTIMER_MSEC, 500);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 32 KiB |
@ -22,9 +22,45 @@ add the following line to the `Makefile`:
|
||||
```makefile
|
||||
USEMODULE += saul
|
||||
USEMODULE += saul_default
|
||||
|
||||
USEMODULE += ztimer
|
||||
USEMODULE += ztimer_msec
|
||||
```
|
||||
|
||||

|
||||
```makefile title="Makefile" {21-27}
|
||||
# name of your application
|
||||
APPLICATION = saul_example
|
||||
|
||||
# Change this to your board if you want to build for a different board
|
||||
BOARD ?= arduino-feather-nrf52840-sense
|
||||
|
||||
# This has to be the absolute path to the RIOT base directory:
|
||||
# If you are following the tutorial, your RIOT base directory will
|
||||
# most likely be something like RIOTBASE ?= $(CURDIR)/RIOT
|
||||
# instead of this
|
||||
RIOTBASE ?= $(CURDIR)/../../..
|
||||
|
||||
# Comment this out to disable code in RIOT that does safety checking
|
||||
# which is not needed in a production environment but helps in the
|
||||
# development process:
|
||||
DEVELHELP ?= 1
|
||||
|
||||
# This board requires a start sleep to actually catch the printed output
|
||||
USEMODULE += shell
|
||||
|
||||
# Add the SAUL module to the application
|
||||
USEMODULE += saul
|
||||
USEMODULE += saul_default
|
||||
|
||||
# Enable the milliseconds timer.
|
||||
USEMODULE += ztimer
|
||||
USEMODULE += ztimer_msec
|
||||
|
||||
# Change this to 0 show compiler invocation lines by default:
|
||||
QUIET ?= 1
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
```
|
||||
|
||||
## Including the Headers
|
||||
|
||||
@ -40,13 +76,27 @@ Add the following lines to the top of the file:
|
||||
```
|
||||
|
||||
We need:
|
||||
|
||||
- `stdio.h` for the `printf` function,
|
||||
- `board.h` for the board specific configuration,
|
||||
- `ztimer.h` for the ztimer module so we can sleep for a while,
|
||||
- and `saul_reg.h` for the SAUL registry and related functions.
|
||||
|
||||
The code should now look like this:
|
||||
|
||||

|
||||
<!--skip ci-->
|
||||
```c title="main.c"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "saul_reg.h"
|
||||
#include "ztimer.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Registering a Sensor
|
||||
|
||||
@ -57,8 +107,8 @@ In this example we will register a temperature sensor, as such we need to simply
|
||||
search for `SAUL_SENSE_TEMP` devices.
|
||||
|
||||
```c
|
||||
/* Define our temperature sensor */
|
||||
saul_reg_t *temperature_sensor = saul_reg_find_type(SAUL_SENSE_TEMP);
|
||||
/* Define our temperature sensor */
|
||||
saul_reg_t *temperature_sensor = saul_reg_find_type(SAUL_SENSE_TEMP);
|
||||
```
|
||||
|
||||
This doesn't actually guarantee that the sensor is available, which is why we also need to
|
||||
@ -66,20 +116,53 @@ check if the sensor truly exists. To do this we create a simple if statement tha
|
||||
whether the result of the function was `NULL` or not.
|
||||
|
||||
```c
|
||||
/* Exit if we can't find a temperature sensor */
|
||||
if (!temperature_sensor) {
|
||||
puts("No temperature sensor found");
|
||||
return 1;
|
||||
} else {
|
||||
/*
|
||||
* Otherwise print the name of the temperature sensor
|
||||
* and continue the program
|
||||
*/
|
||||
printf("Temperature sensor found: %s\n", temperature_sensor->name);
|
||||
}
|
||||
/* Exit if we can't find a temperature sensor */
|
||||
if (!temperature_sensor) {
|
||||
puts("No temperature sensor found");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Otherwise print the name of the temperature sensor
|
||||
* and continue the program
|
||||
*/
|
||||
printf("Temperature sensor found: %s\n", temperature_sensor->name);
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
The code should now look like this:
|
||||
|
||||
<!--skip ci-->
|
||||
```c title="main.c" {9-27}
|
||||
#include <stdio.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "saul_reg.h"
|
||||
#include "ztimer.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* We sleep for 5 seconds to allow the system to initialize */
|
||||
ztimer_sleep(ZTIMER_MSEC, 5000);
|
||||
puts("Welcome to SAUL magic!");
|
||||
|
||||
/* Define our temperature sensor */
|
||||
saul_reg_t *temperature_sensor = saul_reg_find_type(SAUL_SENSE_TEMP);
|
||||
|
||||
/* Exit if we can't find a temperature sensor */
|
||||
if (!temperature_sensor) {
|
||||
puts("No temperature sensor found");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Otherwise print the name of the temperature sensor
|
||||
* and continue the program
|
||||
*/
|
||||
printf("Temperature sensor found: %s\n", temperature_sensor->name);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Congratulations, by this point your program should be able to find
|
||||
a temperature sensor on your board.
|
||||
@ -91,17 +174,17 @@ to read the sensor we simply call the `saul_reg_read` function
|
||||
which then stores the result in a `phydat_t` struct we provide.
|
||||
|
||||
```c
|
||||
/* We start an infinite loop to continuously read the temperature */
|
||||
while (1) {
|
||||
/* Define a variable to store the temperature */
|
||||
phydat_t temperature;
|
||||
/* We start an infinite loop to continuously read the temperature */
|
||||
while (1) {
|
||||
/* Define a variable to store the temperature */
|
||||
phydat_t temperature;
|
||||
|
||||
/*
|
||||
* Read the temperature sensor
|
||||
* and store the result in the temperature variable
|
||||
* saul_reg_read returns the dimension of the data read (1 in this case)
|
||||
*/
|
||||
int dimension = saul_reg_read(temperature_sensor, &temperature);
|
||||
/*
|
||||
* Read the temperature sensor
|
||||
* and store the result in the temperature variable
|
||||
* saul_reg_read returns the dimension of the data read (1 in this case)
|
||||
*/
|
||||
int dimension = saul_reg_read(temperature_sensor, &temperature);
|
||||
```
|
||||
|
||||
Once again, since C doesn't have exceptions,
|
||||
@ -109,11 +192,11 @@ we need to check if the sensor was read correctly.
|
||||
In this case we simply need to check if the dimension is greater than 0.
|
||||
|
||||
```c
|
||||
/* If the read was successful (1+ Dimensions), print the temperature */
|
||||
if (dimension <= 0) {
|
||||
puts("Error reading temperature sensor");
|
||||
return 1;
|
||||
}
|
||||
/* If the read was successful (1+ Dimensions), print the temperature */
|
||||
if (dimension <= 0) {
|
||||
puts("Error reading temperature sensor");
|
||||
return 1;
|
||||
}
|
||||
```
|
||||
|
||||
Now all that is left is to print the temperature to the console and go to sleep.
|
||||
@ -122,14 +205,70 @@ RIOT provides a simple function to solve this problem,
|
||||
`phydat_dump` which prints the data in a `phydat_t` struct to the console.
|
||||
|
||||
```c
|
||||
/* Dump the temperature to the console */
|
||||
phydat_dump(&temperature, dimension);
|
||||
/* Dump the temperature to the console */
|
||||
phydat_dump(&temperature, dimension);
|
||||
|
||||
/* Sleep for 1 seconds */
|
||||
ztimer_sleep(ZTIMER_MSEC, 1000);
|
||||
/* Sleep for 1 seconds */
|
||||
ztimer_sleep(ZTIMER_MSEC, 1000);
|
||||
```
|
||||
|
||||

|
||||
The final code should now look like this:
|
||||
|
||||
```c title="main.c" {29-52}
|
||||
#include <stdio.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "saul_reg.h"
|
||||
#include "ztimer.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* We sleep for 5 seconds to allow the system to initialize */
|
||||
ztimer_sleep(ZTIMER_MSEC, 5000);
|
||||
puts("Welcome to SAUL magic!");
|
||||
|
||||
/* Define our temperature sensor */
|
||||
saul_reg_t *temperature_sensor = saul_reg_find_type(SAUL_SENSE_TEMP);
|
||||
|
||||
/* Exit if we can't find a temperature sensor */
|
||||
if (!temperature_sensor) {
|
||||
puts("No temperature sensor found");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Otherwise print the name of the temperature sensor
|
||||
* and continue the program
|
||||
*/
|
||||
printf("Temperature sensor found: %s\n", temperature_sensor->name);
|
||||
}
|
||||
|
||||
/* We start an infinite loop to continuously read the temperature */
|
||||
while (1) {
|
||||
/* Define a variable to store the temperature */
|
||||
phydat_t temperature;
|
||||
|
||||
/*
|
||||
* Read the temperature sensor
|
||||
* and store the result in the temperature variable
|
||||
* saul_reg_read returns the dimension of the data read (1 in this case)
|
||||
*/
|
||||
int dimension = saul_reg_read(temperature_sensor, &temperature);
|
||||
|
||||
/* If the read was successful (1+ Dimensions), print the temperature */
|
||||
if (dimension <= 0) {
|
||||
puts("Error reading temperature sensor");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Dump the temperature to the console */
|
||||
phydat_dump(&temperature, dimension);
|
||||
|
||||
/* Sleep for 1 seconds */
|
||||
ztimer_sleep(ZTIMER_MSEC, 1000);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Building and Running the Program
|
||||
|
||||
|
||||
@ -35,15 +35,16 @@ Go into your `main.c` file and include the following code:
|
||||
```
|
||||
|
||||
```c title="The main function"
|
||||
int main(void) {
|
||||
/* Buffer to store command line input */
|
||||
char buffer[SHELL_DEFAULT_BUFSIZE];
|
||||
int main(void)
|
||||
{
|
||||
/* Buffer to store command line input */
|
||||
char buffer[SHELL_DEFAULT_BUFSIZE];
|
||||
|
||||
/* Start the shell */
|
||||
shell_run(NULL, buffer, SHELL_DEFAULT_BUFSIZE);
|
||||
/* Start the shell */
|
||||
shell_run(NULL, buffer, SHELL_DEFAULT_BUFSIZE);
|
||||
|
||||
/* Return 0 to indicate that the program has finished successfully */
|
||||
return 0;
|
||||
/* Return 0 to indicate that the program has finished successfully */
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
@ -83,17 +84,18 @@ Go into your `main.c` file and include the following code:
|
||||
|
||||
```c title="The function that implements the echo command"
|
||||
/* Our command we want to register to the shell */
|
||||
int echo_command(int argc, char **argv) {
|
||||
/* We take the arguments passed to the command */
|
||||
for (int i = 1; i < argc; i++) {
|
||||
/* We print each argument followed by a space */
|
||||
printf("%s ", argv[i]);
|
||||
}
|
||||
/* Finally, we print a newline character to end the line */
|
||||
printf("\n");
|
||||
int echo_command(int argc, char **argv)
|
||||
{
|
||||
/* We take the arguments passed to the command */
|
||||
for (int i = 1; i < argc; i++) {
|
||||
/* We print each argument followed by a space */
|
||||
printf("%s ", argv[i]);
|
||||
}
|
||||
/* Finally, we print a newline character to end the line */
|
||||
printf("\n");
|
||||
|
||||
/* Return 0 to indicate success */
|
||||
return 0;
|
||||
/* Return 0 to indicate success */
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
@ -107,7 +109,6 @@ Go back to your `main.c` file and include the following code _outside_ of the `m
|
||||
```c title="Register the command with the shell"
|
||||
/* This little macro registers the command so we can use it in the shell */
|
||||
SHELL_COMMAND(echo, "Echo a message", echo_command);
|
||||
|
||||
```
|
||||
|
||||
This macro takes three arguments: the name of the command,
|
||||
|
||||
@ -19,20 +19,19 @@ Let's create a simple thread that prints a message to the console.
|
||||
Go into your `main.c` file and add the following code:
|
||||
|
||||
```c
|
||||
void *my_first_thread(void *arg) {
|
||||
/* The argument we receive will not be used */
|
||||
(void)arg;
|
||||
void *my_first_thread(void *arg)
|
||||
{
|
||||
/* The argument we receive will not be used */
|
||||
(void)arg;
|
||||
|
||||
/* We print a simple message from the thread */
|
||||
puts("Hello, from the thread!");
|
||||
/* We print a simple message from the thread */
|
||||
puts("Hello, from the thread!");
|
||||
|
||||
/* We return NULL to indicate that the thread has finished */
|
||||
return NULL;
|
||||
/* We return NULL to indicate that the thread has finished */
|
||||
return NULL;
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
This function takes a single argument,
|
||||
a pointer to any data, and prints "Hello, from the thread!" to the console.
|
||||
Now all that is left is to start the thread.
|
||||
@ -56,26 +55,25 @@ The stack size can vary depending on the complexity of your thread.
|
||||
For example, depending of the amount of local variables you use,
|
||||
the stack size might need to be larger.
|
||||
|
||||
Lets define the stack as a global variable:
|
||||
Let's define the stack as a global variable:
|
||||
|
||||
```c
|
||||
char my_thread_stack[THREAD_STACKSIZE_MAIN];
|
||||
```
|
||||
|
||||

|
||||
|
||||
Lastly, we need to actually start the thread.
|
||||
Go into your `main` function and include the following code:
|
||||
|
||||
```c
|
||||
int main(void) {
|
||||
/* Create a thread with the stack we defined above */
|
||||
thread_create(my_thread_stack, sizeof(my_thread_stack),
|
||||
THREAD_PRIORITY_MAIN - 1, 0, my_first_thread, NULL,
|
||||
"My first thread");
|
||||
int main(void)
|
||||
{
|
||||
/* Create a thread with the stack we defined above */
|
||||
thread_create(my_thread_stack, sizeof(my_thread_stack),
|
||||
THREAD_PRIORITY_MAIN - 1, 0, my_first_thread, NULL,
|
||||
"My first thread");
|
||||
|
||||
/* The main thread can continue doing its work (e.g., printing a message) */
|
||||
puts("Hello, from the main thread!");
|
||||
/* The main thread can continue doing its work (e.g., printing a message) */
|
||||
puts("Hello, from the main thread!");
|
||||
}
|
||||
```
|
||||
|
||||
@ -88,6 +86,43 @@ int main(void) {
|
||||
- `NULL`: The argument for the thread function
|
||||
- `"My first thread"`: The name of the thread
|
||||
|
||||
The final code should now look like this:
|
||||
|
||||
```c title="main.c" {5-9, 25-31}
|
||||
#include <stdio.h>
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
/*
|
||||
* Define a stack for the thread.
|
||||
* The size of the stack is defined by THREAD_STACKSIZE_MAIN.
|
||||
*/
|
||||
char my_thread_stack[THREAD_STACKSIZE_MAIN];
|
||||
|
||||
void *my_first_thread(void *arg)
|
||||
{
|
||||
/* The argument we receive will not be used */
|
||||
(void)arg;
|
||||
|
||||
/* We print a simple message from the thread */
|
||||
puts("Hello, from the thread!");
|
||||
|
||||
/* We return NULL to indicate that the thread has finished */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Create a thread with the stack we defined above */
|
||||
thread_create(my_thread_stack, sizeof(my_thread_stack),
|
||||
THREAD_PRIORITY_MAIN - 1, 0, my_first_thread, NULL,
|
||||
"My first thread");
|
||||
|
||||
/* The main thread can continue doing its work (e.g., printing a message) */
|
||||
puts("Hello, from the main thread!");
|
||||
}
|
||||
```
|
||||
|
||||
## Step 3: Building and Running the Program
|
||||
|
||||
Now that we have created our thread, we can build and run our program.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Timers and Callbacks
|
||||
description: This tutorial explains how to use timers and callbacs in RIOT.
|
||||
description: This tutorial explains how to use timers and callbacks in RIOT.
|
||||
code_folder: examples/guides/timers/
|
||||
---
|
||||
|
||||
@ -50,7 +50,7 @@ also use soon. Using `ztimer_sleep(ZTIMER_SEC, 5);` we simply wait for around
|
||||
But what if we want to do something else while waiting for the timer to expire?
|
||||
Let's take a closer look at how we can use timers in RIOT.
|
||||
|
||||
### Step 1.1: Creating a Callback
|
||||
### Step 1: Creating a Callback
|
||||
|
||||
Timers are a way to schedule tasks to be executed at a later time.
|
||||
In RIOT, you have to tell the timers two things:
|
||||
@ -61,12 +61,13 @@ Lets start by creating the callback that the timer will call when it expires.
|
||||
Go into your `main.c` file and add the following code:
|
||||
|
||||
```c
|
||||
void timer_callback(void *arg) {
|
||||
/* Cast the received pointer "arg" to a C String type */
|
||||
char *message = (char *)arg;
|
||||
void timer_callback(void *arg)
|
||||
{
|
||||
/* Cast the received pointer "arg" to a C String type */
|
||||
char *message = (char *)arg;
|
||||
|
||||
/* Print the message */
|
||||
puts(message);
|
||||
/* Print the message */
|
||||
puts(message);
|
||||
}
|
||||
```
|
||||
|
||||
@ -75,15 +76,16 @@ and prints the string to the console. Congrats, you have created a callback func
|
||||
now all that is left is to create the timer and schedule it.
|
||||
To do that lets restructure our `main` function to use the timer.
|
||||
|
||||
### Step 1.2: Scheduling the Timer
|
||||
### Step 2: Scheduling the Timer
|
||||
|
||||
Go into your `main` function and include the following code:
|
||||
|
||||
```c
|
||||
int main(void) {
|
||||
/* Create a timer */
|
||||
ztimer_t timer = {.callback = timer_callback,
|
||||
.arg = "3 seconds have passed!"};
|
||||
int main(void)
|
||||
{
|
||||
/* Create a timer */
|
||||
ztimer_t timer = { .callback = timer_callback,
|
||||
.arg = "3 seconds have passed!" };
|
||||
```
|
||||
|
||||
This code creates a timer and initializes it with the callback function we
|
||||
@ -92,15 +94,15 @@ Now all that is left is to actually start the timer. To do that,
|
||||
we need to simply call the `ztimer_set` function with the timer we created as an argument.
|
||||
|
||||
```c
|
||||
/* Set the timer to fire in 3 seconds */
|
||||
ztimer_set(ZTIMER_SEC, &timer, 3);
|
||||
/* Set the timer to fire in 3 seconds */
|
||||
ztimer_set(ZTIMER_SEC, &timer, 3);
|
||||
```
|
||||
|
||||
This code tells the timer to fire in 3 seconds.
|
||||
The first argument specifies which type of clock we want to use,
|
||||
the second argument is the timer we created, and the third argument is the time in seconds.
|
||||
|
||||
### Step 1.3: Running the Program
|
||||
### Step 3: Running the Program
|
||||
|
||||
Now that we have created the timer and scheduled it, we can run the program.
|
||||
Compile the program using `make` and flash it to your board using `make flash`.
|
||||
@ -108,20 +110,55 @@ If you look into the terminal via `make term` you should see the message
|
||||
"3 seconds have passed!" printed to the console after 3 seconds.
|
||||
|
||||
That's all there is to it! You have successfully used a timer in RIOT.
|
||||
|
||||

|
||||
|
||||
Now you can do other things while waiting for the timer to expire,
|
||||
instead of constantly checking if the timer has expired. For example,
|
||||
lets use our knowledge from before to let the main thread go to sleep for 5 seconds
|
||||
and then print a message.
|
||||
|
||||

|
||||
|
||||
```c
|
||||
/* Sleep for 5 seconds */
|
||||
ztimer_sleep(ZTIMER_SEC, 5);
|
||||
/* Sleep for 5 seconds */
|
||||
ztimer_sleep(ZTIMER_SEC, 5);
|
||||
|
||||
puts("5 seconds have passed!");
|
||||
puts("5 seconds have passed!");
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
```
|
||||
|
||||
The final code should now look like this:
|
||||
|
||||
```c title="main.c"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ztimer.h"
|
||||
|
||||
void timer_callback(void *arg)
|
||||
{
|
||||
/* Cast the received pointer "arg" to a C String type */
|
||||
char *message = (char *)arg;
|
||||
|
||||
/* Print the message */
|
||||
puts(message);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Create a timer */
|
||||
ztimer_t timer = { .callback = timer_callback,
|
||||
.arg = "3 seconds have passed!" };
|
||||
|
||||
/* Set the timer to fire in 3 seconds */
|
||||
ztimer_set(ZTIMER_SEC, &timer, 3);
|
||||
|
||||
/* Sleep for 5 seconds */
|
||||
ztimer_sleep(ZTIMER_SEC, 5);
|
||||
|
||||
puts("5 seconds have passed!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
@ -3,7 +3,7 @@ title: Using C++ in RIOT
|
||||
description: This document explains how to use C++ in RIOT, including levels of support and requirements for C++ code.
|
||||
---
|
||||
|
||||
# Levels of Support
|
||||
## Levels of Support
|
||||
|
||||
A CPU in RIOT can have three levels of support for C++ code:
|
||||
|
||||
@ -21,7 +21,7 @@ can be one (or more) of the following:
|
||||
(such as constructor guards for the thread safe initialization of statically
|
||||
allocated instances) or hooks in the startup process to perform initialization
|
||||
|
||||
# Using C++
|
||||
## Using C++
|
||||
|
||||
In order for C++ code to compile with RIOT, the following needs to be done:
|
||||
|
||||
|
||||
@ -3,19 +3,19 @@ title: Managing a Release
|
||||
description: This page describes the process of managing a release.
|
||||
---
|
||||
|
||||
# Contents
|
||||
## Contents
|
||||
|
||||
1. [Checklist](https://github.com/RIOT-OS/RIOT/wiki/Managing-a-Release#1-checklist)
|
||||
2. [Preparation](https://github.com/RIOT-OS/RIOT/wiki/Managing-a-Release#2-preparation)
|
||||
3. [Feature Freeze and Testing](https://github.com/RIOT-OS/RIOT/wiki/Managing-a-Release#3-feature-freeze-and-testing)
|
||||
4. [Drafting Release Notes](https://github.com/RIOT-OS/RIOT/wiki/Managing-a-Release#4-Drafting-Release-Notes)
|
||||
5. [Actual Release](https://github.com/RIOT-OS/RIOT/wiki/Managing-a-Release#5-actual-release)
|
||||
6. [Other Repositories](https://github.com/RIOT-OS/RIOT/wiki/Managing-a-Release#6-Other-repositories)
|
||||
7. [Important Fixes after Release](https://github.com/RIOT-OS/RIOT/wiki/Managing-a-Release#7-important-fixes-after-release)
|
||||
8. [Resources](https://github.com/RIOT-OS/RIOT/wiki/Managing-a-Release#8-resources)
|
||||
9. [Forum post templates](https://github.com/RIOT-OS/RIOT/wiki/Managing-a-Release#9-forum-post-templates)
|
||||
1. [Checklist](#1-checklist)
|
||||
2. [Preparation](#2-preparation)
|
||||
3. [Feature Freeze and Testing](#3-feature-freeze-and-testing)
|
||||
4. [Drafting Release Notes](#4-drafting-release-notes)
|
||||
5. [Actual Release](#5-actual-release)
|
||||
6. [Other Repositories](#6-other-repositories)
|
||||
7. [Important Fixes after Release](#7-important-fixes-after-release)
|
||||
8. [Resources](#8-resources)
|
||||
9. [Forum post templates](#9-forum-post-templates)
|
||||
|
||||
# 1. Checklist
|
||||
## 1. Checklist
|
||||
|
||||
Steps marked with a :scroll: icon can also be automated with the release manager script.
|
||||
|
||||
@ -31,7 +31,7 @@ Steps marked with a :scroll: icon can also be automated with the release manager
|
||||
- [ ] Go through list of deprecated features and make sure pending removals are applied
|
||||
- [ ] Familiarise with release specs and tests, incl open issues, deprecations, api changes, and PRs
|
||||
|
||||
**Soft feature freeze**
|
||||
**Soft Feature Freeze**
|
||||
- [ ] Post about soft feature freeze to the forum
|
||||
- [ ] Check that there are no pending Rust changes (`find -name Cargo.toml -exec cargo update --manifest-path "{}" --package riot-wrappers --package riot-sys ";"` should be a no-op), otherwise poke Rust using maintainers
|
||||
- [ ] Familiarise with nearly-merged, high impact PRs, and contact the contributors to ask them to hold
|
||||
@ -57,7 +57,7 @@ Do the below actions iteratively, generating new release candidates, until all r
|
||||
- [ ] Inform about the release on the forum
|
||||
- [ ] Update the [release statistics](https://github.com/RIOT-OS/RIOT/wiki/release-statistics)
|
||||
|
||||
# 2. Preparation
|
||||
## 2. Preparation
|
||||
|
||||
A good time to start preparing for the release is two months before the intended release date. Keep track of open pull requests and issues, especially of those marked with the Milestone label for the imminent release. This is a good time to clean up the GitHub repository and get rid of outdated, redundant or already fixed pull requests and issues.
|
||||
|
||||
@ -71,7 +71,7 @@ GitHub's [hub](https://github.com/github/hub) command line tool is useful to col
|
||||
|
||||
Also review PRs tagged for the milestone that have not been updated in a long time. This state arises when a PR was tagged for a particular milestone, but was not merged in time and so the release manager tagged it for the _next_ milestone. As a guideline, if a PR already has been tagged for three milestones, then simply remove the milestone rather than advancing it to the next. After this removal, either the PR gets some attention or the stale bot eventually will close it.
|
||||
|
||||
# 3. Feature Freeze and Testing
|
||||
## 3. Feature Freeze and Testing
|
||||
|
||||
There are two feature freezes: soft and hard.
|
||||
|
||||
@ -82,21 +82,21 @@ Hard feature freeze is the date at which the release branch gets created. When h
|
||||
Any bugfixes should be merged into RIOT master and backported into the release branch by creating an identical PR against it. The backport_pr tool in the RIOT repo can be used to do this automatically. To coordinate testing, you can use the checkboxes and the discussion in the release candidate's issue, and/or the release tracking spreadsheet, at your discretion. Once all bugfixes addressing test failures have been merged and backported, a new release candidate is generated and testing begins again. This happens iteratively until we get a release candidate which passes all the tests without any further bugfixes. As there are "always" known issues, and deadlines need to be satisfied, it is possible to abstain at some point from backporting and re-testing iteratively, and list the issue as known in the release notes.
|
||||
|
||||
|
||||
## Automatic freezing and release candidate generation
|
||||
### Automatic Freezing and Release Candidate Generation
|
||||
|
||||
First create a [classic Token](https://github.com/settings/tokens) and supply it to the `riot-release-manager` script with the `-t <token>` parameter.
|
||||
|
||||
**Feature freeze:**
|
||||
**Feature Freeze:**
|
||||
```bash
|
||||
riot-release-manager feature-freeze yyyy.mm
|
||||
```
|
||||
**Generating a new release candidate:**
|
||||
**Generating a new Release Candidate:**
|
||||
```bash
|
||||
riot-release-manager rc yyyy.mm
|
||||
```
|
||||
|
||||
|
||||
## Manual freezing and release candidate generation
|
||||
### Manual Freezing and Release Candidate Generation
|
||||
|
||||
Even if you're using the release manager script, it's worth reading this section so you know what's going on.
|
||||
|
||||
@ -115,18 +115,18 @@ In the RIOT [Release Specs](https://github.com/RIOT-OS/Release-Specs/issues) rep
|
||||
|
||||
When generating a new release candidate, the release candidate needs to be tagged, a new issue needs to be created in the [Release Specs repository](https://github.com/RIOT-OS/Release-Specs/issues) and testing starts from the beginning (as described above).
|
||||
|
||||
# 4. Drafting Release Notes
|
||||
## 4. Drafting Release Notes
|
||||
|
||||
|
||||
## Automatic draft release note generation
|
||||
### Automatic Draft Release Note Generation
|
||||
|
||||
**Setting milestones :**
|
||||
**Setting Milestones :**
|
||||
This allows the release-notes script to understand which PRs were merged for this release.
|
||||
```bash
|
||||
riot-release-manager set-milestones yyyy.mm --execute
|
||||
```
|
||||
|
||||
**Draft release notes :**
|
||||
**Draft Release Notes :**
|
||||
```bash
|
||||
riot-release-manager release-notes yyyy.mm
|
||||
```
|
||||
@ -135,11 +135,11 @@ Then review the output to sort potential mismatch in categories where different
|
||||
|
||||
A key part of the notes, however, is the selected highlights, which are not be generated automatically, and which you must draft manually.
|
||||
|
||||
## Manually drafting release note
|
||||
### Manually Drafting Release Note
|
||||
|
||||
Obviously, you can also choose to do the above by hand.
|
||||
|
||||
# 5. Actual Release
|
||||
## 5. Actual Release
|
||||
|
||||
Once a release candidate passed all tests you are ready to create the release notes. Open an etherpad and list new features, major improvements and features as well as known issues as done in [previous releases](https://github.com/RIOT-OS/RIOT/blob/master/release-notes.txt). Make sure the line length is about 90 characters. You should share this pad with other maintainers and give them some time for review. Alternatively you can open a pull request with your notes and discuss there. But the former has proven well so far.
|
||||
|
||||
@ -158,7 +158,7 @@ We maintain a Release statistic where you should add numbers from the previously
|
||||
|
||||
After you have released, be sure to inform all RIOTers about the release via mail on all lists and RIOT forum (under Announcements).
|
||||
|
||||
## Automatic releasing
|
||||
### Automatic Releasing
|
||||
|
||||
Run the command
|
||||
|
||||
@ -166,7 +166,7 @@ Run the command
|
||||
riot-release-manager release yyyy.mm
|
||||
```
|
||||
|
||||
## Manual releasing
|
||||
### Manual Releasing
|
||||
|
||||
Again, it's worth reading this section even if you're using the release manager tool.
|
||||
|
||||
@ -174,11 +174,11 @@ Tag this release as you did for the release candidate, except that you should si
|
||||
|
||||
Now that everything is ready, create the release. This can easily be done via GitHubs web interface. In the [RIOT](https://github.com/RIOT-OS/RIOT) repository click on *Releases->Draft a new release*. Assign the tag you previously created and signed, set title `RIOT-<yyyy-mm> and paste the release notes below. Et voilà, that's the release.
|
||||
|
||||
# 6. Other repositories
|
||||
## 6. Other Repositories
|
||||
|
||||
Don't forget to update the submodule in the [applications repository](https://github.com/RIOT-OS/applications) and [Tutorials repository](https://github.com/RIOT-OS/Tutorials) and test if the applications still work.
|
||||
|
||||
# 7. Important Fixes after Release
|
||||
## 7. Important Fixes after Release
|
||||
|
||||
After the release, issues may arise that are important enough to warrant an update to the release. As a first step, such issues should be backported to the release branch. If a single issue represents a critical fix, or if a number of lesser backported issues accumulate, then a bugfix or point release should be created.
|
||||
|
||||
@ -186,7 +186,7 @@ For example, after the 2019.10 release [#12653](https://github.com/RIOT-OS/RIOT/
|
||||
|
||||
A point release for a critical issue is best limited to a small number of changes to the original release to reduce the amount of testing required and also reduce the introduction of new bugs. We do not have a policy on who should manage a point release, but the previous release manager at least should consult on the point release since they are most familiar with the previous release.
|
||||
|
||||
# 8. Resources
|
||||
## 8. Resources
|
||||
|
||||
| Description | Location |
|
||||
|-------------|----------|
|
||||
@ -201,11 +201,11 @@ A point release for a critical issue is best limited to a small number of change
|
||||
| Release test tracking spreadsheet | https://drive.google.com/open?id=0B384VtEXbD_HRzJSY1NGdnFpWERxb2JFeGdaS09iUjV0TGhN |
|
||||
|
||||
|
||||
# 9. Forum post templates
|
||||
## 9. Forum Post Templates
|
||||
|
||||
These templates are suggestions, if useful. Whatever the phrasing, posts with similar content should be made to the forum at various stages of the release process.
|
||||
|
||||
## Date announcement and feature request
|
||||
### Date Announcement and Feature Request
|
||||
**Subject**
|
||||
Release [YYYY.MM] - dates and feature requests
|
||||
|
||||
@ -230,7 +230,7 @@ Best regards, and happy hacking!
|
||||
[Name]
|
||||
```
|
||||
|
||||
## Soft feature freeze announcement
|
||||
### Soft Feature Freeze Announcement
|
||||
**Subject**
|
||||
Release [YYYY.MM] - Soft feature freeze now effective
|
||||
|
||||
@ -246,7 +246,7 @@ Wishing you a happy code/polish/review/merge sprint,
|
||||
[Name]
|
||||
```
|
||||
|
||||
## Hard feature freeze announcement
|
||||
### Hard Feature Freeze Announcement
|
||||
**Subject**
|
||||
Release [YYYY.MM] - Hard feature freeze now effective
|
||||
|
||||
@ -277,7 +277,7 @@ Best regards,
|
||||
[2] https://github.com/RIOT-OS/Release-Specs#pytest-runner
|
||||
```
|
||||
|
||||
### Release announcement
|
||||
#### Release Announcement
|
||||
**Subject**
|
||||
Release [YYYY.MM]
|
||||
|
||||
@ -16,7 +16,7 @@ are backported from `master` to the release branch, and new release candidates m
|
||||
when certain milestones are reached. Once all major bugs are fixed, the new RIOT release
|
||||
is signed off by the appointed release manager, typically within 2 weeks after the feature freeze.
|
||||
For more details and instructions for release managers, see the
|
||||
[managing a release guide](https://github.com/RIOT-OS/RIOT/tree/master/doc/guides/managing-a-release).
|
||||
[managing a release guide](https://guide.riot-os.org/misc/managing-a-release/).
|
||||
|
||||
RIOT follows a rolling release cycle, meaning support and bug fixes are only provided
|
||||
for the most current release.
|
||||
|
||||
@ -8,7 +8,7 @@ For each area, some near-future plans and concrete next steps are indicated.
|
||||
The text and items below are tentative, up for discussion, to be updated by regular pull requests.
|
||||
|
||||
|
||||
# Network Stack High Layers
|
||||
## Network Stack High Layers
|
||||
(contact/steering: [Martine](https://github.com/miri64))
|
||||
|
||||
- ICN stack support clean-up
|
||||
@ -20,19 +20,19 @@ The text and items below are tentative, up for discussion, to be updated by regu
|
||||
- [ ] in legacy networks (eg. by means of tunneling)
|
||||
- [ ] with configurable on-by-default fallbacks
|
||||
|
||||
# Network Stack Low Layers
|
||||
## Network Stack Low Layers
|
||||
(contact/steering: [Peter](https://github.com/PeterKietzmann))
|
||||
|
||||
- Point-to-Point Protocol (PPP): finalize and merge `gnrc_ppp`
|
||||
|
||||
|
||||
# Integrations
|
||||
## Integrations
|
||||
(contact/steering: [Teufelchen](https://github.com/teufelchen1))
|
||||
|
||||
- [Home-Assistant](https://www.home-assistant.io/) BTHome integration
|
||||
- [Home-Assistant](https://www.home-assistant.io/) integration via [MQTT Discovery](https://www.home-assistant.io/integrations/mqtt#mqtt-discovery)
|
||||
|
||||
# Power Modes
|
||||
## Power Modes
|
||||
(contact/steering: [benpicco](https://github.com/benpicco))
|
||||
|
||||
- concept to fix shell usage issue while LPM activated
|
||||
@ -42,17 +42,17 @@ The text and items below are tentative, up for discussion, to be updated by regu
|
||||
|
||||
|
||||
|
||||
# Peripheral Drivers
|
||||
## Peripheral Drivers
|
||||
(contact/steering: [maribu](https://github.com/maribu))
|
||||
|
||||
## Timers
|
||||
### Timers
|
||||
|
||||
(contact/steering: [kaspar030](https://github.com/kaspar030), [benpicco](https://github.com/benpicco), [maribu](https://github.com/maribu))
|
||||
|
||||
- cleanup and unification of low-level timer interfaces (`timer`, `rtt`, `rtc`)
|
||||
- implement capture mode
|
||||
|
||||
## SPI
|
||||
### SPI
|
||||
|
||||
- introduction of `spi_slave` interface
|
||||
- transition to `spi_clk_t` being the frequency in Hz, not an `enum` constant, to allow arbitrary frequencies
|
||||
@ -60,12 +60,12 @@ The text and items below are tentative, up for discussion, to be updated by regu
|
||||
- allow a way to detect the actual frequency an SPI bus is running at
|
||||
- see https://github.com/RIOT-OS/RIOT/pull/16727 for one proposal
|
||||
|
||||
## I2C
|
||||
### I2C
|
||||
|
||||
- introduction of `i2c_slave` interface
|
||||
- see https://github.com/RIOT-OS/RIOT/issues/19560 for a discussion
|
||||
|
||||
## GPIO
|
||||
### GPIO
|
||||
|
||||
(contact/steering: [gschorcht](https://github.com/gschorcht), [maribu](https://github.com/maribu))
|
||||
|
||||
@ -74,7 +74,7 @@ The text and items below are tentative, up for discussion, to be updated by regu
|
||||
- many MCUs still need an implementation
|
||||
- add a high level API that unifies external and internal GPIOs on top
|
||||
|
||||
## ADC
|
||||
### ADC
|
||||
|
||||
(contact/steering: [benpicco](https://github.com/benpicco), [kfessel](https://github.com/kfessel), [gschorcht](https://github.com/gschorcht), [maribu](https://github.com/maribu))
|
||||
|
||||
@ -87,7 +87,7 @@ The text and items below are tentative, up for discussion, to be updated by regu
|
||||
|
||||
|
||||
|
||||
# Software Updates
|
||||
## Software Updates
|
||||
(contact/steering: [Emmanuel](https://github.com/emmanuelsearch))
|
||||
|
||||
- Modularize to provide toolbox supporting other image storing (e.g. support external flash), transport (other than CoAP), crypto (e.g. secure element).
|
||||
@ -95,14 +95,14 @@ The text and items below are tentative, up for discussion, to be updated by regu
|
||||
|
||||
|
||||
|
||||
# Documentation
|
||||
## Documentation
|
||||
(contact/steering: [Emmanuel](https://github.com/emmanuelsearch))
|
||||
|
||||
- Write and publish more RDMs
|
||||
|
||||
|
||||
|
||||
# Low-Level Hardware Support
|
||||
## Low-Level Hardware Support
|
||||
(contact/steering: [Alex](https://github.com/aabadie))
|
||||
|
||||
- radio support for TI SensorTag
|
||||
@ -110,21 +110,21 @@ The text and items below are tentative, up for discussion, to be updated by regu
|
||||
|
||||
|
||||
|
||||
# Testing
|
||||
## Testing
|
||||
(contact/steering: [Kaspar](https://github.com/kaspar030))
|
||||
|
||||
- automated network functionality tests (e.g. RPL + UDP/PING tests through border router, multi-hop) in IoTLAB dev sites?
|
||||
|
||||
|
||||
|
||||
# Security
|
||||
## Security
|
||||
(contact/steering: [Kaspar](https://github.com/kaspar030))
|
||||
|
||||
- RNG unified (secure, or basic), seeding
|
||||
- RIOT default configuration = secure configuration (that's our goal/motto)
|
||||
|
||||
|
||||
## 802.15.4 Link Layer Security
|
||||
### 802.15.4 Link Layer Security
|
||||
(contact/steering: [chrysn](https://github.com/chrysn))
|
||||
|
||||
Current status: RIOT supports application provided keys,
|
||||
|
||||
@ -136,6 +136,7 @@ export default defineConfig({
|
||||
"misc/io_mapping_and_shields",
|
||||
"misc/roadmap",
|
||||
"misc/release_cycle",
|
||||
"misc/managing-a-release",
|
||||
"misc/emulators",
|
||||
"misc/terminal_config",
|
||||
"misc/how_to_doc",
|
||||
|
||||