To promote free and open development, OpenThread uses CMake in the build toolchain. Currently, this toolchain is required for porting OpenThread to a new hardware platform.
Other build toolchains might be supported in the future, but they are not within the scope of this porting guide.
Create a new repository
The first step is set up a new home for your hardware platform. In this guide, we'll be creating a new repository named ot-efr32 which contains the platform abstraction layer, the hardware platform's SDK, and a few useful scripts.
In this example, we created the SiliconLabs/ot-efr32 repository on GitHub and cloned it to ~/repos/ot-efr32.
mkdir -p ~/reposcd ~/reposgit clone git@github.com:SiliconLabs/ot-efr32.gitCloning into 'ot-efr32'... remote: Enumerating objects: 99, done. remote: Counting objects: 100% (99/99), done. remote: Compressing objects: 100% (60/60), done. remote: Total 333 (delta 65), reused 39 (delta 39), pack-reused 234 Receiving objects: 100% (333/333), 170.78 KiB | 5.69 MiB/s, done. Resolving deltas: 100% (194/194), done.git statusOn branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean
Repository structure
To help maintain consistency with existing platform repositories in the OpenThread GitHub organization, you may want to structure your repository as such:
tree -F -L 1 --dirsfirst
.
├── examples/
├── openthread/
├── script/
├── src/
├── third_party/
├── CMakeLists.txt
├── LICENSE
└── README.md
| Folder | Description |
|---|---|
examples |
optional Example applications |
openthread |
The openthread repository as a submodule |
script |
Scripts for building, testing, linting |
src |
The platform abstraction layer implementation |
third_party |
Location for any third-party sources |
Add submodules
The next step is to add openthread and any other required repos as submodules
git submodule add git@github.com:openthread/openthread.git
Cloning into '/home/user/repos/ot-efr32/openthread'...
remote: Enumerating objects: 78281, done.
remote: Counting objects: 100% (1056/1056), done.
remote: Compressing objects: 100% (488/488), done.
remote: Total 78281 (delta 639), reused 864 (delta 556), pack-reused 77225
Receiving objects: 100% (78281/78281), 76.62 MiB | 35.24 MiB/s, done.
Resolving deltas: 100% (61292/61292), done.
For this example, we'll be adding a lite version of the Silicon Labs Gecko SDK as a submodule in third_party.
cd third_partygit submodule add git@github.com:SiliconLabs/sdk_support.gitCloning into '/home/user/repos/ot-efr32/third_party/sdk_support'... remote: Enumerating objects: 32867, done. remote: Counting objects: 100% (8181/8181), done. remote: Compressing objects: 100% (3098/3098), done. remote: Total 32867 (delta 4945), reused 7469 (delta 4732), pack-reused 24686 Receiving objects: 100% (32867/32867), 128.83 MiB | 30.91 MiB/s, done. Resolving deltas: 100% (19797/19797), done.
Scripts
To make common tasks easier, you may want to create some scripts in the script folder. This may include scripts for tasks like bootstraping, building, running a code-linter, and a test script for GitHub CI checks.
Below are some examples of scripts which are standard for most of the existing platform repositories.
bootstrap
This script should install all tools and packages required by your hardware platform. It should also execute openthread's bootstrap script to ensure that the user has everything needed to build the OpenThread stack.
See the bootstrap script in ot-efr32 for an example.
build
The CMake build script should allow users to build the OpenThread stack for your platform. If your repository defines any example applications, this script should build those as well. This script should contain the basic system configuration options, including any platform-specific macro definitions.
See the build script in ot-efr32 for an example.
test
A test script may be useful for users to test changes using any tests you have defined. This could be anything as simple as running sanity-check builds or as complicated as launching a unit-test suite.
In ot-efr32, the script simply executes the build script for every supported board on each of the efr32 platforms.
See the test script in ot-efr32 for an example.
make-pretty
To maintain consistent styling, this script should format code, scripts, and markdown files.
You may define this script yourself, but it may be easiest to use the make-pretty script which existing platform repos are using. The script calls into the openthread's style scripts and helps ensure consistent style across all OpenThread repositories.
Linker script configuration
The GNU Linker script
describes how to map all sections in the input files (.o "object" files
generated by the GNU Compiler Collection (GCC)) to the final output file (for
example, .elf). It also determines the storage location of each segment of an
executable program, as well as the entry address. The platform-specific linker
script is often provided with the platform's BSP.
Configure the ld tool to point to the platform-specific linker script using
target_link_libraries on your platform CMake target in src/CMakeLists.txt:
set(LD_FILE "${CMAKE_CURRENT_SOURCE_DIR}/efr32mg12.ld")
target_link_libraries(openthread-efr32mg12
PRIVATE
ot-config
PUBLIC
-T${LD_FILE}
-Wl,--gc-sections -Wl,-Map=$.map
)
Toolchain startup code
Toolchain startup code is often provided along with the platform's BSP. This code typically:
- Implements the entry function (
Reset_Handler) of the executable program - Defines the interrupt vector table
- Initializes the Heap and Stack
- Copies the
.datasection from non-volatile memory to RAM - Jumps to the application main function to execute the application logic
The startup code (C or assembly source code) must be included in your platform's
openthread-platform-name library, otherwise some key variables used in the linker
script cannot be quoted correctly:
src/CMakeLists.txt
Example: startup-gcc.c in ot-cc2538 - src/CMakeLists.txt
add_library(openthread-cc2538
alarm.c
...
startup-gcc.c
...
system.c
logging.c
uart.c
$
)